1

I wanted a simple way of displaying errors in red, and inputs in green in zsh. I found this response, that works well, but it doesn't implement the input color. I'm not really a unix developper, so I tried some things, but it doesn't work. How can I change the input color to green using this method or a similar one?

Here's what I actually have in my .zshrc:

setcolor()
{
    case "$1" in
    red)
        tput setaf 1
        ;;
    normal)
        tput sgr0
        ;;
    green)
        tput setaf 2
        ;;
    esac
}

make standard error red

rederr() { while read -r line do setcolor $errorcolor echo "$line" setcolor normal done }

errorcolor=red

errfifo=${TMPDIR:-/tmp}/errfifo.$$ mkfifo $errfifo

to silence the line telling us what job number the background job is

exec 2>/dev/null rederr <$errfifo& errpid=$! disown %+ exec 2>$errfifo

Kyrela
  • 41

1 Answers1

1

stdin is an input stream, there's nothing to colour there. I assume you mean you want to colour green the echo of what you type in your terminal which is done either by the terminal device driver in the kernel or by applications themselves when they implement their own line editor.

If you know output to the terminal is only going to be done via stdout, stderr or the input echo (by the kernel or by applications that implement their own line editor and open /dev/tty instead of using stdout/stderr for echo), you could make your stdout/stderr colourizers change the color to green after having output something making green effectively the default colour for anything that is not output via stdout or stderr:

zmodload zsh/system
autoload colors; colors
colour-stream() {
  local buf output_colour=$fg[$1] after_colour=$fg[$2]
  while sysread buf; do
    syswrite -- $output_colour$buf$after_colour
  done > /dev/tty
}
exec 1> >(colour-stream default green) \
     2> >(colour-stream red     green)

Anything written to the terminal by opening $TTY or /dev/tty directly, such as the sudo password prompt, or echo test > /dev/tty would also appear green.

Some shells, such as bash will not run interactively when their stderr is not going to a terminal. You can run bash -i to work around it, but beware that since bash's readline outputs the input echo on stderr, it will appear red. Other applications using readline such as gdb or python may use stdout or stderr or open /dev/tty for the input echo, YMMV. It will probably get worse with TUI applications.

  • Thanks, It does absolutely what I want... But as you said, it completely breaks TUI programs like nano or ranger. – Kyrela Mar 08 '22 at 10:20