繁体   English   中英

“set keymap vi”有什么作用?

[英]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-commandvi-move完全相同的键盘映射)。

如果您想更改插入键映射(例如,在您键入时将Ctrl-A绑定到行的开头 go),您需要在键keymap vi-insert行下方执行此操作。

如果您想了解有关vi模式和地图的更多信息,请跳至标题editing-mode vi (最后一个)。

但是等等:虽然可能需要相当多的背景信息,例如, editing-modekeymap之间的区别。

特别有用的是混合emacs映射的概念,用于插入文本,同时仍然很容易进入vi-command进行更改。

editing-modekeymap有什么区别?

只有两种editing-modeemacs (默认)和vi

GNU Readline 库文档说:

 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-modekeymap之间的区别:在editing-mode vi中,两个(是的,只有两个,请继续阅读)键盘映射被换入和换出,以模拟vi编辑器的不同模式。 所有emacs都在editing-mode emacs中同时运行(稍后解释)。

那么editing-mode实际上做了什么? 它只是在 shell 启动时将活动键盘映射设置为emacsvi-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-commandvi-move键盘映射也是等效的:

+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$ 

这给我们留下了: emacsemacs-metaemacs-ctlxvivi-insert作为唯一的键盘映射来解释。 区分键盘映射可能最好通过检查它们来完成......

什么是键盘映射默认绑定?

要查看(示例)emacs(默认值)的默认键绑定,请使用:

INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^#

您可以将emacs替换为上面示例中的任何其他键盘映射名称。

有很多行说self-insertdo-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-standardemacs-metaemacs-ctlxvi-commandvi-insert的文件中,分别对应对应的keymap ,可以发现:

emacs-metaemacs-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-standardemacs-ctlxemacs-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 ,只要您可以轻松地在emacsvi-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

正如我们在上面看到的, vivi-commandvi-move同一个键盘映射:

+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$ 

请注意,总共只有两个不同的地图,默认情况下与editing-mode vi相关联。

editing-mode vi中,使用的keymapvi / vi-command / vi-movevi-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键盘映射使用标准的单一按键,如abc来移动文本并与文本交互,就像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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM