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
What does "set keymap vi" do?
提问by Vlad the Impala
采纳答案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 vi
does is state that any bindings listed after that point apply to that keymap (which is exactlythe same keymap as vi-command
and vi-move
).
什么keymap vi
是声明在该点之后列出的任何绑定都适用于该键映射(与和完全相同的键映射)。vi-command
vi-move
If you want to change the insertion keymap (eg to add a Ctrl-A
binding to go the beginning of the line while you're typing), you'll need to do this below a keymap vi-insert
line.
如果您想更改插入键映射(例如,Ctrl-A
在您键入时添加绑定到行首),您需要在keymap vi-insert
一行下方执行此操作。
If you want further info on the vi
mode 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-mode
and a keymap
.
可是等等!不过,可能需要一些背景信息:例如, anediting-mode
和 a之间的区别keymap
。
Particularly useful is the concept of a hybrid emacs
keymap for inserting text and while still easily getting to vi-command
for making changes.
特别有用的是emacs
用于插入文本的混合键盘映射的概念,同时仍然可以轻松vi-command
进行更改。
What is the difference between an editing-mode
and a keymap
?
anediting-mode
和 a 和有keymap
什么不一样?
There are onlytwo editing-mode
s: emacs
(the default) and vi
.
有只有2个editing-mode
S: emacs
(默认)和vi
。
The GNU Readline Library documentationsays:
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-mode
and keymap
: In editing-mode vi
the two (yes there's only two, read on) keymaps are swapped in and out to emulate the different modes of the vi
editor. ALLthe emacs
ones operate at the same time in editing-mode emacs
(explained later).
注意区别之间editing-mode
和keymap
:在editing-mode vi
两个(是有只有两个,请继续阅读)键盘映射和移出交换效仿的模式不同vi
的编辑器。所有这些emacs
同时运行editing-mode emacs
(稍后解释)。
So what does editing-mode
actually do? It just sets the active keymap upon shell startup to either emacs
or vi-insert
.
那么editing-mode
实际上有什么作用呢?它只是将 shell 启动时的活动键盘映射设置为emacs
or 或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-command
and vi-move
keymaps are also equivalent:
虽然没有记录,vi
/vi-command
和vi-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-insert
as 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 emacs
with any other keymap name in the example above.
您可以用emacs
上面示例中的任何其他键映射名称替换。
There are many lines saying self-insert
or do-lowercase-version
which aren't very useful, so to remove them:
有很多行说self-insert
ordo-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 emacs
keymaps?
各种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-insert
for their corresponding keymap
s, you can find out that:
如果您将第二个命令的输出放入名为emacs-standard
, emacs-meta
, emacs-ctlx
, vi-command
, 和vi-insert
它们对应keymap
的文件中,您可以发现:
There are NO commands mapped in emacs-meta
and emacs-ctlx
which don't also appear in emacs-standard
:
有没有命令映射emacs-meta
和emacs-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-standard
is a behaviourally functional superset of both emacs-ctlx
and emacs-meta
This means that:
所以,emacs
/emacs-standard
是两者的行为上的功能超集emacs-ctlx
和emacs-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: emacs
vs vi-insert
插入文本:emacs
vsvi-insert
There are 28 commands in emacs-standard
not in vi-insert
在emacs-standard
not in 中有 28 个命令vi-insert
+ravi@boxy:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
+ravi@boxy:~/lib/readline$
emacs
/emacs-standard
is basically a superset of vi-insert
. So for typing text, it's best to use the emacs-standard
keymap over vi-insert
as long as you can easily switch between emacs
and vi-command
.
emacs
/emacs-standard
基本上是vi-insert
. 因此,对于输入文本,最好使用emacs-standard
键盘映射vi-insert
,只要您可以轻松地在emacs
和之间切换vi-command
。
The only additional bindings in vi-insert
not in emacs-standard
are:
vi-insert
not 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 emacs
bindings:
这四个中的前三个与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-command
and vi-move
are one and the samekeymap:
正如我们在上面看到的vi
,vi-command
和vi-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 keymap
s in use are vi
/vi-command
/vi-move
and 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-move
和vi-insert
(起始键映射)。一次只有这两张地图中的一张处于活动状态。
editing-mode vi
does 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-insert
keymap maps most keys to self-insert
so 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-insert
keymap allows itself to be swapped to the text-manipulating keymap called vi-command
/vi
/vi-move
by using vi-movement-mode
command, bound to the ESCkey by default in the vi-insert
keymap.
所述vi-insert
键映射允许自身被交换到称为文本操纵键映射vi-command
/ vi
/vi-move
通过使用vi-movement-mode
命令,结合到ESC默认在键vi-insert
的键映射。
Actually, even the emacs
keymap can set the vi
-like text manipulation keymap active by using the vi-movement-mode
command, as in the hybrid solution mentioned above.
实际上,即使是emacs
键盘映射也可以vi
通过使用该vi-movement-mode
命令将类似文本操作的键盘映射设置为活动状态,如上面提到的混合解决方案。
Or in easier language...
或者用更简单的语言...
By default, press ESCto change to the vi-command
keymap when the vi-insert
keymap is active.
默认情况下,当键盘映射处于活动状态时,按下ESC可更改为vi-command
键盘vi-insert
映射。
The vi-command
keymap uses standard, single keypresses like a, band cto move and interact with text, just like the vi
editor'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-insert
keymap (example: press ifor "Insert").
该vi-command
键盘映射使用标准的,单按键像a,b并c用文字移动和互动,就像vi
编辑器的默认或命令模式。一般没有Ctrl+key组合。在这种模式下不能插入文本;字母键映射到编辑/移动命令。要输入文本,请切换到vi-insert
键盘映射(例如:按i“插入”)。
Entering text is done using the the vi-insert
keymap, which is active when the shell starts if you have editing-mode vi
in your .inputrc
file. Swap to the vi-insert
keymap 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 vi
editor, you'll probably find vi-command
keys 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 inputrc
you can specify different keybinds for the different modes, so, for example, in command
mode you could yank the last argument from the previous command with Altp, but this keybind would have no effect in insert
mode (in this simple setup anyway):
因此,在您inputrc
可以为不同的模式指定不同的键绑定,因此,例如,在command
mode 中,您可以使用 猛拉上一个命令中的最后一个参数Altp,但是此键绑定在insert
mode 中无效(无论如何在这个简单的设置中):
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