我想要一种混合模式,默认情况下我可以使用所有默认keymap emacs
键绑定,并且仍然能够更改为vi-command
模式。
我该如何设置?
答案1
我认为更好的方法是将vi-insert
绑定移动到,而不是将绑定移动到。原因是因为有切换到的绑定,并且很难模拟功能以使其切换到模式。emacs
emacs
vi-insert
vi-command
vi-insert
emacs
例如,A
命令 invi-command
默认为vi-append-eol
(附加在行尾并切换到vi-insert
)。
您无法A
切换到emacs
模式,因为它绑定到函数而不是宏。
例如,这行不通
"A": vi-append-eol emacs-editing-mode
"A": vi-append-eol "\ee"
你可以这样做:
"A": "$a\ee"
但现在这取决于"a"
,vi-append-mode
命令,它也需要反弹。"a"
那么就可以继续前进了"i"
。"i"
可以切换到emacs
.有一个完整的命令链需要转换为宏,这是一件很痛苦的事情。
因此,您最好将emacs
绑定移至vi-insert
.
因此,我们想要设置vi-insert
唯一的绑定,emacs
并且如果它们对于相同的按键序列具有不同的绑定,我们想要决定使用哪个绑定。如果它们具有完全相同的绑定,我们将忽略它们。
可以使用以下命令完成此操作
comm -3\
<(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort) \
<(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort) | cat
| cat
解释了存在的原因这里
丢弃-3
“完全相同的绑定”,因此您浏览此列表并在左列中查找绑定。对于左列上的每个绑定:
如果同一按键序列存在重复绑定,例如
"\C-d": delete-char
"\C-d": vi-eof-maybe
选择其中之一。如果您想要vi-insert
(右侧),您可以删除这两行,因为我们将添加这些绑定到vi-insert
已经具有vi-insert
绑定的位置。如果您想要该emacs
(左侧),请将其删除vi-insert
。
如果右列 ( ) 上存在唯一绑定vi-insert
,例如
"\e": vi-movement-mode
删除它,因为 `vi-insert 已经有它了。
其余的绑定将位于左列 ( emacs
)。不要管这些,因为我们会将它们添加到vi-insert
.
这是我选择添加到的.inputrc
绑定。emacs
vi-insert
我决定不使用"kj"
切换到vi-command
in@汤姆·黑尔的回答因为可以用它来完成"\ee"
将您从 带到 的任务emacs
,vi-insert
然后再完成另一个"\e"
将您从vi-insert
带到 的任务vi-command
。其实有除 blackjack 外包含 kj 的单词和带jk的单词(主要是地名)
我保留"\C-d": delete-char
并扔掉了"\C-d": vi-eof-maybe
。因为我可以只使用Enter
forvi-eof-maybe
并且我不想通过按意外退出 readline "\C-d"
。这意味着删除"\C-d": vi-eof-maybe
绑定,因为我们正在使用绑定覆盖 modevi-eof-maybe
中的绑定。vi-insert
delete-char
我保留"\C-n": menu-complete
而不是"\C-n": next-history
因为我可以使用向下箭头next-history
。这意味着删除两个绑定,因为vi-insert
已有menu-complete
绑定。
我保留"\C-p": menu-complete-backward
而不是"\C-p": previous-history
因为我可以按向上箭头previous-history
。这意味着删除两个绑定,因为vi-insert
已有menu-complete-backward
绑定。
我保留"\C-w": vi-unix-word-rubout
而不是"\C-w": unix-word-rubout
.我不知道有什么区别。我只是坚持其中vi-insert
一个。这意味着删除两个绑定,因为vi-insert
已有vi-unix-word-rubout
绑定。
我保留了"\e": vi-movement-mode
。这意味着删除此绑定,因为vi-insert
已有该vi-movement-mode
绑定。
set editing-mode vi
set keymap emacs
"\ee": vi-editing-mode
set keymap vi-command
"\ee": emacs-editing-mode
# key bindings to get out of vi-editing-mode
set keymap vi-insert
"\ee": emacs-editing-mode
# emacs keybindings in vi-insert mode
"\C-@": set-mark
"\C-]": character-search
"\C-_": undo
"\C-a": beginning-of-line
"\C-b": backward-char
"\C-d": delete-char
"\C-e": end-of-line
"\C-f": forward-char
"\C-g": abort
"\C-k": kill-line
"\C-l": clear-screen
"\C-o": operate-and-get-next
"\C-q": quoted-insert
"\C-x!": possible-command-completions
"\C-x$": possible-variable-completions
"\C-x(": start-kbd-macro
"\C-x)": end-kbd-macro
"\C-x*": glob-expand-word
"\C-x/": possible-filename-completions
"\C-x@": possible-hostname-completions
"\C-x\C-?": backward-kill-line
"\C-x\C-e": edit-and-execute-command
"\C-x\C-g": abort
"\C-x\C-r": re-read-init-file
"\C-x\C-u": undo
"\C-x\C-v": display-shell-version
"\C-x\C-x": exchange-point-and-mark
"\C-xe": call-last-kbd-macro
"\C-xg": glob-list-expansions
"\C-x~": possible-username-completions
"\e ": set-mark
"\e!": complete-command
"\e#": insert-comment
"\e$": complete-variable
"\e&": tilde-expand
"\e*": insert-completions
"\e-": digit-argument
"\e.": insert-last-argument
"\e.": yank-last-arg
"\e/": complete-filename
"\e0": digit-argument
"\e1": digit-argument
"\e2": digit-argument
"\e3": digit-argument
"\e4": digit-argument
"\e5": digit-argument
"\e6": digit-argument
"\e7": digit-argument
"\e8": digit-argument
"\e9": digit-argument
"\e<": beginning-of-history
"\e=": possible-completions
"\e>": end-of-history
"\e?": possible-completions
"\e@": complete-hostname
"\e\C-?": backward-kill-word
"\e\C-]": character-search-backward
"\e\C-e": shell-expand-line
"\e\C-g": abort
"\e\C-h": backward-kill-word
"\e\C-i": dynamic-complete-history
"\e\C-r": revert-line
"\e\C-y": yank-nth-arg
"\e\\": delete-horizontal-space
"\e\e": complete
"\e^": history-expand-line
"\e_": insert-last-argument
"\e_": yank-last-arg
"\eb": backward-word
"\ec": capitalize-word
"\ed": kill-word
"\ef": forward-word
"\eg": glob-complete-word
"\el": downcase-word
"\en": non-incremental-forward-search-history
"\ep": non-incremental-reverse-search-history
"\er": revert-line
"\et": transpose-words
"\eu": upcase-word
"\ey": yank-pop
"\e{": complete-into-braces
"\e~": complete-username
更新
我想我做得更好了一点。有一段时间,我重新打开了"jk"
切换到的命令,vi command
因为按下"\e"
切换到vi-command
有一个延迟,因为很多emacs
命令转移到了作为领导者vi-insert
使用。"\e"
这表明"jk"
moshing 已被注释掉。我目前使用"\ee"
循环模式。我没有解除从到 的"\e"
绑定,因为我认为没有必要。因此,它的效果是,如果您按入并等待,您将转到。vi-insert
vi-command
"\e"
vi-insert
vi-command
要从 到vi-command
,vi-insert
您只需按命令之一,例如"A"
或"i"
so ,允许在 3 种模式之间循环不会有什么坏处,因为您也可以在 2 种vi
模式之间循环。
set keymap emacs
"\ee": vi-editing-mode
set keymap vi-command
"\ee": emacs-editing-mode
# key bindings to get out of vi-editing-mode
set keymap vi-insert
# Choose one of these editor switching modes
#
# moosh jk to switch
#"\ee": emacs-editing-mode
#"\ejk": vi-movement-mode
#"\ekj": vi-movement-mode
#
# "\ee" to cycle
# can unmap "\e" to switch to vi-command but don't see a need
#"\e":
"\ee": vi-movement-mode
更新
在 中vi-insert
,"\C-w"
绑定到 `vi-unix-word-rubout,它在单词边界或其他地方停止。我不喜欢这个功能。
例如,尝试这个
$ cannot-delete'
# press left arrow to go back behind the single quote
# press \C-w in vi-insert to try to delete cannot-delete, it won't work
这个错误报告描述了问题,尽管我对提供的示例没有问题。
所以你可以绑定"\C-w"
到 emacsunix-word-rubout
来解决这个问题。
要重新绑定"\C-w"
,您可能需要取消绑定默认值。
# In .bashrc
stty werase undef
如果您想解除所有默认值的绑定:
# In .inputrc
set bind-tty-special-chars off
不确定这是否重要,但我使用的是 macOS,所以有我删除的其他默认绑定。
然后在你的.inputrc
:
"\C-w": unix-word-rubout
答案2
以下.inputrc
行允许Meta / Alt+在和模式E之间切换。emacs
vi-insert
j同时哞哞k将带你进入vi-command
模式。
注意:唯一带有“kj”的英文单词是“blackjack”,没有单词包含“jk”)
set show-mode-in-prompt on
set keymap emacs
"\ee": vi-editing-mode
"jk": "\eejk"
"kj": "\eejk"
set keymap vi-insert
"\ee": emacs-editing-mode
"jk": vi-movement-mode
"kj": vi-movement-mode
set keymap vi-command
"\ee": emacs-editing-mode
注意:在v4.3.11(1) 中,如果您在bash
to 下添加绑定以尝试直接切换到键盘映射,则提示不会更新(如果您有 ),因此需要此解决方法。keymap emacs
vi-movement-mode
vi-command
show-mode-in-prompt on
有趣的事实:
mode特有的绑定只有 4 个vi-insert
,可以轻松添加到emacs
mode 中:
"\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" # needs to be below "kj" mapping
"\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
旧答案
emacs
在我可以直接从to之前,我就是这样做的vi-command
。它涉及将所有默认emacs
命令导入到vi-insert
键盘映射中。
获取默认值emacs-standard
和vi-insert
映射:
INPUTRC=~/dev/null bash -c 'bind -pm emacs-standard' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort > emacs-standard
INPUTRC=~/dev/null bash -c 'bind -pm vi-insert' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort > vi-insert
仅获取来自以下位置的添加内容emacs-standard
:
comm -23 emacs-standard vi-insert > vi-insert-emacs-additions
然后,在您的 中,在以下行下~/.inputrc
添加以下内容:vi-insert-emacs-additions
(echo set editing-mode vi && echo set keymap vi-insert && cat vi-insert-emacs-additions) >> ~/.inputrc
为了您的方便,在 bash 4.3.11(1)-release 上,vi-insert-emacs-additions
内容为:
"\C-a": beginning-of-line "\C-b": backward-char "\C-]": character-search "\C-d": delete-char "\C-e": end-of-line "\C-f": forward-char "\C-g": abort "\C-k": kill-line "\C-l": clear-screen "\C-n": next-history "\C-o": operate-and-get-next "\C-p": previous-history "\C-q": quoted-insert "\C-@": set-mark "\C-_": undo "\C-x\C-?": backward-kill-line "\C-x\C-e": edit-and-execute-command "\C-x\C-g": abort "\C-x\C-r": re-read-init-file "\C-x\C-u": undo "\C-x\C-v": display-shell-version "\C-x\C-x": exchange-point-and-mark "\C-xe": call-last-kbd-macro "\C-x)": end-kbd-macro "\C-xg": glob-list-expansions "\C-x*": glob-expand-word "\C-x!": possible-command-completions "\C-x/": possible-filename-completions "\C-x@": possible-hostname-completions "\C-x~": possible-username-completions "\C-x$": possible-variable-completions "\C-x(": start-kbd-macro "\e0": digit-argument "\e1": digit-argument "\e2": digit-argument "\e3": digit-argument "\e4": digit-argument "\e5": digit-argument "\e6": digit-argument "\e7": digit-argument "\e8": digit-argument "\e9": digit-argument "\eb": backward-word "\e<": beginning-of-history "\e\C-?": backward-kill-word "\ec": capitalize-word "\e\C-]": character-search-backward "\e\C-e": shell-expand-line "\e\C-g": abort "\e\C-h": backward-kill-word "\e\C-i": dynamic-complete-history "\e!": complete-command "\e/": complete-filename "\e@": complete-hostname "\e{": complete-into-braces "\e~": complete-username "\e$": complete-variable "\e\C-r": revert-line "\e\C-y": yank-nth-arg "\e\\": delete-horizontal-space "\e-": digit-argument "\ed": kill-word "\e\e": complete "\e>": end-of-history "\ef": forward-word "\eg": glob-complete-word "\e^": history-expand-line "\e#": insert-comment "\e*": insert-completions "\e_": insert-last-argument "\e.": insert-last-argument "\el": downcase-word "\en": non-incremental-forward-search-history "\ep": non-incremental-reverse-search-history "\e=": possible-completions "\e?": possible-completions "\er": revert-line "\e ": set-mark "\e&": tilde-expand "\et": transpose-words "\eu": upcase-word "\e_": yank-last-arg "\e.": yank-last-arg "\ey": yank-pop
keymap emacs
注意:如果您在 to下添加绑定vi-movement-mode
以尝试直接切换到vi-command
模式,则提示不会更新(如果您有show-mode-in-prompt on
.
这就是为什么上述解决方案将emacs
绑定添加到vi-insert
.这会导致更长的时间.inputrc
,但对于完整的解决方案来说是必需的。