Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Colored-character displayed on CTRL-C ?



On 2013-09-23 at 17:37 +0000, Larry Schrof wrote:
> Recent versions of bash have this very nifty feature where, when you hit CTRL-C to terminate a command line and get a new prompt on a new line, something like ^C with a yellow background is displayed to help remind you that the command is not actually executed.
> 
> With my vision impairment, simply using the event number in my shell prompt is not sufficient. I'd really like ideas on the best way to tell zsh to display a character with a yellow background on CTRL-C, followed by taking me to a new prompt on the next line.
> 
> I'm speculating this would start by setting up a trap on the right signal?

Looking at the reason for the requirements, rather than the exact
requirement stated, would it be helpful to instead update your prompt to
show that the previous command was terminated with a signal, using a
long name instead of just a number?  In this sample below, the
"{SIGINT}" is in red:

-phil@redoubt:p1[11:55]17½(1006)~% sleep 3
^C
{SIGINT}-phil@redoubt:p1[12:07]17¼(1007)~% 

My prompt configuration includes:

  zmodload -i zsh/parameter || return 1
  function prompt_pdp_precmd {
    local exitstatus=$?
    emulate -L zsh  # ksh_arrays breaks us badly
    psvar=()
    # [...]
    psvar[1]=$exitstatus
    if [[ $exitstatus -ge 128 ]];   then psvar[1]=SIG${signals[$exitstatus-127]:-}
                                         [[ $psvar[1] == SIG ]] && psvar[1]=$exitstatus
    elif [[ $exitstatus -eq 127 ]]; then psvar[1]='127/CmdNotFound'         # SUSv4 XCU 2.8.2
    elif [[ $exitstatus -eq 126 ]]; then psvar[1]='126/CmdNotExecutable'    # SUSv4 XCU 2.8.2
    elif [[ $exitstatus -eq 125 ]]; then psvar[1]='125/GitBisectUntestable' # git
    fi
    # [... other stuff affecting psvar[2]..psvar[5]]
    return $exitstatus
  }

Then part of the prompt configuration would, in more modern zsh idiom,
include the string:

  %(?..%F{red}{%v}%f)

So, if and only if the last command exited non-true, show {exitstatus}
in the prompt, where that is a number if it was a non-signal exit, else
a signal name, and some common special-meanings also shown.

You could use psvar[2] to hold a colour name based upon the exitstatus,
and embed that in the prompt; just note that %2v is not expanded inside
a %F{...} so you would instead have to enable prompt_subst:

  setopt prompt_subst
  PS1='%(?..%F{$psvar[2]}%K{$psvar[3]}{%v}%k%f)%~%# '

That allows for psvar[2] holding a foreground colour and psvar[3]
holding a background colour.

% setopt prompt_subst
% psvar=(SIGINT red yellow); false; print -P '%(?..%F{$psvar[2]}%K{$psvar[3]}{%v}%k%f)%~%# '
{SIGINT}~% 

(where that is showing "{SIGINT}" in red text on a yellow background).

-Phil



Messages sorted by: Reverse Date, Date, Thread, Author