Auto-complétion de Bash dans le mode shell d’Emacs

Dans le terminal GNOME, Bash effectue une auto-complétion intelligente. Par exemple

apt-get in 

devient

 apt-get install 

Dans le mode shell d’Emacs, cette complétion automatique ne fonctionne pas, même après avoir explicitement source /etc/bash_completion . L’exemple ci-dessus se colle comme in ou se complète automatiquement avec un nom de fichier dans le répertoire actuel plutôt qu’une option de commande apt-get valide. Vraisemblablement, c’est parce qu’Emacs intercepte la touche Tab. Comment activer l’auto-complétion intelligente en shell-mode ?

Je sais que cette question a trois ans, mais je me suis aussi intéressée à la résoudre. Une recherche sur le Web m’a dirigé vers un morceau d’élisp qui oblige Emacs à utiliser bash en mode shell. Cela fonctionne pour moi, en tout cas.

Consultez-le à l’ adresse https://github.com/szermatt/emacs-bash-completion .

Dans le shell emacs, ce sont en fait les emacs qui effectuent l’auto-complétion, pas bash. Si le shell et les emacs sont désynchronisés (par exemple en utilisant pushd, popd ou une fonction utilisateur bash qui modifie le répertoire actuel du shell), la complétion automatique ne fonctionne plus.

Pour résoudre ce problème, tapez simplement “dirs” dans le shell et les choses sont synchronisées.

