Como mudo para o modo de edição vi na readline?

15

Eu quero mudar para o modo de edição vi em um ambiente readline. Mas eu não quero usar 'set -o vi'. Eu quero mudar temporariamente usando um atalho de teclado. A man page diz que eu posso fazer isso com M-C-j . Mas isso não funciona para mim.

Estou usando o Ubuntu e um xterm. Não funciona sob o terminal gnome também.

    
por Eric Johnson 04.02.2014 / 02:38

4 respostas

4

O Bash explicitamente desativa este e alguns outros atalhos do Readline. Veja a função initialize_readline() no código fonte do bash ( link ):

   /* 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

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

    
por 06.02.2014 / 11:49
11

Eu confirmo que o mapeamento do teclado Meta + Controle + j está correto no seu sistema. Você pode usar este comando para listar todas as combinações de teclas para os vários modos de Bash. No meu sistema também não havia um atalho de teclado.

$ 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, quando você digitar Esc + e , alterne entre os dois modos.

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

O comando bind 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 + e para alternar entre os dois modos diferentes.

por 04.02.2014 / 03:24
6

Veja o que 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

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

    
por 20.02.2015 / 04:13
2

Eu tentei ter mapeamentos no estilo emacs sendo usados 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
"\e7": 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 do manual para readline e a seção READLINE na página bash man.

    
por 05.10.2015 / 16:19

Tags