在 ZSH 中重置提示符时,如何保持最后一个命令的退出状态?

发布于 2024-10-16 19:34:39 字数 905 浏览 2 评论 0原文

我正在尝试制作一个超级简单(单字符)的提示,为我提供尽可能多的信息。这是我现在所拥有的(已经使用了很长时间,不记得在哪里找到原件了):

# 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

这相当简单;它在渲染时将提示符初始化为命令模式,并在 vi 的“命令”模式下显示 : 提示符,以及 > 提示符(通过更改 psvar [1]) 当处于 vi 的“插入”模式时。此外,如果您以 root 身份运行,则 : 会替换为 #,并且字符的颜色显示最后一个命令的退出状态。

我的问题:

当键盘映射发生变化时(即,当我使用 a 作为示例,然后使用转义键 $? 在“命令”和“插入”模式之间切换时) exit-status 被成功的 0 状态所覆盖,从而导致提示显示为绿色而不是红色(即使上一个命令失败)。这样 $PS1%(?|…|…) 部分将正确显示发送到 shell 的最后一个命令的退出状态 ?

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.

My problem:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沐歌 2024-10-23 19:34:39

我在 zsh-users 邮件列表上从 Bart Schaefer 那里得到了以下答案。有用!

此问题已于 2010 年 7 月修复,因此最终您不需要执行任何操作:

 * users/15217: Src/Zle/zle_main.c: 重画提示时使用顶级状态。

同时,试试这个:

函数 zle-keymap-select {
本地Q=$?
psvar[1]="${${KEYMAP/(main|viins)/>}/vicmd/}"
(返回$Q)
zle 重置提示
psvar[1]=""
}

如果您的 zsh 足够新,可以拥有匿名函数,您可以将子 shell (return $Q) 替换为 (){ return $Q }

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 }.

纸短情长 2024-10-23 19:34:39
function zle-keymap-select {
  local saved_exitcode=$?
  psvar[1]="${${KEYMAP/(main|viins)/>}/vicmd/}"
  zle reset-prompt
  psvar[1]=""
  return $saved_exitcode
}
function zle-keymap-select {
  local saved_exitcode=$?
  psvar[1]="${${KEYMAP/(main|viins)/>}/vicmd/}"
  zle reset-prompt
  psvar[1]=""
  return $saved_exitcode
}
九八野马 2024-10-23 19:34:39
oldexitcode=$?
∶
# do stuff...
∶
( exit $oldexitcode )
oldexitcode=$?
∶
# do stuff...
∶
( exit $oldexitcode )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文