HackerTrans
TopNewTrendsCommentsPastAskShowJobs

_rmcx

no profile record

comments

_rmcx
·4 năm trước·discuss
> Have you considered that many of us want ansi codes in the pipeline?

Yes I have. Using /dev/tty doesn't stop an application's author from adding a --color that lets their program send color codes to stdout. But if the author doesn't use /dev/tty either stdout or stderr of their application can't be redirected.
_rmcx
·4 năm trước·discuss
> This is my first time hearing of this functionality.

I was also surprised when I discovered this. IMO this should be used everywhere but I've rarely seen it.

> How does it work with buffered stdout? For example, if you wanted to colour a single word?

This is not affected by buffering. What matters is what the output device/file/stream gets eventually.

How coloring a single word works depends on how you use it.

You can do

    write_and_flush_to_dev_tty(BEGIN_RED_TEXT);
    write_and_flush_to_dev_tty("word");
    write_and_flush_to_dev_tty(END_RED_TEXT);
The write_and_flush_... pseudo functions are written in this way just to make it clear that I'm describing the behavior when the output gets the bytes immediately. I don't mean that you should use /dev/tty like this.

Redirection won't have any effect on these lines of code. You always get a red "word" on the terminal. The redirection target doesn't get anything.

    write_and_flush_to_dev_tty(BEGIN_RED_TEXT);
    write_and_flush_to_stdout("word");
    write_and_flush_to_dev_tty(END_RED_TEXT);
When directly used on a terminal, you get a red "word" on your terminal, but when you do redirection, the target only gets plaintext "word".

    write_and_flush_to_dev_tty(BEGIN_RED_TEXT);
    write_and_flush_to_stdout("word");
    write_and_flush_to_stdout(END_RED_TEXT);
When redirected, your terminal stays red after the red "word" is printed, and your redirection target gets an extra escape code.

When stdout is a tty, /dev/tty is the same as stdout, so a write that goes to one goes to the other. In this case, even if you don't flush after write immediately it's likely not a problem. Still it's something that the developer should pay attention to.

-------------

Edit:

Please ignore all the pseudocode examples. They don't convey what I wanted to express.

Just use /dev/tty in the same way as how you would use stdin/stdout/stderr that is connected to a terminal. Only difference is that it is a rw device that can be used for input and output at the same time.
_rmcx
·4 năm trước·discuss
One thing that the author doesn't seem to know about is /dev/tty. In the article the escape codes are just sent to stdout. Though an awful lot of applications (including the greatest ones) do this, IMHO this is wrong. The terminal control codes are used to control a terminal, and they are often not meant to be part of the output stream, for example when the output is piped or redirected to a text file. When what you intend to do is to make your output fancy only when the output is a terminal, surely you should just send everything to stdout and use isatty to decide whether to also send those terminal control codes. But if what you want to build is a whole TUI like vim or the author's example app, you should send all the control to /dev/tty. This way if needed you can extend your app to be able to be a useful part of a pipe, as bytes sent to /dev/tty will not be redirected but will always be handled by the terminal. To prove that this can be useful, fzf, a fuzzy matcher, uses a TUI to let users input the pattern and pick among the matches, and prints the result to stdout. Sadly, however, it uses stderr to control the terminal instead of /dev/tty; this makes its ability to print error messages somewhat limited and its behavior unexpected when stderr is redirected. Also imagine that you can use vim in a pipe, instead of sed or awk, to see the effect of your edits live. Also, try `vi > /dev/null`. I'd say the behavior is a bug. IIRC ncurses makes use of /dev/tty and by default makes the app made with it redirectable, and this is a reason we should use it in the 21st century, among others. What's sad to me is that so far all the Rust terminal libs I've seen ignore /dev/tty, so it's impossible to use them to build something that both have a good TUI and can be used in pipes.