“设置keymap vi”有什么作用?

时间:2012-04-03 22:27:48

标签: bash shell

我想为我的终端提供类似vim的导航,所以我补充道:

set editing-mode vi
set keymap vi

基于this到我的.inputrc文件。 editing-mode vi添加了vi导航。 keymap vi做了什么,为什么需要它呢?

2 个答案:

答案 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(最后一个)。

但是等等!虽然可能需要相当多的背景信息:例如,viediting-mode vi之间的差异。

特别有用的是用于插入文本的混合editing-mode键映射的概念,同时仍然可以轻松访问keymap进行更改。

emacsvi-command有什么区别?

只有 两个editing-mode s:keymap(默认值)和editing-mode

GNU Readline Library documentation说:

emacs

请注意viediting-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 viviemacs中同时运行(稍后解释)。

那么editing-mode emacs实际上做了什么?它只是在shell启动时将活动键映射设置为editing-modeemacs

有哪些独特的键盘图?

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. / vivi-command键映射也是等效的:

vi-move

这使我们得到:+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move) +ravi@boxy:~$ emacsemacs-metaemacs-ctlxvi作为解释的唯一键图。区分键盘图最好通过检查它们来完成......

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

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

vi-insert

您可以将INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^# 替换为上述示例中的任何其他键映射名称。

有很多行说emacsself-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 emacsemacs-standardemacs-metaemacs-ctlxvi-command的文件中,则表示其对应的{{ 1}} s,你可以找到:

vi-insertkeymap中没有映射的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) $ emacsemacs-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 vivivi-command同一个键映射:

vi-move

请注意,共有两个不同的地图,默认情况下会与+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move) +ravi@boxy:~$ 相关联。

editing-mode vi时,正在使用的editing-mode vikeymap / vi / vi-commandvi-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个键很难使用,但如果您擅长它,则可以编辑长文本胡子巫师。