Live data from Hacker News

"Rules" that terminal programs follow

jvns.ca

131–140 of 153 posts

Re: "Rules" that terminal programs follow

#132
post #82

Earlier quoted context omitted.

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").

According to stty(1), ”cbreak” is a negative alias of “icanon”, which simply enables the special functions of the ‘erase’ (backspace), ‘kill’ (Ctrl-U), ‘werase’ (Ctrl-W), and ‘rprnt’ (Ctrl-R) keybindings. “cooked” mode includes “icanon”.

So no, I do not think that what you wrote is correct. From what I can tell, the line-by-line mode is “extproc”.

Re: "Rules" that terminal programs follow

#133

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…

Oh, and I just remembered where this always burns me. It's cases like this: ./myprogram --config=~/.config/myprogram Of course, many flags parsers are aware of this, or at least accidentally aware of this, because you can write it in a form that your shell will expand. ./myprogram --config ~/.config/myprogram For some reason, my muscle memory requires me to type the =. I don't know why. It's probably a habit I picked…

I have the same habit. The lack of tilde expansion after the equals sign has helped a bit in breaking this habit, however.

Interestingly, bash does do tilde expansion, but not tab completion, after the first equal sign, and after every colon, in variable-style arguments:

  $ /bin/echo --foo=~ bar=~:~root
  --foo=~ bar=/home/jtm:/root
While tab completion can be fixed in appropriate contexts using custom completion functions (e.g., [1]), AFAIK there's no way to customize tilde expansion contexts (other than the fact that tilde expanding variable-style arguments is disabled in POSIX mode).

[1] https://github.com/scop/bash-completion/blob/8a8880db78e9b04...

Re: "Rules" that terminal programs follow

#134
post #107

Earlier quoted context omitted.

How can you grep output if there's no output? Can you provide a concrete example of such an application?

Some applications print usage information (e.g. with --help flag) to stderr. That is a bit annoying when there is a lot of output and I just want to grep for some flag, since the first attempt will fail and then I have to try again after adding 2>&1.

If I pass the --help flag, I'm explicitly asking the program to print the help text. In this case it's appropriate for the help text to be written to standard output since the help text is the output.

If the user passes invalid options and inputs, then the program should produce no output and any error or help messages should be written to the error stream. It's important that these messages end up on the terminal when one gets the command invocation wrong while trying to pipe data into another program. If they're written to standard output, the program on the other end of the pipe will slurp all the error messages up and try to parse them as though they were valid inputs.

Re: "Rules" that terminal programs follow

#135
post #117

Earlier quoted context omitted.

What combinations can be assumed to be legible? I think if a terminal user has their colors configured so that some of the 8 ASCII colors aren’t legible on their background, that’s on them, with the exception of white and black. It seems like the only way to satisfy your ask is to not use color at all.

The default configurations of most terminals includes illegible color combinations. So I think it's not on every user to somehow design optimal color palette settings on their computer that work in all combinations (if they even can), but rather on the developers of software not to say "Hey, I bet every yellow would be legible on white" or "Yolo, I bet yellow is legible on every background, so I'm just going to set t…

> The default configurations of most terminals includes illegible color combinations

This hasn’t been my experience - while I’m not familiar with a wide breadth of terminal emulators, all the ones I’ve used have a default black background with the ANSI colors being very bright, making them clearly visible. I would again say that if a terminal emulator has some of the standard ANSI colors set to not be visible on their default background, that is the terminal emulator’s problem, as it is clearly undesirable.

And of course, once a terminal program starts changing the background color then it can’t make any assumptions about which of the user’s colors will be visible - which is why, as you say, the background color should not be changed without a very good reason. If the bg is set, it should be very easy to switch it to either a “dark mode” or “light mode” to make colors visible.

But some assumptions must be made in order to make any use of color, and “the 6 standard ANSI colors (red, green, yellow, magenta, cyan, blue) are visible on the user’s background” seems like it has to be the safest assumption.

I am in support of terminal programs respecting a universal configuration to disable color: https://no-color.org/

Re: "Rules" that terminal programs follow

#136

Earlier quoted context omitted.

How can you grep output if there's no output? Can you provide a concrete example of such an application?

I think what they meant was something like: > Unless your app doesn't generate [stdout] output,then grepping the [visible] output will not work if it's stderr and it will be confusing With the first "output" meaning "specifically stdout", and the second meaning "what you see on the terminal". As in, you run a command, see it printed a lot of stuff, so then you do it again but piping it to `grep` or `less`, and realiz…

I see what you mean. My logic only really applies to the simpler programs which exclusively use the standard file descriptors. It gets fuzzier when the output of a program is an actual file somewhere.

The output of a package manager is the packages. The text it writes to the terminal is not part of the output, it's just the program's log. I haven't thought about what's appropriate in this situation. By unix standards package managers shouldn't even be printing anything to begin with.

Re: "Rules" that terminal programs follow

#137
post #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.

This would massively complicate kernel path resolution on many systems. Taking Linux as an example, even in the simplest cases, ~user expansion as typically implemented — via the getpwnam(3) libc function, which in itself implies a rather unfortunate dependency — requires reading and parsing /etc/passwd, and may also require access to network directory services like LDAP.

Re: "Rules" that terminal programs follow

#138

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

You think that's hard, try getting out of vi when you're on a keyboard from an unfamiliar country.

Vim tells you how to quit when you press ctrl-c. It even tells you how to quit the moment you launch it. The meme about how impossible it is to quit Vim is nonsense.

Re: "Rules" that terminal programs follow

#139
post #130
post #113

Earlier quoted context omitted.

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 midd…

That is only after a newline, so if you typed 'cat' before the filename, for instance, it would work just fine.

Re: "Rules" that terminal programs follow

#140
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.

Sure there is a reason, just not a good one. Bad defaults are rather sticky. And the keybinding would be ergonomic, not random
Post reply on HN