Live data from Hacker News

"Rules" that terminal programs follow

jvns.ca

91–100 of 153 posts

Re: "Rules" that terminal programs follow

#91
post #42

Additional suggestions: * Respect the user's default foreground and background color. Don't change them without good reason. * If you use colors, make them legible regardless of what the default background and foreground colors are, and regardless of the terminal's color map. * Don't use color as the only indication of something. The user's terminal might not display it, and it probably won't be preserved in copy&pas…

> Use emoji only judiciously, if at all.

That reminds me of an incredibly annoying bug I encountered a few years ago involving Docker. One of the scripts being run was outputting emoji to STDOUT, and this was causing the interactive terminal to crash and thus the container to exit. (This issue [0] has error-strings and simple repro tests.)

I'm not sure if the root cause ever got fixed, but I (and many others) ended up making PRs for various open-source projects, to grudgingly implement workarounds that compromised their original artistic vision. :p

[0] https://github.com/docker-archive/toolbox/issues/695

Re: "Rules" that terminal programs follow

#92

Nice writeup. Since she mentioned how hard it is to learn these conventions, I'll plug my preferred reference when thinking about CLIs specifically (rather than TUIs and REPLs) - the Command Line Interface Guidelines https://clig.dev It does include the blog post's rules on exiting on Ctrl-C, accepting `-` for stdin, disabling color in pipes, and much more.

Thanks. Didn't know about that one. There is also:

https://usage.jdx.dev/

Re: "Rules" that terminal programs follow

#93
post #81
post #42

Additional suggestions: * Respect the user's default foreground and background color. Don't change them without good reason. * If you use colors, make them legible regardless of what the default background and foreground colors are, and regardless of the terminal's color map. * Don't use color as the only indication of something. The user's terminal might not display it, and it probably won't be preserved in copy&pas…

> * Don't use color as the only indication of something. The user's terminal might not display it The user may be colour-blind (30% of the population). The user may be completely blind and relying on a screen reader.

30%? As far as I know, about 10% of male population has red-green deficiency, in females it's much rarer, and and all the other forms of colorblindness are very rare regardless of sex.

Re: "Rules" that terminal programs follow

#94

One that's missing is treating ~ as the home directory. This appears to be a shell thing and not a POSIX API thing. For example, this doesn't work: func main() { if _, err := os.ReadFile("~/.bashrc"); err != nil { log.Fatal(err) } fmt.Println("ok") } Meanwhile over in shell land: $ echo ~/~/~ /home/jrockway/~/~ The behavior is actually kind of amazing. I mention it because while "yourprogram ~/path/to/file" always wo…

That's a good point, particularly given that .. is handled for you at the OS API level so you might be inclined to expect ~ is too on POSIX.

Re: "Rules" that terminal programs follow

#95
post #90

One thing I'm wondering about is what text encoding the program should use to output. I tend to write scripts that output exclusively in UTF-8, but I realise this might not be a given. (And, of course, the user's terminal expected encoding setting doesn't necessarily mean that files should be written in that encoding.) Presumably, you would ideally output text in whatever encoding is specified by the LANG environment…

I think these days on POSIX you can just assume UTF-8. On Windows the situation is... not great and entirely depends on what terminal/shell combination you're using.

Re: "Rules" that terminal programs follow

#96
post #81
post #42

Additional suggestions: * Respect the user's default foreground and background color. Don't change them without good reason. * If you use colors, make them legible regardless of what the default background and foreground colors are, and regardless of the terminal's color map. * Don't use color as the only indication of something. The user's terminal might not display it, and it probably won't be preserved in copy&pas…

> * Don't use color as the only indication of something. The user's terminal might not display it The user may be colour-blind (30% of the population). The user may be completely blind and relying on a screen reader.

Colourblindness is <10% of the population. But yes, quite right it's not a good idea to rely on colour as the sole indication of something important.

Re: "Rules" that terminal programs follow

#97

Ctrl-D for REPLs always bites me with GHCi. My usual approach to quitting GHCi is: - Press Ctrl-D, like normal - Get confused when nothing happens - Remember that it doesn't work in GHCi, so run `:q` instead - Get an error message about "lexical error at character '\EOT'", due to Ctrl-D inserting an invisible char at the start of the input - Try `:q` again, without any invisible prefix - GHCi successfully quits

Are you on Windows?

No, this is in Emacs shell-mode on Linux (various distros over the years). Just tried a few other places: it works in qterminal, and also doesn't work in eshell. I've been writing Haskell for about 15 years, including my current job as a full-time Haskell developer, and I never realised GHCi supports Ctrl-D in some situations!

Every other REPL I've used handles this fine, e.g. for quitting Python, Nix repl, SSH sessions, and even the shell itself. Weird.

Re: "Rules" that terminal programs follow

#98
post #44

Earlier quoted context omitted.

This is definitely one of the things that PowerShell got right. 6 different streams, each of which can be intercepted separately and configured differently. https://learn.microsoft.com/en-us/powershell/module/microsof...

I don't think that 6 different streams that will always go to the same place but some of them are usually turned off are very useful. Standard-error/user is useful because it goes to a different place. Levels would be better suited to a simple global variable, or a level associated with each printed line. The chance that someone redirects errors to error.log is reasonable, but the chance that someone redirects errors…

I turn on Verbose logging sometimes, to get more info.

Error logging can be set to either spit out the error and continue, or to stop processing, which is very useful.

Warning and error messages come out in their own colours automatically, which is nice.

And sure, you can just have them all come out to the same place. But having the options to configure them is very handy.

Re: "Rules" that terminal programs follow

#99
post #44

Earlier quoted context omitted.

I don't think that 6 different streams that will always go to the same place but some of them are usually turned off are very useful. Standard-error/user is useful because it goes to a different place. Levels would be better suited to a simple global variable, or a level associated with each printed line. The chance that someone redirects errors to error.log is reasonable, but the chance that someone redirects errors…

I turn on Verbose logging sometimes, to get more info. Error logging can be set to either spit out the error and continue, or to stop processing, which is very useful. Warning and error messages come out in their own colours automatically, which is nice. And sure, you can just have them all come out to the same place. But having the options to configure them is very handy.

None of this is related to them being separate streams instead of metadata in one stream

Re: "Rules" that terminal programs follow

#100

> programs should print “regular” output to stdout and errors to stderr This is really important. I'd like to expand on this. Standard output is for the data the program was asked to produce, no more and no less. If user asked for some JSON data, standard output should contain that exact JSON object and absolutely nothing else. Standard "error" is actually a misnomer. It should have been called the standard user stre…

This is definitely one of the things that PowerShell got right. 6 different streams, each of which can be intercepted separately and configured differently. https://learn.microsoft.com/en-us/powershell/module/microsof...

Also related to the article, PowerShell has PSReadLine, which implements a pretty reasonable text editor, including selection, copy/paste, classic keybindings such as Home/End/Ctrl-arrows, sane multiline command editing, semantic autocomplete and custom actions that can operate on input AST.

Once you get used to having all that, going back to other shells is pretty hard.

Post reply on HN