3 ms·
Absolutely agreed. The main problem with that is providing new features that xterm doesn't support, but terminfo pretty much refuses to add new features anyway,
by JoshTriplett 3y ago
Absolutely agreed. The main problem with that is providing new features that xterm doesn't support, but terminfo pretty much refuses to add new features anyway, so modern terminals have had to work around that with some combination of autodetection, separate environment variables, or YOLO approaches. So, at this point, I'm not sure it's worth supporting terminfo at all for most applications, either as a terminal emulator or as a CLI program. (The article makes a similar point about the negative value terminfo is providing for modern applications.)
If you're building a program that takes over the terminal screen, you probably should use one of the established libraries that abstracts over terminfo and over old non-ANSI Windows consoles. But if you're doing light terminal handling in an application that doesn't take over the screen, such as emitting colors or doing simple cursor control, forget about terminfo and just handle two or three cases: ANSI, optionally old pre-ANSI Windows consoles, and files/terminals with no support for anything. Rounding ancient terminals or terminal emulators to "no support" and giving them the same thing you'd give a redirection to a file seems entirely reasonable for a new program.
- bitwize 3y agoJust... please please please call isatty() and don't barf ANSI cruft into my buffers.
- vidarh 3y agoI'd frankly far prefer people not to call isatty(), and require switches for machine-readable output. The kind of tools that "barf ANSI cruft" are usually the tools I want to do so even when I'm piping their output into something else. It's a real nuisance to e.g. deal with options to preserve colours through a pipe for every element. There might well be exceptions where I'd prefer to default to checking isatty(), but they are few. If there was any remotely standard way of signaling the preferred default, and a remotely standard command line option to toggle that default, it'd make things a lot nicer, because I totally understand where you're coming from; I get equally annoyed just in the opposite scenarios, so the situation is a nuisance for both of us.
- JoshTriplett 3y agoI'd love to have a standard command-line tool for "run the following program with its output set to a pty, and then pipe the output to stdout". That's the most reliable way to get programs to display color and similar. Any tool whose output is ever parsed, including "parsing" as simple as "tool | grep xyz", shouldn't emit terminal escapes to a pipe by default. If `xyz` has an embedded color sequence in it, that grep will fail. Or worse, produce unexpected results. (The standard color sequences end in `m`; a grep for 'msomething' could match 'something' preceded by a color sequence.)
- vidarh 3y agoI agree, of sorts. The problem being that we have developed a culture of making user-facing user interface and APIs the same in Unix-y tools. I think "everyone" recognises the problem, but we may have different preferences about what the default should be. Personally, I'd prefer a default way of indicating "I want API behaviour now" but defaulting to more human-friendly output, because even in most cases like "tool | grep xyz" from the command line I'm still more likely to want colours etc. to stay intact through the pipeline. Most of the time that's fine, but you're of course right it will give unexpected results some time. I think my ideal expected behaviour (which would still not be perfect) would be something like: * Tools defaulting to unescaped output in scripts, but with a standard short option and/or ENV var to trigger colour output. * Tools default to colour/escaped output when run in an interactive shell even if in a pipe. * Tools being escape sequence aware, maybe with switches to turn that behaviour off if you genuinely e.g. do want to grep for sequences that may include escapes and you want them considered. But I'm not sure there is a good solution to this other than decoupling UI and API and having different defaults for tools that are expected to be "user facing" vs treated as API. I have an "ls" replacement on my system, for example, which changes formatting and adds more colour to my ls output, and it's obviously not named ls because the amount of stuff that breaks if "ls" isn't reliably the same as always is significant. It's still not great to have to separate this given that part of the ease of composing pipelines etc. is familiarity with the output, but maybe if coupling that with reasonably standard switches to turn on/off machine-friendly output.
- JoshTriplett 3y agoYes, absolutely. Also, as a pet peeve: always read your input from stdin, and if stdin isn't readable, do not assume that if stdout/stderr is a tty you're allowed to use that for input. (This assumption is broken in batch/CI/etc systems where stdout/stderr may be a tty so that a program emits color/etc, while making stdin /dev/null because there's no user interaction possible.)
- boxfire 3y agoTTY queries are written to stdout but read from stdin. That's not user interaction. E.g. if you're system doesn't have ioctl for window size (or you're over a remote serial etc), setting the cursor to the bottom right and asking it's position. Those programs break with no stdin because a tty is inherently bidirectional communication!
- JoshTriplett 3y agoSuch queries are not universally supported, and a program using them has to be prepared to expect a lack of response to the query. (This is one of many issues with such queries.)