Domanda

Nel Terminale GNOME, Bash esegue il completamento automatico intelligente. Ad esempio

apt-get in<TAB>

diventa

apt-get install

Nella modalità shell di Emacs, questo completamento automatico non funziona, anche dopo aver esplicitamente creato / etc / bash_completion . L'esempio sopra si configura come in o si completa automaticamente con un nome file nella directory corrente anziché con un'opzione di comando apt-get valida. Presumibilmente, questo perché Emacs sta intercettando la pressione del tasto Tab. Come abilitare il completamento automatico intelligente in shell-mode ?

È stato utile?

Soluzione

So che questa domanda ha tre anni, ma è qualcosa che mi è stato anche interessato a risolvere. Una ricerca sul Web mi ha indirizzato a un pezzo di elisp che fa sì che Emacs usi bash per il completamento in modalità shell. Funziona per me, in ogni caso.

Dai un'occhiata a https://github.com/szermatt/emacs-bash-completion .

Altri suggerimenti

Nella shell di emacs, in realtà è emacs che esegue il completamento automatico, non bash. Se la shell e gli emacs non sono sincronizzati (ad esempio utilizzando pushd, popd o qualche funzione utente bash che modifica la directory corrente della shell), il completamento automatico smette di funzionare.

Per risolvere questo problema, basta digitare 'dirs' nella shell e le cose tornano in sincronia.

Ho anche quanto segue nel mio .emacs:

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

Quindi, semplicemente premendo Esc-return si risincronizza il completamento automatico.

Non conosco la risposta a questo. Ma la ragione per cui non funziona come previsto è probabilmente perché il completamento nelle shell emacs è gestito internamente da emacs (dalla funzione comint-dynamic-complete) e non ha quelle funzioni di completamento intelligente integrate.

Temo che non sia una cosa facile da risolvere.

Modifica: il suggerimento di njsf di usare la term-mode è probabilmente buono come sembra. Inizia con

M-x term
È incluso nella distribuzione standard di emacs (e almeno in emacs21-common o emacs22-common su Ubuntu e Debian).

Come ha detto Matli, non è un compito facile, dato che bash è iniziato con --noediting e TAB è destinata a comint-dynamic-complete.

Si potrebbe eventualmente ricollegare TAB al comando autoinserimento in shell-comando-hook con local-set-key e fare in modo che la modalità shell non inizi con --noediting di M-x custom-variabile RET esplicito-bash-args, ma sospetto che non andrà bene con tutte le altre modifiche.

Potresti voler provare a term-mode, ma ha un'altra serie di problemi, perché alcune delle altre combinazioni di tasti regolari sono superate da term-mode.

EDIT: Con altre normali offerte di tasti che vengono superate da term-mode, intendo tutto tranne C-c che diventa la fuga per poter cambiare buffer. Quindi invece di C-x k per uccidere il buffer dovresti C-c C-x k. Oppure per passare a un altro buffer "C-c C-x o" o "C-c C-x 2"

Per favore, prendi in considerazione un'altra modalità termine Mx , come ho fatto quando ho riscontrato un problema nel 2011. Ho cercato di raccogliere tutti gli sforzi su Inet in quel momento per far funzionare la shell con il completamento di Bash, inclusa questa domanda . Ma da quando ho scoperto un'alternativa di fronte a term-mode non voglio nemmeno provare eshell .

È un emulatore di terminale completo, quindi puoi eseguire un programma interattivo all'interno, come Midnight Commander. Oppure passa al completamento zsh in modo da non perdere tempo con la configurazione di Emacs.

Ottieni il completamento della TAB in bash gratuitamente. Ma è ancora più importante ottenere la piena potenza di Readline, come ricerca di comandi incrementale o con prefisso . Per rendere più comoda questa configurazione, controlla il mio .inputrc , . bashrc , . emacs .

Parte essenziale di .inputrc :

# I like this!
set editing-mode emacs

# Don't strip 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
"\C-x\C-e": edit-and-execute-command
$endif

# Define my favorite Emacs key bindings.
"\C-@": set-mark
"\C-w": kill-region
"\M-w": 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 string as prefix.
"\e[A": history-search-backward
"\C-p": history-search-backward
"\eOA": history-search-backward
"\e[B": history-search-forward
"\C-n": 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! C'è dabbrev in Bash da qualsiasi parola in ~ / .bash_history ):

set -o emacs

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

.emacs per rendere la navigazione comoda nel termine buffer:

(setq term-buffer-maximum-size (lsh 1 14))

(eval-after-load 'term
  '(progn
    (defun my-term-send-delete-word-forward () (interactive) (term-send-raw-string "\ed"))
    (defun my-term-send-delete-word-backward () (interactive) (term-send-raw-string "\e\C-h"))
    (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-string "\ef"))
    (defun my-term-send-backward-word () (interactive) (term-send-raw-string "\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-string "\e[1;3C"))
    (defun my-term-send-m-left () (interactive) (term-send-raw-string "\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)

Come tutti i soliti comandi come C-x o non funzionano in modalità di emulazione terminale ho esteso la mappa dei tasti con:

(unless
    (ignore-errors
      (require 'ido)
      (ido-mode 1)
      (global-set-key [?\s-d] #'ido-dired)
      (global-set-key [?\s-f] #'ido-find-file)
      t)
  (global-set-key [?\s-d] #'dired)
  (global-set-key [?\s-f] #'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)

Nota che uso la chiave super in modo che term-raw-map e possibilmente qualsiasi altra mappa chiave non siano in conflitto con i miei collegamenti chiave. Per rendere la chiave super da sinistra Win uso .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

Dovresti solo ricordare 2 comandi: Cc Cj - per accedere alla normale modalità di modifica di Emacs (per la copia o il grepping nel testo del buffer), Cc Ck - per tornare a modalità di emulazione terminale.

La selezione del mouse e Maiusc-Inserisci funzionano come in xterm .

Uso Prelude e quando premo Meta + Tab si completa per me.

Inoltre, Ctrl + i sembra fare la stessa cosa.

Uso la modalità timone. Ha questa funzionalità (dopo aver premuto " TAB "): inserisci qui la descrizione dell'immagine

Non pretendo di essere un esperto di emacs ma questo dovrebbe risolvere il tuo problema:

Crea: ~ / .emacs

Aggiungi ad esso:

(richiede 'shell-command) (Shell-command-completion-mode)

Emacs prende il controllo della shell in modo che le impostazioni BASH non vengano eseguite. Ciò imposterà il completamento automatico per EMACS stesso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top