15

In Bash's "Emacs mode" (set -o emacs), I can edit the current command line in my favorite external $EDITOR. All I have to do is press Ctrl+X then Ctrl+E.

But, because I have switched to Bash's "vi mode" (set -o vi), this key sequence doesn't do anything. In "vi mode", how can I launch an external editor in order to compose longer commands?

4 Answers 4

15

The emacs mode binding executes command edit-and-execute-command. To see which binding executes it in vi mode you can give command:

$ bind -m vi -q edit-and-execute-command
edit-and-execute-command is not bound to any keys.

Easiest would be to add a binding for it

$ bind -m vi-insert '"\C-x\C-e": edit-and-execute-command'

To make it permanent, you can add it to ~/.inputrc as

set keymap vi-insert
"\C-x\C-e": edit-and-execute-command
4
  • Thank you very much! this is the answer I am looking for. Can you show me how to trigger the editor using ctrl+x,e combined rather than just ctrl+ x?
    – Alby
    Commented Apr 2, 2014 at 17:29
  • 1
    Ok. I edited the answer. Sorry for not making it complete in the first place. Commented Apr 3, 2014 at 19:26
  • How do I refresh my .inputrc file to test that this works? Commented Jan 21, 2022 at 18:33
  • You start a new shell. bash or exec bash if you want to replace your current shell. Commented Jan 23, 2022 at 14:51
8

The answer

Press ESC to go into vi-command mode, then press v. Bash will start your your chosen $EDITOR. If you haven't chosen one, Bash will start vi (the visual editor).

Explanation

Why does Bash's ESCv start vi?

Because Bash's bashline.c includes the function call:

rl_bind_key_if_unbound_in_map ('v', vi_edit_and_execute_command, vi_movement_keymap);

What is vi_edit_and_execute_command? It's a Bash C function, defined elsewhere in bashline.c.

One aside. I have experimented a bit, and the following is what I now suspect is true. Binding Bash C functions is weird. You can do it from within Bash's source code, but it seems impossible to do so by using the bind builtin at the Bash prompt. And, once you've done it, the bind builtin doesn't seem to even recognize that it's been done.

I thank Glenn Jackman for pointing out that ESCv is the answer, and dualbus and Riviera of Freenode #bash for helping me to figure out the explanation above.

3

If you want to specify the default editor as vi, then you need to set the environment variable EDITOR:

export EDITOR=vi

Now saying Ctrl-XCtrl-E would launch vi.

2

How to disable edit-and-execute-command for the v key in vi\vi-command\vi-movement mode:

You cannot rebind it to nop, since it will automatically be rebound (see post by unforgettableid). Instead, you can bind it to set-mark if you don't use that. .inputrc:

set keymap vi-command
v: set-mark
# If you want to bind it to something else, e.g. Ctrl-v:
# "\C-v": edit-and-execute-command
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .