如何“绑定 -x”键盘快捷键并刷新提示

如何“绑定 -x”键盘快捷键并刷新提示

我正在尝试通过以下配置将 git 分支切换绑定到按键:

bind -x '"\et":"git checkout -"'

这像 charm 一样工作,但是我也有以下设置代码用于在 PS1 中显示分支名称:

PS1='${debian_chroot:+($debian_chroot)}\u@:\W $(parse_git_branch)\$ '

调用我的键盘快捷键后,分支名称不会刷新,直到我这样做,比如说cd .

据我所知,唯一已知的解决方法是按如下方式更新配置:

bind '"\et":"git checkout - \n"'

没什么大不了的,但我想知道在保留“-x”键的情况下实现理想行为的最佳方法是什么。到目前为止,我在谷歌上搜索到的是redraw-current-line功能,但问题是它没有安装在我的 Ubuntu 上,而且我不知道如何安装它。

答案1

redraw-current-line是 readline 中的一个命令,您无需安装它。Bash 使用 readline 库,仅此而已,该命令已经存在。您可以将其与bind内置命令一起使用。

我的测试表明,redraw-current-line重新绘制提示而不重新评估它。PROMPT_COMMAND未被触发,因此您也不能使用它来更新提示。为了比较:clear-screen行为类似。

换句话说,Bash 会记住您的提示符并重新绘制它而无需parse_git_branch再次运行。似乎真正重新评估的唯一方法是键入命令(可能是空的)并点击Enter。您的"git checkout - \n"模拟了这一点:git checkout -是命令并且\n像 一样工作Enter

我理解至少在某个方面bind -x '"\et":"git checkout -"'比 更好bind '"\et":"git checkout - \n"'。前者绑定可以在输入随机命令时使用,并且不会干扰您输入的内容。后者绑定在这种情况下会产生混乱。

但只有后者的绑定才会重新评估提示。

有一种相对复杂的方法可以让你鱼与熊掌兼得:

_save_command_line() {
   READLINE_LINE_OLD="$READLINE_LINE"
   READLINE_POINT_OLD="$READLINE_POINT"
   READLINE_LINE=
   READLINE_POINT=0
}

_restore_command_line() {
   READLINE_LINE="$READLINE_LINE_OLD"
   READLINE_POINT="$READLINE_POINT_OLD"
}

bind -x '"\C-x\C-s":"_save_command_line; git checkout -"'
bind -x '"\C-x\C-r":"_restore_command_line"'
bind '"\et":"\C-x\C-s\n\C-x\C-r"'

现在如果你输入,EsctBash 将:

  • Ctrl+ x, Ctrl+发送s给自身,这将运行_save_command_line; git checkout -;注意_save_command_line不仅保存而且还清除命令行;
  • 发送\n给自身,即Ctrl+ j,其工作方式类似Enter;所以它现在Enter在我们现在空的命令行中;这将重新评估PS1并打印一个新的提示;
  • Ctrl+ xCtrl+发送r给其自身,这将运行_restore_command_line

这样你就可以运行git checkout - 重新评估提示而不中断当前命令行。

答案2

接受的答案可以简化为:

bind -x '"\C-x\C-s":"git checkout -"'

bind '"\et":"\C-x\C-s\n"'
    1. 使用 -x 绑定我们的命令。
    1. 我们实际调用的绑定。没有任何痕迹,调用新行来更新提示。

相关内容