Ask HN: What do you love/hate about terminals? Would you change them?
I'm part of a small group that is working on a new set of protocols for terminals and shells, in order to move terminal handling out of the kernel as much as possible, and to replace the huge organically grown mess of ANSI escape sequences, terminfo databases, and so on.
I'm posting this from 34C3, where I'm asking people the same questions:
- What do you love about terminals?
- What do you hate about terminals?
- If you had to build one from scratch, how would you do it?
If you do not wish to answer in public, you can also write a mail to 34c3-terminal-survey at posteo dot de.
[I'm posting from a throwaway account because my Github links to the work that we have started on this, and I don't want to bias the survey by having you look at it before answering.]
203 comments
[ 4.1 ms ] story [ 227 ms ] threadI hate that the terminal and the browser are two different applications.
I think something like hyper will get us close: https://hyper.is
And i'd prefer the two very different functions remain separate programs, i don't need my terminal client to be vulnerable for browser issues (or vice versa).
I'm curious, why would you want that? What is the benefit of having these two applications with separate concerns becoming one?
https://en.wikipedia.org/wiki/VT100
I actually used these, a later model, in the mid-late '90's:
https://en.wikipedia.org/wiki/VT220
The classic green text on black background look comes from these, tho' I always preferred amber.
A shell is the software that reads input from the keyboard, takes some action, which might be to run another program, and sends that output back to the screen. The terminal emulator you are using eg. xterm or PuTTY relays from your hardware keyboard on your PC to the shell, then renders what the shell sends back to it. The kernel's TTY drivers are the glue between them - TTY once meaning "teletype". In the old days between the VT on your desk and the VAX back in the machine room there would be LAT https://en.wikipedia.org/wiki/Local_Area_Transport
So it's a decoupled system, with the Unix philosophy of doing one thing well, and you are free to swap the terminal you use (xterm, rxvt, whatever) and the shell you prefer (csh, bash, zsh, etc) as you please, which you couldn't do if it were a monolithic program like CMD.EXE.
There's "cat -n" which numbers all lines. (-n is not POSIX, but it's available on at least on BSDs and Linux.)
> sed -n 16p filename > newfile
where 16 is the line number.. this is it! That's quite handy.
oh, that's just a man page lookup away. use 'nl -ba' which numbers all the lines. default style is '-bt' which numbers only non-empty ones, as you have experienced...
On a more serious note, the terminal has to "just work", its role is to host shells, ncurses apps, and so on. It doesn't need to have any clever features, it just needs to be a blank canvas, one that is tolerant of its guests doing weird stuff and able to recover gracefully. All the "cleverness" should be in the shell, so it can be swapped out for another one easily.
But still, do you have any "small" things that could be improved. There was someone suggesting that any keypresses / releases should be sent (also Shift/Ctrl etc). I like that to some extent, but I'm afraid it already breaks a lot of usecases.
Maybe the question should be more like, as a DevOp / Sysadmin / Developer, what does your ideal environment look like? And the answers will be as varied as the people asked.
* https://news.ycombinator.com/item?id=16014573
Enjoy.
systemd is like that emacs of process supervisors.
No, it is not blasphemy! I often find myself copying text from some non-keyboard driven program into the command line and having the ability to change the position of the text cursor in the command line with the mouse would be nicer and faster because my hand is already on the mouse.
Pointing with the mouse to a specific location in the middle of a string is always faster than doing the same thing with the keyboard (if your hand is already on the mouse)
My favorite example is htop: Clicking on a random column header with the mouse feels easier and faster than doing the same thing with pure keyboard navigation.
> slowly crawling your way there with arrow keys.
In case you did not know yet: Try using ctrl + arrow keys (or ctrl + b/f) to jump over whole words. It's still not ideal but at least it is faster than just arrow keys.
This would allow one to have two terminals connected to two different machines ( via ssh for example ) and drag and drop files from one terminal to the other, even if there is no route between the two hosts
It would also be nice if words or sentences in the terminal had metadata. So one could type `ls`, see a lot files and click on obe of them to open it
Some protocol for a real dropdown rendered in the style of the OS, plus a standard data format that allows tool builders to specify options, their meanings and the kinds of allowed parameters in a structural way (much like doccomments in code), is direly needed.
If I type "git " I want to see "add" as an option, with docs in a tooltip as I navigate the options. When I "git add " I want to see a list of files that make sense to add, eg only files that can be staged right now.
I want this to be consistent across commands, I want any shell to be able to add support for this and I want any command line program to be able to add support for this.
I don't know much about how SSH works, but there has to be a way to communicate between the daemon and the client that both support this protocol and send the data separate from the screen content? In the typical case where you SSH from your own terminal window your ssh client just forwards the connection to your terminal window and done.
It's not like anything stops working when this stuff isn't there. It's just like colors in that respect.
I don't think that's computable in a terminal.
A bit like how man pages are a standard format for static docs, every tool could ship "autocomplete files" which tell a shell how to build the autocomplete. These files could even contain runnable code (in sh or something) without an additional security risk - after all, they came with a program that you're about to run :-)
I'm sure there's all kinds of challenges with this when you go deeper, but when even a relatively lightweight tool like VS Code can give me perfect C# IntelliSense on every major OS, I find it a bit abysmal that unzipping a file from the terminal is non-trivial.
Also zip sucks, use tar or cpio.
for example, i do the following:
edit-001: added trivial example.https://i.imgur.com/SZqu63p.png
I'm not sure it covers all of the obscure commands you can think of, but 99% of the time it's great.
Edit: looks like it might be stock behaviour https://github.com/zsh-users/zsh/blob/master/Completion/Unix...
I don't want remembered commands, I want the terminal to tell me what stuff means. I want it to tell me what makes sense in which context. Like the IntelliSense when coding Java or C#. Docs at your fingertips, all relevant options (and none else) available, etc. This is incomparable to the kind of autocomplete any shell I've seen to date has. Zsh is a nice step in the right direction but it's still shit.
Regarding contextual analysis, the fundamental problem is that command execution relies on a list of strings (argv) with no types or meaning. Each command is responsible for parsing its own arguments, either manually or using a shared library (e.g. getopt). This provides loose coupling and flexibility, but makes introspection really difficult, and features like completions become an afterthought reimplemented in every shell either by special cases for each command or hacks like parsing help messages.
With fish you can customize auto completion for individual commands with full color and tooltip support.
As a long time emacs user I want to believe that much of the required functionality for menus can be achieved via a text only format (either using standard escape codes or a markup language).
I completely agree that we need to be able to incorporate native UI elements in CLI programs.
Recently I stumbled upon Steve Jobs's presentation of Next computers and the initial UIkit. Jobs himself programmed without writing a single line of code, only using the built in interface builder. This was in the 80s, now the year is 2017 and we are still trying to remember the parameters for tar to extract files :)
I think the future should not rely on terminals where we extensively type and read. There should be drop-down menus for all applications, whether text based or GUI based. And these menus should be able to incorporate system-native dialogs e.g choose a file, choose a font etc.
And I'd want PostScript support to all terminals. Green on black mono fonts are cool but we have 4K displays now, come on! I want to be able to specify font, show images, draw charts etc. in a terminal window.
Frankly the future of terminals should look like Python Notebooks such as Jupyter. We need to be able to use cool fonts graphics UI elements and we need to be able to share our terminal "page" with others.
I watch it regularly. Every time I see even seasoned developers takes weeks or even months for building even a simple application, whether it's frontend or backend, I wonder if we developers have a subconscious bias towards tougher way of building things instead of a much easier way. Visual basic comes into my mind. Visual basic is probably inspired by interface builder and had similar rapid development features. Where/when have we lost it?
> Frankly the future of terminals should look like Python Notebooks such as Jupyter.
I second that. A terminal should ultimately do it's purpose. Not mimic a 1950's thin client terminal with 80x25 resolution and dark colors (Nothing against dark theme, just saying). A user whether a normal user or power user or even a developer shouldn't be bothered with remembering the exact parameter or it's structure. It should be completely scriptable, but it need not appear like existing terminals.
That and the fact you we don't know everything that's possible and stick to what we know.
But, there is another side of the story: reusability is hard, plus similarity and equality are very different things. Generalizing a problem can be more or less productive depending of your situation. Also learning how to use something and bend it to your needs can be an mistake too on the long run.
Mix complexity, money, human factors in that and you get the average IT project.
Which is still awesome if you ask me. Current softwares have many warts, but they are so freaking amazing.
I see how that would easily break scripts. Not in theory no, but in practice. The instant developers gets a choice on this they will develop for their needs and break others.
It breaks what I as a user expects from a terminal and if such a terminal was launched today I don't believe anyone would use it. Not because the idea is bad but because the users of a terminal have a very confined idea of how the communication is supposed to work.
It absolutely must work the same over ssh on my phone or my fridge as on my workstation (regardless of OS). KISS.
Now that doesn't mean we can innovate or improve things, but it must be done without breaking expectations and it must be compatible with the mindset of today or I don't believe anyone will pick it up.
Terminal Programs are already outputting differently based on context (ie ls to a pipe vs screen), so supporting interactive and scripting is hardly a novel idea in the space; its just that the interactive support hasn't fundamentally improved in decades
[0] https://www.youtube.com/watch?v=92NNyd3m79I
You do not need to watch the whole 2 hours, only 20-25 mins where Steve Jobs introduces Nextstep and demonstrates it on a Next machine.
Maybe have something like "when I run the cat command, ignore all commands to the terminal until cat finishes".
stty sane; printf '\033k%s\033\\\033]2;%s\007' "`basename "$SHELL"`" "`uname -n`"; tput reset; tmux refresh
1. "reset" is six keypresses long, seven if you use the Control+J approach (although terminal control codes do not affect the line discipline and won't by themselves upset the newline settings of the line discipline in the first place), and not really archaic or long. On many terminal emulators, there is a menu option on the emulator that does the very same thing.
2. The mosh people addressed this problem years ago, and made a lot of noise about doing so. It's mainly a matter of just not supporting the old ISO/IEC 2022 control sequences for changing 7-bit character sets. See https://news.ycombinator.com/item?id=13904008 for more.
https://github.com/p-e-w/finalterm
If some command prints a line which gets wrapped because it is too long then I wish I could un-wrap it by making the terminal window wider and forcing some sort of re-layout.
1. Minimal latency from keyboard to screen.
2. As others have mentioned here, awareness of line wrap, so that cut and paste work correctly at all times. Not just for raw output from a command. Editors too should communicate with the terminal to indicate that it is wrapping lines.
3. 24-bit color.
4. Apps (shells, editors) can query and set the window icon as well as the window title.
5. Integrated graphics display. So that I can just 'cat' a picture to display it in the terminal window, instead of using an external application.
A sensible protocol to draw raster graphics would be nice, though. (And it might exist, I don't even know). I don't care whether I need to type "cat" or the name of a terminal-based image viewer.
https://github.com/saitoha/PySixel/blob/master/README.rst
Making plain `cat` work too should not be too big of a problem with some small support from the running shell. iTerm2 also knows when a command is starting to run/exits, parsing the output it retrieved from STDOUT in between by matching it against some magic numbers and displaying the content accordingly is not too difficult.
In fact it's not currently technically possible for a terminal emulator to know which program is writing into it. It maybe many programs simulatenously, or it may be the kernel asynchronously, etc... If you want to change that you would have to make the architecture tremendously more complicated and less flexible.
And the same goes for shells. You don't want to complicate the architecture just so that a lawyer could attest you that "it was cat" who drew the image und some weird interpretation. Nothing would be gained, and nobody would be able to understand what's happening anymore.
We have an idea in that direction, where each program in a pipeline can optionally specify a file type, and the last file type hint in the pipeline determines how the stdout is rendered. So if you have "cat image.jpg", then "cat" can indicate a file type of image/jpg, causing stdout to be interpreted as an image. But if you have "cat image.jpg | grep foo" (just making something up here), then grep can indicate a file type of application/octet-stream because it cannot guarantee what the file type is.
The tricky part, from what I can see, is explaining the pipeline topology to the terminal, so that it knows that "grep" comes after "cat", even though command parsing happens in the shell only. That's still a big unknown. A previous project in this area (TermKit) mandated that applications specify a "Content-Type" header (like in HTTP) in their stdout, but that would break most existing programs, so it's not an option for us.
It's not a problem to have this handled in the shell such that the output is rendered in such a way as to please the terminal. You can do this manually (e.g. append a "| display-jpeg-in-terminal" command to the pipeline), or use a magic bytes based file viewer.
Look at "run-mailcap" or its shortcuts like "see". It does basically that, and can also be fed through standard input (which covers the piping situation).
Enlightenment's Terminology has this. It's a separate command "tycat", but yeah, it can display images and videos in the terminal.
They also have "tyls", which will create little thumbnails when listing picture or video files and then you can click on the thumbnails to show the full thing.
https://www.enlightenment.org/about-terminology
* https://github.com/mkschreder/avr-vt100
* https://hackaday.io/project/13273-diy-vt100-a-miniature-hard...
* https://hackaday.com/2010/02/24/oscilloscope-doubles-as-a-se...
* https://tech.scargill.net/vt100-terminal-for-hc2016/
so here are some suggestions off the top of my head
* padding on the left of the terminal. mouse selection from the start of the line needlessly requires precision mousing. more often than essential when attempting to select some text with the mouse, one resizes the terminal or selects a window behind the terminal frame. probably best in the gui client but perhaps some escape modes where whitespace can be hinted as not copyable
* perhaps a modes to suggest arbitrary text should not be copied to the clipboard ? say lots of banner text with a supprt url among it. selectingthe whole block only selects the useful url. ignorable by the end user of course
* mouse double-click-to-select should grow the selection. terminal output often needs to be cutnpasted into other apps
* snapshot the offscreen buffer somehow ? less somefile.txt... exit... rm somefile.txt... oops gone for all time including scrollback
* sane modern defaults. Ctrl-S freezes terminal ?!? I know this a bash thing setopt -w checkwinsize. why is this not on by default ?
I would suggest asking authors of libraries like python_prompt_toolkit who likely have ideas.
yes, it is. thank you ! one simple solution might be to wrap this thingy within an 'xprop(1)' invokation. for example, i can do the following:
WM_NAME(STRING) points to the current title. and when i change the directory, i can query the new name. fitting this mechanism for aforementioned usecase is left as an exercise for the reader :) fwiw, the value for '-id' argument comes from 'xwininfo(1)'X being a network protocol at heart, it positively is weird. i tried that thingy on both local machine, and ssh'ed xterm to remote-machine (with X sessions correctly forwarded locally), and it all seems to work just fine for me.
edit-001 : these are linux machines at both ends, so, i dunno...
* https://news.ycombinator.com/item?id=16014824
The cursor is (generally) an absolute source of truth: Terminals usually behave very predictably. A good terminal does not get in my way or have any bells and whistles. Text goes in, output goes out, there's support for whatever the application needs wrt graphical capabilities and cursor manipulation. That's it. I don't want to have to deal with "oh god I accidentally clicked on a link, let's wait for the firefox tab I didn't need to open".
They're text-based and thus it's very difficult to introduce distraction or overly busy interfaces. Scripting being part of the terminal culture is great. Automation is often at least somewhat thought about.
> - What do you hate about terminals?
There used to be an issue with terminals not being encoding-aware and having big issues with UTF-8. Fortunately, it seems these days are long gone. One thing I loathe is when terminals try to look or behave fancy. Get out of my way, please. If you have that much dev time to spare, please make sure that bitmap fonts actually work.
Not about terminals themselves, but about the ecosystem around it: people assume bash is present and always in /bin/bash. That's an unreasonable assumption. Tab completion is a crapshoot since it's not context aware and extending tab completion for the major shells (bash, zsh, fish) is still an unsolved task.
> - If you had to build one from scratch, how would you do it?
Assuming I can look at prior work, I'd first look at prior work. Ideally simple prior work, like st. I'd also read as much documentation on the VT100 and ANSI escape sequences as I possibly could, since I think that's (still?) kind of the gold standard.
Anything related to mouse support, "integration" with a desktop, trying to outsmart the shell at tab completion are anti-features.
How does mouse support harm you?
The change I'd most like to see to Apple's Terminal.app is that when I want make an edit to the middle of a command line that has not been sent to the shell yet, I can use the pointing device to move the cursor to the location of the intended edit. How would that change harm you?
Why isn't it enough that you are able to work the way you want to work?
Why are you in addition advocating preventing a different way of working that is preferred by many people?
(Most of the time, I use an emacs mode written by myself to issue command lines to a shell, and that mode allow me to use the pointing device to move the cursor, but when I've introduced a bug into the emacs-lisp code that I maintain, I have to use Terminal.app to recover from the bug. I also have to use Terminal.app when setting up a new Mac.)
I recall being able to do this by holding down the alt key as I left clicked where I wanted the cursor to be relocated.
There's nothing wrong with mouse support in itself. Being able to move the cursor, select text, and in general interface with the OS or an application using a mouse is great. However being _forced_ to use the mouse for any kind of general OS or application interfacing feels like an injustice. A macOS specific example would be moving a window between desktops. The last time I used macOS there was no native way to do this without using the mouse. I had to drag the window to the desired desktop (either by dragging it towards the edge of the current desktop or by going to the desktop overview mode and dragging it onto the desired desktop).
Thanks!
Applications know when shift+arrow is pressed because they receive a different control sequence. Modifier keys are reported as an extra parameter in the control sequence for function keys and extended keys. Dickey xterm has been doing the same since 1999. The PuTTY changelog does not indicate when it gained this, but it has had it for years, too.
* http://invisible-island.net/xterm/xterm.log.html#xterm_94
And indeed you will find that TUI applications such as VIM and NeoVIM recognize these control sequences and can distinguish arrow from shift+arrow. See :help cursor-up and (on VIM) :help xterm-modifier-keys . (NeoVIM handles the TUI differently, is terminfo-only, and has modifier recognition always on.)
If some other application does not, then it is not the terminals that need fixing.
One possibility is graphical output. It’s not easy to write a ‘simple’ application that produces graphics right now in the same way you can write one that outputs text to the terminal (also: ‘moving on’ from a simple design to a more polished one generally involves rewriting the graphical portion).
A more random pet peeve: when you run a command and it goes wrong, usually the most useful error message is the first one it displays, but the terminal will scroll to display the last errors which are usually less interesting. A ‘workbook’ style terminal (like you might see in a CAS) might ameliorate this problem? It also helps with a command outputting a giant pile of garbage because a parameter was wrong, as well as the issue where if you’re running something like a compilation job over and over to fix errors it’s hard to tell which messages were from the most recent vs the previous command.