我正在尝试通过以下配置将 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+ x,Ctrl+发送r给其自身,这将运行
_restore_command_line
。
这样你就可以运行git checkout -
和重新评估提示而不中断当前命令行。
答案2
接受的答案可以简化为:
bind -x '"\C-x\C-s":"git checkout -"'
bind '"\et":"\C-x\C-s\n"'
-
- 使用 -x 绑定我们的命令。
-
- 我们实际调用的绑定。没有任何痕迹,调用新行来更新提示。