Como alterno para o modo de edição vi no readline?


16

Quero mudar para o modo de edição vi em um ambiente de linha de leitura. Mas não quero usar 'set -o vi'. Quero mudar temporariamente usando um atalho de teclado. A página de manual diz que eu posso fazer isso M-C-j. Mas isso não funciona para mim.

Estou usando o Ubuntu e um xterm. Também não funciona no terminal gnome.

Respostas:


12

Confirmo que o mapeamento do teclado Meta+ Control+ jestá correto no seu sistema. Você pode usar este comando para listar todas as teclas de atalho para os vários modos do Bash. No meu sistema também não havia uma combinação de teclas.

$ 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

Você pode fazer o seguinte para que, ao digitar Esc+ e, alterne entre os 2 modos.

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

O bindcomando agora mostra isso:

no modo vi

$ 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

no modo emacs

$ 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".

Agora você pode usar Esc+ epara alternar entre os 2 modos diferentes.


Observe que você precisa ser rápido ao digitar ESC E. Se você pausar, passará do modo vi-insert para o comando vi, ou apenas cancelará o comando vi atual.
Spelufo

6

O Bash desativa explicitamente esse e alguns outros atalhos do Readline. Veja a initialize_readline()função no código-fonte do bash ( 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

Não consigo substituir esse comportamento usando o arquivo de configuração Readline (.inputrc).


6

Aqui está o que eu acabei usando para o meu ~/.inputrc, com base na resposta do slm.

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

Tentei a $if mode=sintaxe, mas acho que isso é resolvido estaticamente (uma vez, ao ler o arquivo), para que não funcione como eu esperava. Portanto, precisamos mudar para cada mapa de teclas e modificar suas associações de teclas, mesmo se definidas anteriormente em outros mapas de teclas. No final, eu digo com qual modo eu quero começar.


2

Tentei usar mapeamentos no estilo emacs no modo vi. Acabei com:

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

É útil ler a página de manual readlinee a READLINEseção na bashpágina de manual.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.