我无法绞尽脑汁寻找解决方案简单的Readline 中的编辑任务。我只想向前删除字符,直到一个大单词的末尾,也就是说,(或多或少)直到下一个空格字符(dE
在 vim 中)。
特别是,当按下按键序列时,
> 2234I567.890 32345678
会成为
> 2234I 32345678
其中光标位置由 指示I
。
~/.inputrc
以下是我为实现这一目标而尝试添加的内容。
第一次尝试:
"\eF": vi-fWord "\eD": "\eF\C-w"
这确实会向前杀死一个大单词,但如果放置光标,它会错误地工作在单词。在这种情况下,整个词都会被杀死。
第二次尝试:
"\eF": vi-fWord "\C-x1": kill-region "\eD": "\C-@\eF\C-x1 "
这应该已经起作用了,不是吗?至少,如果我\C-@\eF\C-x1
自己在命令行上手动踢出完整的按键序列,它会起作用。然而,奇怪的是,当我按下\eD
按键序列时什么也没有发生。
- 我还考虑过使用 vi 模式命令
vi-delete-to
等,但由于完全缺乏与 Readline vi 模式相关的文档,所以不确定如何执行。
所以我来这里寻求帮助。
答案1
好的,我终于成功了。
事实证明,我只需将set-mark
功能重新映射到另一个键序列(例如, )并用这个新映射\C-x2
替换默认值。\C-@
然后一切都很好。
也许这是一个错误,\C-@
当它出现在 Readline 宏的 RHS 中时,无法按预期运行。
以下是我的设置,使Alt+ D删除输入转发到下一个空格或大单词(vim 术语)。
"\C-x0": vi-eWord
"\C-x1": kill-region
"\C-x2": set-mark
"\eF": "\C-x0\C-f"
"\eD": "\C-x2\eF\C-x1"
因为我们没有使用 shell 特定的 Readline 函数,例如shell-forward-word
,所以键绑定适用于所有使用 Readline 库的应用程序,例如 bash、(i)python 等。
答案2
答案确实在于记录不足的 vi-delete-to(默认映射到“d”)。仅当后续移动命令带有数字前缀时,此功能才有效。默认映射dE
隐式使用计数 1,但重新映射移动命令需要显式计数。
例如,在您的情况下,按键序列“d1\C-x0”将删除一个单词。您可以映射该序列,这样您就不必指定单词计数/数字来删除 1 个单词:
"d\C-x0": "d1\C-x0"
删除多个 WORD 仍然有效。
请注意,这适用于所有动作。例如,d1fe
将删除(包括)第一次出现的字母“e”,c2to
将更改为(排除)第二次出现的字母“o”。所有这些操作都可以用“.”重复,就像 vi/vim 一样。
至于你的解决方案
因为您正在使用 vi 功能,所以我假设您正在使用 vi 编辑模式。 C-@ 是一个 emacs 映射,因此您必须像您所做的那样显式映射该函数:这不是一个错误。
您可以将“Cf”替换为“x”(在光标功能下删除),这样命令就不会在行尾中断(因为光标无法向前移动)
"\C-x0": vi-eWord "\C-x1": kill-region "\C-x2": set-mark "\eD": "\C-x2\C-x0x\C-x1"
不幸的是,这个/您的解决方案的缺点不能以“vi-arg-digit”为前缀来一次性删除多个单词。