Bash Autocompletion in Emacs Shell-Mode

In de GNOME-terminal, bash doet slimme auto-voltooiing. Bijvoorbeeld

apt-get in<TAB>

wordt

apt-get install

In Emacs Shell-Mode werkt deze auto-voltooiing niet, zelfs nadat ik expliciet wordt gedaan /etc/bash_completion. Het bovenstaande voorbeeld stickt als inof automatisch voltooid met een bestandsnaam in de huidige map in plaats van een geldige apt-get-opdrachtoptie. Vermoedelijk is dit omdat EMACS het tabblad Tab-toets onderschept. Hoe maak ik Smart Auto-voltooiing in shell-mode?


Antwoord 1, Autoriteit 100%

Ik weet dat deze vraag drie jaar oud is, maar het is iets dat ik ook geïnteresseerd ben geweest in het oplossen. Een webzoekopdracht leidde me naar een stuk Elisp dat EMACS bash gebruikt voor de voltooiing in de Shell-modus. Het werkt in ieder geval voor mij.

Controleer het op https://github.com/szermatt/emacs-bash-completion .


Antwoord 2, Autoriteit 22%

In de Emacs Shell is het eigenlijk emacs die de auto-voltooiing doen, niet bash. Als de schaal en EMACS niet synchroon (b.v. met behulp van pushd, POPD of wat BASH-gebruikersfunctie die de huidige directory van de Shell wijzigen), stopt automatisch voltooien.

Om dit te verhelpen, typt u gewoon ‘DIRS’ in de schaal en gaan dingen opnieuw in synchronisatie.

Ik heb ook het volgende in mijn .macs:

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

Draai vervolgens gewoon de Esc-Return Resyncs de automatische voltooiing.


Antwoord 3, Autoriteit 17%

Ik weet het antwoord hierop niet. Maar de reden dat het niet werkt zoals je verwacht is waarschijnlijk omdat de voltooiing in Emacs-shells door Emacs intern wordt afgehandeld (door de Comint-dynamic-complete functie), en heeft die slimme voltooiingsfuncties niet.

Ik ben bang dat het niet gemakkelijk is om te repareren.

EDIT: NJSF’s suggestie van het gebruik van de Term-modus is waarschijnlijk net zo goed als het wordt. Start het met

m-x-term 

Het is opgenomen in de standaard Emacs-distributie (en in Emacs21-Common of Emacs22-Common on Ubuntu en Debian in ieder geval).


Antwoord 4, Autoriteit 7%

Overweeg alstublieft een andere modus M-x term, zoals ik dit heeft gedaan bij het probleem in 2011. Ik probeerde alle inspanningen over inet op dat moment te verzamelen om Shell-werk te maken met Bash-voltooiing, inclusief deze vraag . Maar sinds het ontdekken van alternatief in het gezicht van term-modeIk wil het niet eens proberen eshell.

Het is volledige terminalemulator, dus u kunt interactief programma binnenlopen, zoals middernachtcommandant. Of overschakelen naar zshCOMPLETIE, dus u zult geen tijd verliezen op EMACS-configuratie.

U krijgt gratis tabblad in bash. Maar belangrijker, u krijgt volledige readline-power, zoals incrementele of voorvoegde opdrachtonderzoek . Om deze setup gemakkelijker te maken, controleer dan mijn .Inputrc , . Bashrc , . Emacs .

Essential deel van .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! Er is dabbrev in Bash van elk woord in ~/.bash_history):

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

.emacsom navigatie comfortabel te maken in termijnbuffer:

(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)

Zoals alle gebruikelijke commando’s zoals C-x oniet werken in terminalemulatiemodus heb ik de keymap uitgebreid met:

(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)

Merk op dat ik de super-sleutel gebruik, zodat term-raw-mapen mogelijk elke andere keymap niet in strijd zijn met mijn toetscombinaties. Om de super-sleutel van de linker Win-sleutel te maken, gebruik ik .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

Je moet gewoon 2 commando’s onthouden: C-c C-j– om naar de normale Emacs-bewerkingsmodus te gaan (voor kopiëren of greppen in buffertekst), C-c C-k– om terug te keren naar terminal-emulatiemodus.

Muisselectie en Shift-Insertwerken zoals in xterm.


Antwoord 5, autoriteit 6%

Zoals Matli al zei, het is geen gemakkelijke taak, aangezien bash wordt gestart met –noediting en TAB gebonden is aan comint-dynamic-complete.

Je zou TAB mogelijk opnieuw kunnen binden aan zelf-insert-command in shell-command-hook met local-set-key
en laat shell-mode niet beginnen met –noediting door M-x customize-variable RET expliciet-bash-args, maar ik vermoed dat het niet goed zal passen bij alle andere bewerkingen.

Misschien wil je term-mode proberen, maar het heeft nog een aantal problemen, omdat sommige van de andere reguliere sneltoetsen worden ingehaald door term-mode.

EDIT: met andere reguliere keybidings die worden ingehaald door term-mode, bedoel ik alles behalve C-c, wat de ontsnapping wordt om van buffer te kunnen wisselen. Dus in plaats van C-x k om de buffer te doden, zou je C-c C-x k moeten gebruiken. Of om over te schakelen naar een andere buffer ‘C-c C-x o’ of ‘C-c C-x 2’


Antwoord 6, autoriteit 3%

Ik weet dat dit bericht nu meer dan 11 jaar oud is. Maar ik heb een functie gemaakt om native shell-aanvulling in Emacs te geven. Het stuurt gewoon een tab-toets naar het onderliggende proces en onderschept de uitvoer, dus het is precies hetzelfde als in de shell zelf.

https://github.com/CeleritasCelery/emacs-native-shell-complete


Antwoord 7

Ik gebruik Prelude en wanneer ik op Meta+Tab druk, is het voor mij voltooid.

Ook Ctrl+i lijkt hetzelfde te doen.


Antwoord 8

Ik gebruik de roermodus. Het heeft deze functionaliteit (na het indrukken van “TAB”):


Antwoord 9

Ik beweer niet dat ik een emacs-expert ben, maar dit zou je probleem moeten oplossen:

Maken: ~/.emacs

Voeg er aan toe:

(vereist ‘shell-commando)
(shell-command-completion-mode)

Emacs neemt de shell over, zodat de BASH-instellingen niet doorgaan. Hiermee wordt automatisch aanvullen voor EMACS zelf ingesteld.

Other episodes