# How do I switch to vi editing mode in readline?

I want to switch to vi editing mode in a readline environment. But I don't want to use 'set -o vi'. I want to temporarily switch using a keyboard shortcut. The man page says I can do this with M-C-j. But that doesn't work for me.

I'm using Ubuntu and an xterm. Doesn't work under gnome-terminal either.

-

I'd confirm that the keyboard mapping Meta+Control+j is in fact correct on your system. You can use this command to list all the keybinds for the various modes of Bash. On my system there wasn't a keybinding either.

$bind -P| grep edit edit-and-execute-command can be found on "\C-x\C-e". emacs-editing-mode is not bound to any keys vi-editing-mode is not bound to any keys  You can do the following so that when you type Esc+e it will toggle between the 2 modes. $ set -o emacs
$bind '"\ee": vi-editing-mode'$ set -o vi
$bind '"\ee": emacs-editing-mode'  The bind command now shows this: in vi mode $ bind -P |grep edit
edit-and-execute-command is not bound to any keys
emacs-editing-mode can be found on "\ee".
vi-editing-mode is not bound to any keys


in emacs mode

$bind -P |grep edit edit-and-execute-command can be found on "\C-x\C-e". emacs-editing-mode is not bound to any keys vi-editing-mode can be found on "\ee".  Now you can use Esc+e to toggle between the 2 different modes. - Note that you have to be quick when typing ESC E. If you pause you will go from vi-insert to vi-command mode, or just cancell the current vi command. – spelufo Feb 20 '15 at 3:05 Bash explicitly disables this and a few other Readline shortcuts. See the initialize_readline() function in the bash source code (http://www.catonmat.net/download/bashline.c):  /* In Bash, the user can switch editing modes with "set -o [vi emacs]", so it is not necessary to allow C-M-j for context switching. Turn off this occasionally confusing behaviour. */ rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap); rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap); #if defined (VI_MODE) rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap); #endif  I don't seem to be able to override this behavior using the Readline configuration file (.inputrc). - Here's what I ended up using for my ~/.inputrc, based on slm's answer. set show-mode-in-prompt on set keymap emacs "\ea": vi-editing-mode set keymap vi-command "k": history-search-backward "j": history-search-forward "z": emacs-editing-mode "\ea": emacs-editing-mode set keymap vi-insert "\ea": emacs-editing-mode "\C-l": clear-screen "\C-e": end-of-line "\C-k": kill-line set editing-mode vi  I tried the $if mode= syntax, but I think that is resolved statically (one time, when reading the file), so it doesn't work as I expected. So we need to switch to each keymap and modify its key bindings, even if previously set on another keymaps. At the end I say which mode I want to start with.

-

I tried to have emacs-styled mappings being used in vi mode. I ended up with:

set keymap vi-command
"k": history-search-backward
"j": history-search-forward

set keymap vi-insert
"\C-A": beginning-of-line
"\C-B": backward-char
"\C-D": delete-char
"\C-E": end-of-line
"\C-F": forward-char
"\C-K": kill-line
"\C-L": clear-screen
"\C-N": next-history
"\C-P": previous-history
"\C-O": operate-and-get-next

# Enable Readline not waiting for additional input when a key is pressed.
# Needed for the mappings below.
set keyseq-timeout 0

# yank-last-arg does not work exactly as in emacs mode
"\e.": yank-last-arg
"\e\177": backward-kill-word
"\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
"\ec": capitalize-word
"\ed": kill-word
"\ef": forward-word
"\el": downcase-word
"\en": non-incremental-forward-search-history
"\ep": non-incremental-reverse-search-history
"\et": transpose-words
"\eu": upcase-word
"\ey": yank-pop

# some other useful mappings

"\e/": complete-filename
"\ek": kill-whole-line
"\eo": "\C-v\C-j"
# quickly switch to "normal" mode
"\C-[": vi-movement-mode
# perserve the currently editing line so that we can
# do something else before restoring it.
"\eg": insert-comment
"\er": "\C-R#\C-A\C-D\C-E"

set editing-mode vi


It is helpful to read the man page for readline and the READLINE section on the bash man page.

-