调用 readline 绑定命令后刷新 Bash 提示符

3

我的shell是GNU Bash 4.3.11,我目前将M-h绑定到调用内置命令cd ..上。

bind -x '"\eh": "cd .."'

这给了我一个巧妙的方法来浏览目录树,我可以反复按 M-h 键,而不是极其耗时的 cd .. 命令。然而,它的缺点是要么不能重置我的 $PS1 ,要么不能重新绘制我的提示符,因此我失去了当前工作目录的上下文,直到我输入新命令。
我知道的另一种选择是编写类似于
"\eh": "\C-a\C-kcd ..\C-m"

在我的.inputrc中直接输入命令存在缺点,不仅会丢失我正在输入的任何现有命令的上下文(这可能是可以解决的),而且还会打印出cd ..(我认为无法解决)。
我的期望行为是,当我处于目录~/one/two并且提示符为~/one/two$时,按下M-h后进入~/one并且提示符为~/one$,最好保留我最初输入的任何命令。我该如何实现这个功能?
2个回答

3
弄清楚了。
# maintain state
bind -x '"\200": TEMP_LINE=$READLINE_LINE; TEMP_POINT=$READLINE_POINT'
bind -x '"\201": READLINE_LINE=$TEMP_LINE; READLINE_POINT=$TEMP_POINT; unset TEMP_POINT; unset TEMP_LINE'

# "cd .." use case.
bind -x '"\206": "cd .."'
bind '"\eh":"\200\C-a\C-k\206\C-m\201"'

请注意,这会破坏许多UTF-8字符(通常0x80将是几乎未使用的C1范围,例如用于拉丁编码)。我建议使用以下替换:\300\301 \365-\367 \370-\377。(RFC 3629:“八位字节值C0、C1、F5到FF从不出现。”) - Přemysl J.

0

我来晚了,也是在这里寻找答案。首先,因为你是唯一提供信息的人,感谢你没有让它变成这样:https://xkcd.com/979/ ;) 而是指向了那个似乎有解决方案的分形角落。

在我看来,这种方法经过数小时的尝试,是唯一可以 a) 替换行内容和 b) 执行 bash 代码的方法。让我提出一些针对特定问题的建议:

如果您既想在命令行上插入某些内容,想执行代码,事情可能会变得非常棘手。对于这两个问题,都存在绑定操作,我让读者通过 help bind 找出解决方法。但在某些情况下,比如你使用 FZF 产生某个目录作为输出,并且你想要在该目录中执行 cd 命令,或者将其粘贴到你的命令中 - 这取决于在 FZF 中按下的按键 - 这时事情就变得几乎不可能。你将面临没有更新提示符的问题,或者无法在顶层 shell(具有效果的地方)执行 cd 命令。
您的解决方案将是一个多路复用的 -x 绑定,检查输出内容中的“宏”(提取并评估)或默认的传递(操纵 READLINE_LINE/POINT)。

因为解决方案有些庞大,而且受众可能有限(封闭答案...),我只会留下一个随意的要点,其中我粘贴了现在可用的代码。为了弥补简洁和未注释的缺点,我欢迎在评论或其他地方提出任何问题。希望有人能指出正确的方向。 - 与此问题相关的代码从函数bindInsertEvalWithMacrosVi开始 - 它是为Vi键绑定设计的,但同样的原则适用于正常的readline模式 - 它依赖于一些\C-x\C-...组合来在与本帖子无关的位置进行重绘。 https://gist.github.com/simlei/032470cfcd23641987f97a96749128d7


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接