当前一个命令失败时,我希望我的提示显示交叉(✘)。我使用以下代码:
export PROMPT=$'%(?..✘\n)\n› '
这给了我以下输出:
› echo Hello
Hello
› asjdfiasdf
zsh: command not found: asjdfiasdf
✘
›
✘
我想修改提示,以便在 Enter 之后重新绘制提示时不重复交叉(上例中的第三种情况)。
有可能吗?
答案 0 :(得分:6)
我想我明白了。如果你发现了一个错误,请告诉我......
preexec() {
preexec_called=1
}
precmd() {
if [ "$?" != 0 ] && [ "$preexec_called" = 1 ]
then echo ✘; unset preexec_called; fi
}
PROMPT=$'\n› '
结果:
› ofaoisfsaoifoisafas
zsh: command not found: ofaoisfsaoifoisafas
✘
›
› echo $? # (not overwritten)
127
答案 1 :(得分:2)
我在zsh中执行此操作,但使用的是颜色而不是unicode字符。这是相同的原则。
首先,我设置了我的颜色,确保它们仅在受支持时使用:
case $TERM in
( rxvt* | vt100* | xterm* | linux | dtterm* | screen )
function PSC() { echo -n "%{\e[${*}m%}"; } # insert color-specifying chars
ERR="%(0?,`PSC '0;32'`,`PSC '1;31'`)" # if last cmd!=err, hash=green, else red
;;
( * )
function PSC() { true; } # no color support? no problem!
ERR=
;;
esac
接下来,我设置了一个魔术输入功能(感谢this post about an empty command(忽略这个问题,看看我在这里如何调整它):
function magic-enter() { # from https://superuser.com/a/625663
if [[ -n $BUFFER ]]
then unset Z_EMPTY_CMD # Enter was pressed on an empty line
else Z_EMPTY_CMD=1 # The line was NOT empty when Enter was pressed
fi
zle accept-line # still perform the standard binding for Enter
}
zle -N magic-enter # define magic-enter as a widget
bindkey "^M" magic-enter # Backup: use ^J
现在是时候解释捕获命令并使用其返回码来设置提示颜色:
setopt prompt_subst # allow variable substitution
function preexec() { # just after cmd has been read, right before execution
Z_LAST_CMD="$1" # since $_ is unreliable in the prompt
#Z_LAST_CMD="${1[(wr)^(*=*|sudo|-*)]}" # avoid sudo prefix & options
Z_LAST_CMD_START="$(print -Pn '%D{%s.%.}')"
Z_LAST_CMD_START="${Z_LAST_CMD_START%.}" # zsh <= 5.1.1 makes %. a literal dot
Z_LAST_CMD_START="${Z_LAST_CMD_START%[%]}" # zsh <= 4.3.11 makes %. literal
}
function precmd() { # just before the prompt is rendered
local Z_LAST_RETVAL=$? # $? only works on the first line here
Z_PROMPT_EPOCH="$(print -Pn '%D{%s.%.}')" # nanoseconds, like date +%s.%N
Z_PROMPT_EPOCH="${Z_PROMPT_EPOCH%.}" # zsh <= 5.1.1 makes %. a literal dot
Z_PROMPT_EPOCH="${Z_PROMPT_EPOCH%[%]}" # zsh <= 4.3.11 makes %. a literal %.
if [ -n "$Z_LAST_CMD_START" ]; then
Z_LAST_CMD_ELAPSED="$(( $Z_PROMPT_EPOCH - $Z_LAST_CMD_START ))"
Z_LAST_CMD_ELAPSED="$(printf %.3f "$Z_LAST_CMD_ELAPSED")s"
else
Z_LAST_CMD_ELAPSED="unknown time"
fi
# full line for error if we JUST got one (not after hitting <enter>)
if [ -z "$Z_EMPTY_CMD" ] && [ $Z_LAST_RETVAL != 0 ]; then
N=$'\n' # set $N to a literal line break
LERR="$N$(PSC '1;0')[$(PSC '1;31')%D{%Y/%m/%d %T}$(PSC '1;0')]"
LERR="$LERR$(PSC '0;0') code $(PSC '1;31')$Z_LAST_RETVAL"
LERR="$LERR$(PSC '0;0') returned by last command"
LERR="$LERR (run in \$Z_LAST_CMD_ELAPSED):$N"
LERR="$LERR$(PSC '1;31')\$Z_LAST_CMD$(PSC '0;0')$N$N"
print -PR "$LERR"
fi
}
最后,设置提示符:
PROMPT="$(PSC '0;33')[$(PSC '0;32')%n@%m$(PSC '0;33') %~$PR]$ERR%#$(PSC '0;0') "
以下是它的外观:
根据上述内容改编的问题更直接的答案:
function magic-enter() { # from https://superuser.com/a/625663
if [[ -n $BUFFER ]]
then unset Z_EMPTY_CMD # Enter was pressed on an empty line
else Z_EMPTY_CMD=1 # The line was NOT empty when Enter was pressed
fi
zle accept-line # still perform the standard binding for Enter
}
zle -N magic-enter # define magic-enter as a widget
bindkey "^M" magic-enter # Backup: use ^J
function precmd() { # just before the prompt is rendered
local Z_LAST_RETVAL=$? # $? only works on the first line here
# full line for error if we JUST got one (not after hitting <enter>)
if [ -z "$Z_EMPTY_CMD" ] && [ $Z_LAST_RETVAL != 0 ]; then
echo '✘'
fi
}
PROMPT=$'\n› '
使用屏幕截图: