Live data from Hacker News

"Rules" that terminal programs follow

jvns.ca

121–130 of 153 posts

Re: "Rules" that terminal programs follow

#121
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. Similar with gratuitous non-ASCII characters.

This deserves to be highlighted more. Nowadays some authors keep assuming users use a patched font and build their tools with that in mind, thus hampering ease of use significantly.

Re: "Rules" that terminal programs follow

#122
post #71

Some more notes: - If this is your first time hearing about the readline/emacs keybindings like Ctrl-E and Ctrl-W, you'll be pleased to know that most macOS input sources use these keybindings. If you're on macOS, feel free to try Ctrl-E, Ctrl-W, or Ctrl-U in your browser's address bar right now - If you're using a command line program that doesn't support _any_ line editing (e.g. no readline keybindings, and no othe…

> If you're on macOS, feel free to try Ctrl-E, Ctrl-W, or Ctrl-U in your browser's address bar right now Most browsers I've used close the current tab when you press Ctrl-W. Actually, the terminal emulator I use, Alacritty, also does this, and most file explorers that have tabs also do. Iirc even windows explorer does this now, but it's been a while since I've actually used windows.

>Actually, the terminal emulator I use, Alacritty, also does this

This can't be right. I use ctrl+w all the time, and occasionally use Alacritty. I'd notice if this shortcut closed my terminal window (it's extremely annoying when I use a web-based ssh, because I have this shortcut deep in my muscle memory).

Re: "Rules" that terminal programs follow

#123
post #89

Some of the rules codify many bad practices, from poor color support to unergonomic keybindings. Given that the support isn't universal and breaks in parts anyway, it's better to break it competely and use something more ergonomic

If you write a command line program, please don't introduce random keybindings for simple actions, or unnecessarily fancy colors when standard 8 would suffice. These rules (or rather conventions) exist for a reason.

Re: "Rules" that terminal programs follow

#124
Other rules for command line tools:

1. Don’t assume a terminal type. Look at `TERM` and use termcap/terminfo or a library built atop them for anything beyond line-oriented plain text output, or least assume a plain teletype unless you specifically recognize the user’s terminal type.

2. Don’t assume the presence of a terminal at all. Check `isatty()` before doing anything fancy, and be sure to work without a terminal so your tool can be used in pipelines and called by other programs via `exec()`.

3. Follow the common conventions in your arguments and output structure. For example, if your tool takes an open-ended set of arguments, support specifying a response file with `@path/to/file` to avoid argument limits. If your tool supports record-oriented output, support a `-0` argument to `NUL`-separate the output for use with `xargs` in pipelines.

4. Use the standard `` exit codes. They exist for a reason and they make use of your tool within pipelines and programs more straightforward because they make it easier to trace why a failure occurred.

5. Include both in-binary `--help`/usage information and a man page. Often a user will just need a quick refresher on argument syntax, which is what the built-in help text is for; the man page should be a comprehensive reference with examples. It should *never* defer to a web page or GNU `info`—it’s fine if those exist too and are pointed out, but they should not be the primary user reference.

Lots of Linux-oriented tools have one or more of these failure modes, and behave poorly on real terminals that aren’t VT100 derivatives or are awkward to use in anything but an interactive setting.

Re: "Rules" that terminal programs follow

#125
post #112
post #108

Earlier quoted context omitted.

You can delegate the choice to the terminal by using ANSI color codes [1]. Then the onus is on the user/terminal developer to make sure the colors they’ve configured (or the defaults provided) are reasonable. A downside of this is that it is quite restrictive, there are only like 8 colors. EDIT: I missed the “regardless of the color map” bit, that is a bit unreasonable. Either you trust the terminal emulator or don’t…

For example, I've seen a program that sets foreground color to a symbolic (not RGB value) yellow, and doesn't set background. While that combination might be legible on some terminals, it's definitely not on all of them. Don't assume that the user's terminal's color map makes all combinations legible.

I've definitely noticed this going on. `jj log` uses the right colors, but `watch --color jj log` somehow breaks and prints black-on-black.

Re: "Rules" that terminal programs follow

#126
post #82

Earlier quoted context omitted.

cooked mode also generally gives input to the program a line at a time and handles things like backspace to delete characters, and it handles program output too, doing things like replacing \n with \r\n.

No, line-by-line vs. character-by-character is a separate mode from “cooked” mode. See “stty extproc”.

I read up on this and "cooked but character-by-character" is apparently something called "cbreak mode" (or "rare mode").

Re: "Rules" that terminal programs follow

#127
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, and it probably won't be preserved in copy&paste into notes.

And some of us choose to disable color by default. (Yes, I'm old-fashioned.)

Re: "Rules" that terminal programs follow

#128
post #88

How did copy-pasting text between programs fit in the initial shell design ? You can't paste from a remote tmux to a local one, you can't mouse-copy multiple lines from a vim vertical split, etc. Where's the terminal clipboard that works across programs ?

You can (usually) run your remote tmux in a window in your local tmux session; then you can use the local tmux session's copy/paste features.

I commonly run "ssh remote-system" in a tmux window, then attach to a tmux session on the remote system.

If you nest tmux sessions like this, you have to type the prefix character (Ctrl-B by default; I use Ctrl-Space) twice for the nested session to see it.

Re: "Rules" that terminal programs follow

#129

Other rules for command line tools: 1. Don’t assume a terminal type. Look at `TERM` and use termcap/terminfo or a library built atop them for anything beyond line-oriented plain text output, or least assume a plain teletype unless you specifically recognize the user’s terminal type. 2. Don’t assume the presence of a terminal at all. Check `isatty()` before doing anything fancy, and be sure to work without a terminal…

> 1. Don’t assume a terminal type. Look at `TERM` and use termcap/terminfo or a library built atop them for anything beyond line-oriented plain text output, or least assume a plain teletype unless you specifically recognize the user’s terminal type.

I agree, but these days I think you can mostly get away with assuming VT100-compatible behavior.

> 4. Use the standard `` exit codes. They exist for a reason and they make use of your tool within pipelines and programs more straightforward because they make it easier to trace why a failure occurred.

I just took a look at this header file. (It defines exit codes starting at 64.) I'm not sure I've ever seen a program that uses these codes. Many programs for UNIX-like systems just use exit(1) for generic errors, or maybe something to distinguish between data errors and usage errors such as unrecognized command-line options. I mostly use Linux; maybe it's more common on BSD-based systems (it appeared "somewhere after 4.3BSD"). For example curl defines nearly 100 distinct error codes; none of them are based on .

> 5. Include both in-binary `--help`/usage information and a man page. Often a user will just need a quick refresher on argument syntax, which is what the built-in help text is for; the man page should be a comprehensive reference with examples. It should never defer to a web page or GNU `info`—it’s fine if those exist too and are pointed out, but they should not be the primary user reference.

In practice, GNU `info` tends to be the primary reference for GNU programs. The man page is often missing a lot of information.

Re: "Rules" that terminal programs follow

#130
post #113

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…

I would not do that to your own REPL unless you are really serious about it, with good documentation, escaping, etc... What if there is a file named "~"? What about "~username"? How do you escape/quote it? What if $HOME is not set, or set to something different than the actual user home directory? What about Windows? Also, a lesser known fact is that typing "~." after newline in ssh will force close the connection fr…

It's even worse than that, there are others, much more likely key combinations that are interpreted by the SSH client. For example "~v" increases the verbosity of the SSH client, "~C" opens a command line, etc.

Entering "~vicky/doc.txt" or "~Ricky/doc.txt" over SSH will actually only write "icky/doc.txt", and entering "~Chris/doc.txt" will have SSH print out it's internal command-line's usage instructions in the middle of the TUI. Screenshot from Vim: https://imgur.com/a/NCt0G9r

Post reply on HN