"设置keymap vi"有什么作用?

Vla*_*ala 14 bash shell

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

set editing-mode vi
set keymap vi
Run Code Online (Sandbox Code Playgroud)

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

jas*_*yan 11

man readline(我的重点):

合法键映射名称的集合是emacs,emacs-standard,emacs-meta,emacs-ctlx,vi,vi-move,vi-command和vi-insert. vi相当于vi-command

因此,在您inputrc可以为不同模式指定不同的键绑定,因此,例如,在command模式中,您可以从上一个命令中Altp抽取最后一个参数,但是此键绑定在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
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,`"\ep"` 是 `ESC` + `p`。而 `"\e[A"` 是 `ESC` + `[`、`SHIFT` + `a`。 (2认同)

Tom*_*ale 9

TL; DR

如果您不想在默认键盘映射中更改/添加绑定,则不需要该行keymap vi.

什么keymap vi做的是,在这之后列出的任何绑定适用于键盘映射(这是状态正好相同的键盘映射为vi-commandvi-move).

如果要更改插入键映射(例如,Ctrl-A在键入时添加绑定以在行的开头处),则需要在keymap vi-insert一行下方执行此操作.

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

可是等等!虽然可能需要相当多的背景信息:例如,editing-modea和a 之间的差异keymap.

特别有用的是emacs用于插入文本的混合键映射的概念,同时仍然可以轻松地vi-command进行更改.

editing-modea和a有keymap什么区别?

只有 2个editing-modeS: emacs(默认)和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'.
Run Code Online (Sandbox Code Playgroud)

注意区别之间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.
Run Code Online (Sandbox Code Playgroud)

虽然没有记录,但vi/ vi-commandvi-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独特的键盘布局来解释.区分键盘图最好通过检查它们来完成...

keymaps默认绑定有哪些?

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

INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^#
Run Code Online (Sandbox Code Playgroud)

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

有许多行说self-insertdo-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-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)
$
Run Code Online (Sandbox Code Playgroud)

所以,emacs/ emacs-standard是两者的行为上的功能超集emacs-ctlxemacs-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

有28个命令在emacs-standardvi-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-insertemacsvi-command

在唯一的附加绑定vi-insertemacs-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.

editing-mode vi时,keymap在使用中s为vi/ vi-command/ vi-movevi-insert(起始键映射).这两个地图中只有一个一次处于活动状态.

editing-mode vi只是在shell启动时设置默认键映射,标记为vi-insert.同样,一次只有一个键映射处于活动状态.此vi-insert键盘映射大多数键,self-insert因此当您按下键盘上的塑料按钮时,屏幕上会显示打印在其上的符号.

所述vi-insert键映射允许自身被交换到称为文本操纵键映射vi-command/ vi/ vi-move通过使用vi-movement-mode命令,结合到ESC默认在键vi-insert的键映射.

实际上,即使是键emacs映射也可以vi通过使用vi-movement-mode命令来设置类似文本操作键映射,就像上面提到的混合解决方案一样.

或者用更简单的语言......

默认情况下,按键ESC可在vi-command键盘vi-insert映射处于活动状态时更改为键盘映射.

vi-command键盘映射使用标准的,单按键一样a,bc移动,并与文字互动,就像vi编辑器的默认或命令模式.通常没有Ctrl+ key组合.您无法在此模式下插入文字; 字母键映射到编辑/移动命令.要键入文本,请切换到vi-insert键盘映射(例如:按i"插入").

输入文本是使用vi-insertkeymap 完成的,如果你editing-mode vi.inputrc文件中有shell,它将在shell启动时处于活动状态.vi-insert通过在输入时按i"插入" vi-command(或以其他许多方式启动vi)来切换到键映射.

除非你知道vi编辑器,否则你vi-command最初可能会发现很难使用的键,但是如果你擅长它,你可以像长胡子的向导一样编辑文本.