readline(3) 联机帮助页列出了这四个(vi、vi-move、vi-command、vi-insert)作为keymap设置的可能选项。我试过设置这些不同的选项,但它们似乎没有任何影响set editing-mode vi。
回答这个问题最简洁的方法可能是举例说明变化如何keymap产生影响。
来自联机帮助页的引用:
keymap (emacs)
Set the current readline keymap. The set of legal keymap names
is emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
vi-command, and vi-insert. vi is equivalent to vi-command;
<<snip>>
Run Code Online (Sandbox Code Playgroud)
长话短说
如果您想了解要点,请跳至标题editing-mode vi(最后一个)。
可是等等!不过,可能需要相当多的背景信息:例如, anediting-mode和 a之间的区别keymap。
特别有用的是混合键盘映射的概念,emacs用于插入文本,同时仍然可以轻松进行vi-command更改。
editing-modean和 a 和有什么不一样keymap?
只有两个s editing-mode:(emacs默认)和vi。
Run Code Online (Sandbox Code Playgroud)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。
有哪些独特的键盘映射?
Run Code Online (Sandbox Code Playgroud)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:~$
Run Code Online (Sandbox Code Playgroud)
这给我们留下了:emacs、emacs-meta、emacs-ctlx、vi和vi-insert作为独特的键盘映射来解释。区分键盘映射可能最好通过检查它们来完成......
键映射默认绑定是什么?
要查看(例如)emacs(默认)的默认键绑定,请使用:
INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^#
Run Code Online (Sandbox Code Playgroud)
您可以替换emacs为上例中的任何其他键盘映射名称。
有很多行说self-insertordo-lowercase-version不是很有用,所以要删除它们:
INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort
Run Code Online (Sandbox Code Playgroud)
各种键盘映射之间有什么区别emacs?
TL;DR:它们是对应用于 的一组映射的不同视图editing-mode emacs。
如果将第二个命令的输出放入名为emacs-standard、emacs-meta、emacs-ctlx、 、的文件中vi-command,并vi-insert为其对应的keymaps,您可以发现:
没有映射的命令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)
$
Run Code Online (Sandbox Code Playgroud)
所以emacs/emacs-standard是两者的行为功能超集emacs-ctlx这emacs-meta意味着:
keymap emacs
"\eg": glob-expand-word
"\C-x\C-r": re-read-init-file
Run Code Online (Sandbox Code Playgroud)
功能上等同于:
keymap emacs-meta
"g": glob-expand-word
keymap emacs-ctlx
"\C-r": re-read-init-file
Run Code Online (Sandbox Code Playgroud)
您可能会说第二种形式更容易阅读。
插入文本:emacsvsvi-insert
emacs-standardnot in中有 28 个命令vi-insert
+ravi@boxy:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
+ravi@boxy:~/lib/readline$
Run Code Online (Sandbox Code Playgroud)
emacs/emacs-standard基本上是 . 的超集vi-insert。因此,对于输入文本,最好使用emacs-standard键盘映射vi-insert,只要您可以轻松地在和 之间切换emacsvi-command。
vi-insertnot in中唯一的附加绑定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
Run Code Online (Sandbox Code Playgroud)
这四个中的前三个与emacs绑定冲突:
"\C-d": delete-char
"\C-n": next-history
"\C-p": previous-history
Run Code Online (Sandbox Code Playgroud)
我解决如下:
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
Run Code Online (Sandbox Code Playgroud)
editing-mode vi正如我们在上面看到的,vi、vi-command和vi-move是同一个键盘映射:
+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$
Run Code Online (Sandbox Code Playgroud)
请注意,总共只有两个不同的映射,默认情况下与 关联editing-mode vi。
当 in 时editing-mode vi,keymap使用的 s 是//vi和(起始键盘映射)。这两张地图同时只有一张处于活动状态。vi-commandvi-movevi-insert
editing-mode vi只不过是在 shell 启动时设置一个默认的键盘映射,标记为vi-insert。同样,一次只有一个键盘映射处于活动状态。此vi-insert键盘映射将大多数键映射到,self-insert因此当您按下键盘上的塑料按钮时,其上打印的符号会出现在屏幕上。
键映射允许通过使用命令vi-insert将自身交换到名为 // 的文本操作键映射vi-command,vi默认情况下绑定到键映射中的键。vi-movevi-movement-modeESCvi-insert
实际上,即使是emacs键盘映射也可以vi通过使用vi-movement-mode命令将类似文本操作的键盘映射设置为活动状态,如上面提到的混合解决方案。
或者用更简单的语言...
默认情况下,当键盘映射处于活动状态时,按下ESC可更改为键盘映射。vi-commandvi-insert
键盘vi-command映射使用标准的单按键(如 、和 )a来移动文本并与文本交互,就像编辑器的默认模式或命令模式一样。一般没有+组合。您无法在此模式下插入文本;字母键映射到编辑/移动命令。要输入文本,您可以切换到键盘映射(例如:按“插入”)。bcviCtrlkeyvi-inserti
输入文本是使用键盘映射完成的,如果文件中vi-insert有的话,键盘映射在 shell 启动时处于活动状态。在 中时按“插入”键即可切换到键盘映射(对于那些启动进入的人,则可以通过多种其他方式)。editing-mode vi.inputrcvi-insertivi-commandvi
除非您熟悉vi编辑器,否则一开始您可能会发现vi-command按键很难使用,但如果您擅长使用它,您就可以像长胡子巫师一样编辑文本。
它们是 vi 模式下不同的键盘映射。例如,我.inputrc设置了keymap不同模式下的绑定按键。摘抄:
# insert mode bindings
set keymap vi-insert
"\C-p": previous-history
"\C-n": next-history
# command mode bindings
set keymap vi-command
"|": beginning-of-line
"_": vi-first-print
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1907 次 |
| 最近记录: |