我想为我的终端提供类似vim的导航,所以我补充道:
set editing-mode vi
set keymap vi
基于this到我的.inputrc
文件。 editing-mode vi
添加了vi导航。 keymap vi
做了什么,为什么需要它呢?
答案 0 :(得分:10)
来自man readline
(我的重点):
合法键映射名称的集合是emacs,emacs-standard,emacs-meta,emacs-ctlx,vi,vi-move,vi-command和vi-insert。 vi相当于vi-command
因此,在inputrc
中,您可以为不同的模式指定不同的键绑定,因此,例如,在command
模式下,您可以使用 Alt <从上一个命令中抽取最后一个参数/ kbd> p ,但是这个keybind在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
答案 1 :(得分:6)
<强> TL; DR 强>
如果您不想在默认键盘映射中更改/添加绑定,则不需要行keymap vi
。
keymap vi
所做的是声明在该点之后列出的任何绑定都适用于该键映射(与<{1}}完全相同的键映射和vi-command
)
如果您想更改插入键盘映射(例如,在您键入内容时添加vi-move
绑定以转到该行的开头),您需要在{a}下面执行此操作{1}}行。
如果您想了解Ctrl-A
模式和地图的更多信息,请跳至标题keymap vi-insert
(最后一个)。
但是等等!虽然可能需要相当多的背景信息:例如,vi
和editing-mode vi
之间的差异。
特别有用的是用于插入文本的混合editing-mode
键映射的概念,同时仍然可以轻松访问keymap
进行更改。
emacs
和vi-command
有什么区别?
只有 两个editing-mode
s:keymap
(默认值)和editing-mode
。
GNU Readline Library documentation说:
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
编辑器的模式。 ALL editing-mode vi
个vi
在emacs
中同时运行(稍后解释)。
那么editing-mode emacs
实际上做了什么?它只是在shell启动时将活动键映射设置为editing-mode
或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
作为解释的唯一键图。区分键盘图最好通过检查它们来完成......
什么是键盘映射默认绑定?
要查看(示例)emacs(默认值)的默认键绑定,请使用:
vi-insert
您可以将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
键映射有什么区别?
TL; DR:对于应用于emacs
的一组映射,它们是不同的视图。
如果第二个命令输出到名为editing-mode emacs
,emacs-standard
,emacs-meta
,emacs-ctlx
和vi-command
的文件中,则表示其对应的{{ 1}} s,你可以找到:
vi-insert
和keymap
中没有映射的NO命令也不会出现在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
vs keymap emacs-meta
"g": glob-expand-word
keymap emacs-ctlx
"\C-r": re-read-init-file
emacs
中有28个命令不在vi-insert
emacs-standard
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
键盘图。easily switch between emacs
and vi-command
。
vi-insert
中唯一不在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
只会在shell启动时设置默认键映射,标记为editing-mode vi
。同样,一次只有一个键映射处于活动状态。此vi-insert
键盘映射将大多数键映射到vi-insert
,因此当您按下键盘上的塑料按钮时,屏幕上会显示打印在其上的符号。
self-insert
keymap允许通过使用vi-insert
命令将其自身交换到名为vi-command
/ vi
/ vi-move
的文本操作键映射,绑定到默认情况下,在vi-movement-mode
键映射中使用 ESC 键。
实际上,即使vi-insert
键盘映射也可以使用emacs
命令设置vi
- 类似文本操作键映射,就像上面提到的混合解决方案一样。
或者用更简单的语言......
默认情况下,当vi-movement-mode
键盘图处于活动状态时,按 ESC 更改为vi-command
键盘映射。
vi-insert
键映射使用标准的单键按键,如 a , b 和 c 来移动文本并与之交互,比如vi-command
编辑器的默认或命令模式。通常没有 Ctrl + 键组合。您无法在此模式下插入文字;字母键映射到编辑/移动命令。要输入文字,请切换到vi
键盘映射(例如:按 i 表示&#34;插入&#34;)。
使用vi-insert
键盘映射完成输入文本,如果vi-insert
文件中有editing-mode vi
,则在shell启动时处于活动状态。通过按 i 转换为.inputrc
键映射,用于&#34;插入&#34;而在vi-insert
中(或以许多其他方式发起的vi-command
)。
除非您了解vi
编辑器,否则您最初可能会发现vi
个键很难使用,但如果您擅长它,则可以编辑长文本胡子巫师。