I’m trying to make an über-simple (single-character) prompt that gives me as much information as possible. Here’s what I have at the moment (had it for ages, can’t remember where I found the original):
# RPS1="['%1v', '%2v', '%3v', '%4v', '%5v', '%6v', '%7v', '%8v', '%9v']" # debug
PS1=" %(?|%2F|%1F)%1(V|%1v|%(#|#|:))%(?|%2f|%1f) "
function zle-line-init {
zle -K vicmd
}
zle -N zle-line-init
function zle-keymap-select {
psvar[1]="${${KEYMAP/(main|viins)/>}/vicmd/}"
zle reset-prompt
psvar[1]=""
}
zle -N zle-keymap-select
This is fairly simple; it initializes the prompt into command mode on rendering, and displays a :
prompt when in the vi’s “command” mode, and a >
prompt (by changing psvar[1]
) when in vi’s “insert” mode. In addition, the :
is replaced with #
if you are acting as root, and the color of the character exhibits the exit status of the last command.
When the keymap changes (that is, when I toggle through the “command” and “insert” modes using, as an example, a
and then the escape key, the $?
exit-status is overtrodden with a successful 0
status, thus causing the prompt to display in green instead of red (even if the previous command failed). How can I save or set the prompt such that the %(?|…|…)
portions of $PS1
will properly display the exit status of the last command sent to the shell?
I got the following answer from Bart Schaefer on the zsh-users
mailing list. It works!
This was fixed in July 2010, so eventually you won't need to do anything:
* users/15217: Src/Zle/zle_main.c: use top-level status when redrawing prompt.
In the meantime, try this:
function zle-keymap-select { local Q=$? psvar[1]="${${KEYMAP/(main|viins)/>}/vicmd/}" (return $Q) zle reset-prompt psvar[1]="" }
If your zsh is recent enough to have anonymous functions, you can replace the subshell
(return $Q)
with(){ return $Q }
.