Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question

3 Answers 3

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.

share|improve this answer
    
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 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).

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.