J’ai aussi ce qui suit dans mes .emacs:

 (global-set-key "\M-\r" 'shell-resync-dirs) 

Ensuite, appuyez sur Esc-return pour resynchroniser l’auto-complétion.

Je ne connais pas la réponse à cela. Mais la raison pour laquelle il ne fonctionne pas comme prévu est sans doute parce que la complétion dans les shells emacs est gérée par emacs en interne (par la fonction comint-dynamic-complete), et que ces fonctions

J’ai peur que ce ne soit pas une chose facile à réparer.

Edit: la suggestion de njsf d’utiliser le terme-mode est probablement aussi bonne que possible. Commencez avec

  Terme Mx 

Il est inclus dans la dissortingbution emacs standard (et au moins dans emacs21-common ou emacs22-common sur Ubuntu et Debian).

Comme l’a dit Matli, ce n’est pas une tâche facile, car bash est lancé avec –noediting et TAB est lié à comint-dynamic-complete.

On pourrait éventuellement relier TAB à self-insert-command dans shell-comand-hook avec local-set-key et faire en sorte que le mode shell ne commence pas par –noediting par Mx custom-variable RET basc-args explicite, mais je suppose que il ne va pas bien avec tout autre assembly.

Vous voudrez peut-être essayer le terme-mode, mais il a un autre ensemble de problèmes, car certains des raccourcis clavier standard sont dépassés par le mode terme.

EDIT: Par d’autres keybidings réguliers dépassés par le terme-mode, je veux dire tout sauf Cc qui devient l’évasion pour pouvoir changer de tampon. Donc, au lieu de Cx k, vous devez tuer le tampon Cc Cx k. Ou pour passer à un autre tampon ‘Cc Cx o’ ou ‘Cc Cx 2’

S’il vous plaît, considérez un autre Mx term mode Mx term , comme je l’ai fait quand j’ai rencontré un problème en 2011. J’ai essayé de rassembler tous les efforts sur Inet à ce moment pour faire fonctionner le shell avec Bash, y compris cette question. Mais depuis que j’ai découvert une alternative face au term-mode je ne veux même pas essayer eshell .

C’est un émulateur de terminal complet, de sorte que vous pouvez exécuter un programme interactif à l’intérieur, comme le commandant de minuit. Ou passez à l’achèvement de zsh pour ne pas perdre de temps sur la configuration d’Emacs.

Vous obtenez la complétion TAB en bash gratuitement. Mais plus important, vous obtenez une puissance de Readline complète, comme la recherche de commandes incrémentielle ou préfixée . Pour rendre cette configuration plus pratique, vérifiez mes fichiers .inputrc , .bashrc , .emacs .

Partie essentielle de .inputrc :

 # I like this! set editing-mode emacs # Don't ssortingp characters to 7 bits when reading. set input-meta on # Allow iso-latin1 characters to be inserted rather than converted to # prefix-meta sequences. set convert-meta off # Display characters with the eighth bit set directly rather than as # meta-prefixed characters. set output-meta on # Ignore hidden files. set match-hidden-files off # Ignore case (on/off). set completion-ignore-case on set completion-query-items 100 # First tab suggests ambiguous variants. set show-all-if-ambiguous on # Replace common prefix with ... set completion-prefix-display-length 1 set skip-completed-text off # If set to 'on', completed directory names have a slash appended. The default is 'on'. set mark-directories on set mark-symlinked-directories on # If set to 'on', a character denoting a file's type is appended to the # filename when listing possible completions. The default is 'off'. set visible-stats on set horizontal-scroll-mode off $if Bash "\Cx\Ce": edit-and-execute-command $endif # Define my favorite Emacs key bindings. "\C-@": set-mark "\Cw": kill-region "\Mw": copy-region-as-kill # Ctrl+Left/Right to move by whole words. "\e[1;5C": forward-word "\e[1;5D": backward-word # Same with Shift pressed. "\e[1;6C": forward-word "\e[1;6D": backward-word # Ctrl+Backspace/Delete to delete whole words. "\e[3;5~": kill-word "\C-_": backward-kill-word # UP/DOWN filter history by typed ssortingng as prefix. "\e[A": history-search-backward "\Cp": history-search-backward "\eOA": history-search-backward "\e[B": history-search-forward "\Cn": history-search-forward "\eOB": history-search-forward # Bind 'Shift+TAB' to complete as in Python TAB was need for another purpose. "\e[Z": complete # Cycling possible completion forward and backward in place. "\e[1;3C": menu-complete # M-Right "\e[1;3D": menu-complete-backward # M-Left "\e[1;5I": menu-complete # C-TAB 

.bashrc (YEA! Il y a dabbrev dans Bash depuis n’importe quel mot de ~/.bash_history ):

 set -o emacs if [[ $- == *i* ]]; then bind '"\e/": dabbrev-expand' bind '"\ee": edit-and-execute-command' fi 

.emacs pour faciliter la navigation dans le tampon de termes:

 (setq term-buffer-maximum-size (lsh 1 14)) (eval-after-load 'term '(progn (defun my-term-send-delete-word-forward () (interactive) (term-send-raw-ssortingng "\ed")) (defun my-term-send-delete-word-backward () (interactive) (term-send-raw-ssortingng "\e\Ch")) (define-key term-raw-map [C-delete] 'my-term-send-delete-word-forward) (define-key term-raw-map [C-backspace] 'my-term-send-delete-word-backward) (defun my-term-send-forward-word () (interactive) (term-send-raw-ssortingng "\ef")) (defun my-term-send-backward-word () (interactive) (term-send-raw-ssortingng "\eb")) (define-key term-raw-map [C-left] 'my-term-send-backward-word) (define-key term-raw-map [C-right] 'my-term-send-forward-word) (defun my-term-send-m-right () (interactive) (term-send-raw-ssortingng "\e[1;3C")) (defun my-term-send-m-left () (interactive) (term-send-raw-ssortingng "\e[1;3D")) (define-key term-raw-map [M-right] 'my-term-send-m-right) (define-key term-raw-map [M-left] 'my-term-send-m-left) )) (defun my-term-mode-hook () (goto-address-mode 1)) (add-hook 'term-mode-hook #'my-term-mode-hook) 

Comme toutes les commandes habituelles comme Cx o ne fonctionnent pas en mode d’émulation de terminal, j’ai étendu keymap avec:

 (unless (ignore-errors (require 'ido) (ido-mode 1) (global-set-key [?\sd] #'ido-dired) (global-set-key [?\sf] #'ido-find-file) t) (global-set-key [?\sd] #'dired) (global-set-key [?\sf] #'find-file)) (defun my--kill-this-buffer-maybe-switch-to-next () "Kill current buffer. Switch to next buffer if previous command was switching to next buffer or this command itself allowing sequential closing of uninteresting buffers." (interactive) (let ( (cmd last-command) ) (kill-buffer (current-buffer)) (when (memq cmd (list 'next-buffer this-command)) (next-buffer)))) (global-set-key [s-delete] 'my--kill-this-buffer-maybe-switch-to-next) (defun my--backward-other-window () (interactive) (other-window -1)) (global-set-key [s-up] #'my--backward-other-window) (global-set-key [s-down] #'other-window) (global-set-key [s-tab] 'other-window) 

Notez que j’utilise super clé afin que term-raw-map et éventuellement toute autre keymap n’entre pas en conflit avec mes raccourcis clavier. Pour créer une super clé à partir de la clé Win j’utilise .xmodmaprc :

 ! To load this config run: ! $ xmodmap .xmodmaprc ! Win key. clear mod3 clear mod4 keycode 133 = Super_L keycode 134 = Hyper_R add mod3 = Super_L add mod4 = Hyper_R 

Vous devez juste vous rappeler 2 commandes: Cc Cj – pour accéder au mode d’édition Emacs normal (pour copier ou gruger du texte tampon), Cc Ck – pour revenir au mode d’émulation de terminal.

Sélection de la souris et Shift-Insert fonctionnent comme dans xterm .

J’utilise Prelude et quand je frappe Meta + Tab, ça se termine pour moi.

En outre, Ctrl + i semble faire la même chose.

J’utilise le mode barre. Il a cette fonctionnalité (après avoir appuyé sur “TAB”): entrer la description de l'image ici

Je ne prétends pas être un expert emacs mais cela devrait résoudre votre problème:

Créer: ~ / .emacs

Ajouter à cela:

(require ‘shell-command) (mode de fin de commande shell)

Emacs reprend le shell afin que les parameters BASH ne soient pas appliqués. Cela va définir l’achèvement automatique pour EMACS lui-même.