![](/img/trans.png)
[英]Why can't I set \C-e in inputrc to be end-of-line for vi-command keymap?
[英]What does "set keymap vi" do?
我想为我的终端提供类似 vim 的导航,所以我添加了:
set editing-mode vi
set keymap vi
基于此到我的.inputrc
文件。 editing-mode vi
添加 vi 导航。 keymap vi
有什么作用,我为什么需要它?
长话短说
如果您不想在默认键盘映射中更改/添加绑定,则不需要keymap vi
行。
keymap vi
所做的是 state ,在该点之后列出的任何绑定都适用于该键盘映射(与vi-command
和vi-move
完全相同的键盘映射)。
如果您想更改插入键映射(例如,在您键入时将Ctrl-A
绑定到行的开头 go),您需要在键keymap vi-insert
行下方执行此操作。
如果您想了解有关vi
模式和地图的更多信息,请跳至标题editing-mode vi
(最后一个)。
但是等等:虽然可能需要相当多的背景信息,例如, editing-mode
和keymap
之间的区别。
特别有用的是混合emacs
映射的概念,用于插入文本,同时仍然很容易进入vi-command
进行更改。
editing-mode
和keymap
有什么区别?
只有两种editing-mode
: emacs
(默认)和vi
。
editing-mode The editing-mode variable controls which default set of key bindings is used. By default, Readline starts up in Emacs editing mode, where the keystrokes are most similar to Emacs. This variable can be set to either `emacs' or `vi'.
注意editing-mode
和keymap
之间的区别:在editing-mode vi
中,两个(是的,只有两个,请继续阅读)键盘映射被换入和换出,以模拟vi
编辑器的不同模式。 所有emacs
都在editing-mode emacs
中同时运行(稍后解释)。
那么editing-mode
实际上做了什么? 它只是在 shell 启动时将活动键盘映射设置为emacs
或vi-insert
。
什么是独特的键盘映射?
Acceptable keymap names are emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert. vi is equivalent to vi-command; emacs is equivalent to emacs-standard.
虽然没有记录,但vi
/ vi-command
和vi-move
键盘映射也是等效的:
+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$
这给我们留下了: emacs
、 emacs-meta
、 emacs-ctlx
、 vi
和vi-insert
作为唯一的键盘映射来解释。 区分键盘映射可能最好通过检查它们来完成......
什么是键盘映射默认绑定?
要查看(示例)emacs(默认值)的默认键绑定,请使用:
INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^#
您可以将emacs
替换为上面示例中的任何其他键盘映射名称。
有很多行说self-insert
或do-lowercase-version
这不是很有用,所以要删除它们:
INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort
各种emacs
键盘映射之间有什么区别?
TL;DR:它们是应用于editing-mode emacs
的一组映射的不同视图。
如果将第二条命令的 output 分别放入名为emacs-standard
、 emacs-meta
、 emacs-ctlx
、 vi-command
和vi-insert
的文件中,分别对应对应的keymap
,可以发现:
在emacs-meta
和emacs-ctlx
中没有映射的命令也没有出现在emacs-standard
中:
$ comm -13 <(sed -r 's/.*: (\S+)/\1/' emacs-standard|sort) <(sed -r 's/.*: (\S+)/\1/' emacs-ctlx|sort)
$ comm -13 <(sed -r 's/.*: (\S+)/\1/' emacs-standard|sort) <(sed -r 's/.*: (\S+)/\1/' emacs-meta|sort)
$
所以emacs
/ emacs-standard
是emacs-ctlx
和emacs-meta
的行为功能超集这意味着:
keymap emacs
"\eg": glob-expand-word
"\C-x\C-r": re-read-init-file
在功能上等同于:
keymap emacs-meta
"g": glob-expand-word
keymap emacs-ctlx
"\C-r": re-read-init-file
您可能会争辩说第二种形式更容易阅读。
插入文本: emacs
vs vi-insert
emacs-standard
中有 28 个命令, vi-insert
中没有
+ravi@boxy:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
+ravi@boxy:~/lib/readline$
emacs
/ emacs-standard
基本上是vi-insert
的超集。 因此,对于键入文本,最好使用emacs-standard
键盘映射而不是vi-insert
,只要您可以轻松地在emacs
和vi-command
之间切换。
vi-insert
中唯一的附加绑定不是emacs-standard
中的:
+ravi@boxy:~/lib/readline$ comm -23 vi-insert emacs-standard
"\C-d": vi-eof-maybe
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\e": vi-movement-mode
这四个中的前三个与emacs
绑定冲突:
"\C-d": delete-char
"\C-n": next-history
"\C-p": previous-history
我解决如下:
set keymap emacs
"\e": "kj" # see https://unix.stackexchange.com/questions/303631/how-can-i-setup-a-hybrid-readline-with-emacs-insert-mode-and-vi-command-mode
"\C-d": delete-char # eof-maybe: ^D does nothing if there is text on the line
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\C-y": previous-history # historY
"\e\C-y": previous-history
editing-mode vi
正如我们在上面看到的, vi
、 vi-command
和vi-move
是同一个键盘映射:
+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$
请注意,总共只有两个不同的地图,默认情况下与editing-mode vi
相关联。
在editing-mode vi
中,使用的keymap
是vi
/ vi-command
/ vi-move
和vi-insert
(起始键盘映射)。 一次只有这两个地图中的一个处于活动状态。
editing-mode vi
只是在 shell 启动时设置默认键盘映射,标记为vi-insert
。 同样,一次只有一个键映射处于活动状态。 此vi-insert
键盘映射将大多数键映射为self-insert
,因此当您按下键盘上的塑料按钮时,其上打印的符号会出现在屏幕上。
vi-insert
键盘映射允许通过使用vi-movement-mode
命令将其自身交换到称为vi-command
/ vi
/ vi-move
的文本操作键盘映射,默认情况下绑定到vi-insert
键盘映射中的ESC键。
实际上,即使是emacs
键盘映射也可以通过使用vi-movement-mode
命令将类似vi
的文本操作键盘映射激活,就像上面提到的混合解决方案一样。
或者用更简单的语言...
默认情况下,当vi-insert
键盘映射处于活动状态时,按ESC键更改为vi-command
键盘映射。
vi-command
键盘映射使用标准的单一按键,如a 、 b和c来移动文本并与文本交互,就像vi
编辑器的默认或命令模式一样。 通常没有Ctrl + 组合键。 您不能在此模式下插入文本; 字母键映射到编辑/移动命令。 要输入文本,您可以切换到vi-insert
键盘映射(例如:按i表示“插入”)。
输入文本是使用vi-insert
键盘映射完成的,如果您的.inputrc
文件中有editing-mode vi
,则该键盘映射在 shell 启动时处于活动状态。 通过在vi-command
中按i进行“插入”来切换到vi-insert
键盘映射(或者以许多其他方式启动vi
)。
除非您了解vi
编辑器,否则一开始您可能会发现vi-command
键非常难用,但如果您熟练使用它,您就可以像长胡子巫师一样编辑文本。
来自man readline
(我的重点):
合法的键盘映射名称集是 emacs、emacs-standard、emacs-meta、emacs-ctlx、vi、vi-move、vi-command 和 vi-insert。 vi 等同于 vi 命令
因此,在您的inputrc
中,您可以为不同的模式指定不同的键绑定,因此,例如,在command
模式中,您可以使用Alt p从上一个命令中抽出最后一个参数,但此键绑定在insert
模式中无效(在此无论如何简单的设置):
set editing-mode vi
set keymap vi-command
# these are for vi-command mode
"\e[A": history-search-backward
"\e[B": history-search-forward
"\ep": yank-last-arg
set keymap vi-insert
# these are for vi-insert mode
"\e[A": history-search-backward
"\e[B": history-search-forward
Control-l: clear-screen
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.