bash “设置键盘映射 vi”有什么作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10002356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:54:49  来源:igfitidea点击:

What does "set keymap vi" do?

bashshell

提问by Vlad the Impala

I wanted vim-like navigation for my terminal, so I added:

我想为我的终端提供类似 vim 的导航,所以我添加了:

set editing-mode vi
set keymap vi

To my .inputrcfile based on this. editing-mode viadds vi navigation. What does keymap vido, and why do I need it?

.inputrc基于到我的文件。editing-mode vi添加 vi 导航。有什么作用keymap vi,为什么我需要它?

采纳答案by Tom Hale

TL;DR

TL; 博士

If you don't want to change/add bindings in the default keymaps, you don't need the line keymap vi.

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

What keymap vidoes is state that any bindings listed after that point apply to that keymap (which is exactlythe same keymap as vi-commandand vi-move).

什么keymap vi是声明在该点之后列出的任何绑定都适用于该键映射(与和完全相同的键映射)。vi-commandvi-move

If you want to change the insertion keymap (eg to add a Ctrl-Abinding to go the beginning of the line while you're typing), you'll need to do this below a keymap vi-insertline.

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

If you want further info on the vimode and maps, skip to the heading editing-mode vi(the last one).

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

But wait! There's a fair bit of background info that may be needed though: eg, the difference between an editing-modeand a keymap.

可是等等!不过,可能需要一些背景信息:例如, anediting-mode和 a之间的区别keymap

Particularly useful is the concept of a hybrid emacskeymap for inserting text and while still easily getting to vi-commandfor making changes.

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

What is the difference between an editing-modeand a keymap?

anediting-mode和 a 和有keymap什么不一样?

There are onlytwo editing-modes: emacs(the default) and vi.

只有2个editing-modeS: emacs(默认)和vi

The GNU Readline Library documentationsays:

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-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'.

Note the difference between editing-modeand keymap: In editing-mode vithe two (yes there's only two, read on) keymaps are swapped in and out to emulate the different modes of the vieditor. ALLthe emacsones operate at the same time in editing-mode emacs(explained later).

注意区别之间editing-modekeymap:在editing-mode vi两个(是有只有两个,请继续阅读)键盘映射和移出交换效仿的模式不同vi的编辑器。所有这些emacs同时运行editing-mode emacs(稍后解释)。

So what does editing-modeactually do? It just sets the active keymap upon shell startup to either emacsor vi-insert.

那么editing-mode实际上有什么作用呢?它只是将 shell 启动时的活动键盘映射设置为emacsor 或vi-insert

What are the unique keymaps?

什么是独特的键盘映射?

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.
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.

While not documented, vi/vi-commandand vi-movekeymaps are also equivalent:

虽然没有记录,vi/vi-commandvi-move键盘映射也是等效的:

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

This leaves us with: emacs, emacs-meta, emacs-ctlx, vi, and vi-insertas unique keymaps to explain. Differentiating the keymaps is probably best done by inspecting them...

这给我们留下了:emacs, emacs-meta, emacs-ctlx, vi, 和vi-insert作为唯一键映射来解释。区分键映射可能最好通过检查它们来完成...

What are the keymaps default bindings?

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

To view the default keybindings for (example) emacs (the default), use:

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

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

You can replace emacswith any other keymap name in the example above.

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

There are many lines saying self-insertor do-lowercase-versionwhich aren't very useful, so to remove them:

有很多行说self-insertordo-lowercase-version不是很有用,所以要删除它们:

INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort

What is the difference between the various emacskeymaps?

各种emacs键盘映射之间有什么区别?

TL;DR: They are different views on a single set of mappings applied to editing-mode emacs.

TL;DR:它们是对应用于editing-mode emacs.

If you the output of the second command into the files called emacs-standard, emacs-meta, emacs-ctlx, vi-command, and vi-insertfor their corresponding keymaps, you can find out that:

如果您将第二个命令的输出放入名为emacs-standard, emacs-meta, emacs-ctlx, vi-command, 和vi-insert它们对应keymap的文件中,您可以发现:

There are NO commands mapped in emacs-metaand emacs-ctlxwhich don't also appear in emacs-standard:

有没有命令映射emacs-metaemacs-ctlx不同时出现在emacs-standard

$ comm -13 <(sed -r 's/.*: (\S+)//' emacs-standard|sort) <(sed -r 's/.*: (\S+)//' emacs-ctlx|sort)
$ comm -13 <(sed -r 's/.*: (\S+)//' emacs-standard|sort) <(sed -r 's/.*: (\S+)//' emacs-meta|sort)
$

So emacs/emacs-standardis a behaviourally functional superset of both emacs-ctlxand emacs-metaThis means that:

所以,emacs/emacs-standard是两者的行为上的功能超集emacs-ctlxemacs-meta这意味着:

keymap emacs
"\eg": glob-expand-word
"\C-x\C-r": re-read-init-file

Is functionally equivalent to:

在功能上等同于:

keymap emacs-meta
"g": glob-expand-word

keymap emacs-ctlx
"\C-r": re-read-init-file

You might argue that the second form is easier to read.

您可能会争辩说第二种形式更容易阅读。

Inserting text: emacsvs vi-insert

插入文本:emacsvsvi-insert

There are 28 commands in emacs-standardnot in vi-insert

emacs-standardnot in 中有 28 个命令vi-insert

+ravi@boxy:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
+ravi@boxy:~/lib/readline$

emacs/emacs-standardis basically a superset of vi-insert. So for typing text, it's best to use the emacs-standardkeymap over vi-insertas long as you can easily switch between emacsand vi-command.

emacs/emacs-standard基本上是vi-insert. 因此,对于输入文本,最好使用emacs-standard键盘映射vi-insert,只要您可以轻松地在emacs和之间切换vi-command

The only additional bindings in vi-insertnot in emacs-standardare:

vi-insertnot inemacs-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

The first 3 of these four conflict with emacsbindings:

这四个中的前三个与emacs绑定冲突:

"\C-d": delete-char
"\C-n": next-history
"\C-p": previous-history

which I resolved as follows:

我解决如下:

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

editing-mode vi

As we saw above, vi, vi-commandand vi-moveare one and the samekeymap:

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

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

Note that's a total of just twodistinct maps which are associated by default with editing-mode vi.

请注意,总共只有两个不同的地图,它们默认与editing-mode vi.

When in editing-mode vi, the keymaps in use are vi/vi-command/vi-moveand vi-insert(the starting keymap). Only one of these two maps is active at a time.

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

editing-mode vidoes nothing more than set a default keymap when the shell starts, labelled vi-insert. Again, tthere is only one keymap active at a time. This vi-insertkeymap maps most keys to self-insertso when you press the plastic button on your keyboard, the symbol printed on it appears on your screen.

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

The vi-insertkeymap allows itself to be swapped to the text-manipulating keymap called vi-command/vi/vi-moveby using vi-movement-modecommand, bound to the ESCkey by default in the vi-insertkeymap.

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

Actually, even the emacskeymap can set the vi-like text manipulation keymap active by using the vi-movement-modecommand, as in the hybrid solution mentioned above.

实际上,即使是emacs键盘映射也可以vi通过使用该vi-movement-mode命令将类似文本操作的键盘映射设置为活动状态,如上面提到的混合解决方案。

Or in easier language...

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

By default, press ESCto change to the vi-commandkeymap when the vi-insertkeymap is active.

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

The vi-commandkeymap uses standard, single keypresses like a, band cto move and interact with text, just like the vieditor's default or command mode. There are generally no Ctrl+keycombinations. You can't insert text in this mode; the letter keys are mapped to editing/moving commands. For typing text, you switch to the vi-insertkeymap (example: press ifor "Insert").

vi-command键盘映射使用标准的,单按键像abc用文字移动和互动,就像vi编辑器的默认或命令模式。一般没有Ctrl+key组合。在这种模式下不能插入文本;字母键映射到编辑/移动命令。要输入文本,请切换到vi-insert键盘映射(例如:按i“插入”)。

Entering text is done using the the vi-insertkeymap, which is active when the shell starts if you have editing-mode viin your .inputrcfile. Swap to the vi-insertkeymap by pressing ifor "insert" while in vi-command(or in numerous other ways for those initiated into vi).

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

Unless you know the vieditor, you'll probably find vi-commandkeys very hard to use at first, but if you get good at it, you can edit text like a long-bearded wizard.

除非您了解vi编辑器,否则一开始您可能会发现vi-command按键很难使用,但如果您熟练掌握,您就可以像长胡子的巫师一样编辑文本。

回答by jasonwryan

From man readline(my emphasis):

来自man readline(我的重点):

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
合法的键盘映射名称集是 emacs、emacs-standard、emacs-meta、emacs-ctlx、vi、vi-move、vi-command 和 vi-insert。 vi 等价于 vi 命令

Thus, in your inputrcyou can specify different keybinds for the different modes, so, for example, in commandmode you could yank the last argument from the previous command with Altp, but this keybind would have no effect in insertmode (in this simple setup anyway):

因此,在您inputrc可以为不同的模式指定不同的键绑定,因此,例如,在commandmode 中,您可以使用 猛拉上一个命令中的最后一个参数Altp,但是此键绑定在insertmode 中无效(无论如何在这个简单的设置中):

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