Is there a way to switch Bash or zsh from Emacs mode to vi mode with a keystroke?

帅比萌擦擦* 提交于 2019-12-02 21:07:58

You can create a toggle since the key bindings are separate between vi mode and emacs mode.

$ set -o emacs
$ bind '"\ee": vi-editing-mode'
$ set -o vi
$ bind '"\ee": emacs-editing-mode'

Now Alt-e (or Esc e) will toggle between modes.

Add this somewhere in your definition for PS1 so you have an indicator in your prompt of which mode you're in. It won't show the change immediately when you toggle modes, but it will update when a new prompt is issued.

$(set -o | grep emacs.*on >/dev/null 2>&1 && echo E || echo V)

Aha! I looked at the readline source, and found out that you can do this:

 "\M-v": vi-editing-mode
 "\M-e": emacs-editing-mode

There doesn't appear to be a toggle, but that's probably good enough!

For posterity's sake, here's my original answer, which could be useful for people trying to do things for which there is no readline function.

Here's a way you could set it up, clearing the current command line in the process. Not what you want, I know, but maybe it'll help someone else who finds this question. In ~/.inputrc:

"\M-v": "\C-k\C-uset -o vi\C-j" # alt (meta)-v: set vi mode
"\M-e": "\C-k\C-uset -o vi\C-j" # alt (meta)-e: set emacs mode

or to toggle...this should work:

"\M-t": "\C-k\C-u[[ \"$SHELLOPTS\" =~ '\\bemacs\\b' ]] && set -o vi || set -o emacs\C-j"

These are essentially aliases, taken one step farther to map to keys in readline so that you don't have to type an alias name and hit enter.

The following .inputrc lines allow Meta / Alt+E to switch between emacs and vi-insert modes.

Mooshing both j and k simultaneously will take you to vi-command mode.

Note: The only English word with "kj" is "blackjack", no words contain "jk")

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

Note: If you add a binding under keymap emacs to vi-movement-mode to try to switch straight to vi-command mode, the prompt doesn't update if you have show-mode-in-prompt on, hence the above work-around is needed.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!