Comment passer en mode d'édition vi en ligne de lecture?

16

Je souhaite passer en mode d'édition vi dans un environnement de ligne de lecture. Mais je ne veux pas utiliser 'set -o vi'. Je souhaite basculer temporairement à l'aide d'un raccourci clavier. La page de manuel indique que je peux le faire avec M-C-j. Mais ça ne marche pas pour moi.

J'utilise Ubuntu et un xterm. Ne fonctionne pas non plus sous gnome-terminal.

Eric Johnson
la source

Réponses:

12

Je confirmerais que le mappage du clavier Meta+ Control+ jest en fait correct sur votre système. Vous pouvez utiliser cette commande pour répertorier tous les raccourcis clavier pour les différents modes de Bash. Sur mon système, il n'y avait pas non plus de raccourci clavier.

$ 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

Vous pouvez faire ce qui suit pour que lorsque vous tapez Esc+, eil bascule entre les 2 modes.

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

La bindcommande affiche maintenant ceci:

en mode 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

en mode 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".

Vous pouvez maintenant utiliser Esc+ epour basculer entre les 2 modes différents.

slm
la source
Notez que vous devez être rapide lors de la frappe ESC E. Si vous faites une pause, vous passerez du mode vi-insert au mode vi-command, ou annulerez simplement la commande vi actuelle.
spelufo
6

Bash désactive explicitement cela et quelques autres raccourcis Readline. Voir la initialize_readline()fonction dans le code source 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

Je ne semble pas pouvoir remplacer ce comportement en utilisant le fichier de configuration Readline (.inputrc).

Eric Johnson
la source
6

Voici ce que j'ai fini par utiliser pour moi ~/.inputrc, basé sur la réponse de 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

J'ai essayé la $if mode=syntaxe, mais je pense que cela est résolu statiquement (une fois, lors de la lecture du fichier), donc cela ne fonctionne pas comme je m'y attendais. Nous devons donc basculer sur chaque image clé et modifier ses raccourcis clavier, même s'ils ont été précédemment définis sur d'autres images clés. À la fin, je dis avec quel mode je veux commencer.

spelufo
la source
2

J'ai essayé d'utiliser des mappages de style emacs en mode vi. Je me suis retrouvé avec:

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

Il est utile de lire la page de manuel readlineet la READLINEsection de la bashpage de manuel.

Caizheng Peng
la source