Я использую Bash в "режиме vi". Какая последовательность горячих клавиш для редактирования текущей командной строки с использованием внешнего редактора?

1218
Alby

В "Emacs mode" Bash ( set -o emacs) я могу редактировать текущую командную строку в моем любимом внешнем $ EDITOR. Все, что мне нужно сделать, это нажать Ctrl+, Xзатем Ctrl+E .

Но, поскольку я переключился на «режим vi» Баша ( set -o vi), эта последовательность клавиш ничего не делает. В режиме «vi», как я могу запустить внешний редактор, чтобы составлять более длинные команды?

5

3 ответа на вопрос

8
Marko Kohtala

Привязка режима emacs выполняет команду edit-and-execute-command. Чтобы увидеть, какая привязка выполняет его в режиме vi, вы можете дать команду:

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

Проще всего было бы добавить для него привязку

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

Чтобы сделать его постоянным, вы можете добавить его в ~ / .inputrc как

set keymap vi-insert "\C-x\C-e": edit-and-execute-command 
Большое спасибо! это ответ, который я ищу. Можете ли вы показать мне, как запускать редактор, используя сочетанные сочетания клавиш Ctrl + X, а не Ctrl + X? Alby 10 лет назад 0
Хорошо. Я отредактировал ответ. Извините за то, что не сделал это в первую очередь. Marko Kohtala 10 лет назад 1
1
devnull

Если вы хотите указать редактор по умолчанию как vi, то вам нужно установить переменную окружения EDITOR:

export EDITOR=vi 

Теперь говорят, Ctrl-XCtrl-Eчто запустят vi.

1
unforgettableid

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.