Emacs kabuk modunda Bash otomatik tamamlama


93

GNOME Terminalinde, Bash akıllı otomatik tamamlama yapar. Örneğin

apt-get in<TAB>

olur

apt-get install

Emacs kabuk modunda, bu otomatik tamamlama, açıkça kaynak sağladıktan sonra bile çalışmıyor /etc/bash_completion. Yukarıdaki örnek in, geçerli bir apt-getkomut seçeneği yerine geçerli dizindeki bir dosya adı olarak yapışır veya otomatik olarak tamamlanır . Muhtemelen, bunun nedeni Emacs'ın Tab tuşuna basmayı kesmesidir. İçinde akıllı otomatik tamamlamayı nasıl etkinleştiririm shell-mode?


Emacs'de yeni olan herkes için ... emacs'de başka kabuk modları vardır. Mesela eshell-modehangi sekme tamamlama vardır. Daha fazla bilgi burada: masteringemacs.org/articles/2010/11/01/…
Ross

3
eshell'in otomatik tamamlama işlevi yalnızca yerel dizinler için çalışır, başka bir makineye ssh yaparsanız, bu yeteneği aniden kaybedersiniz.
hajovonta

Yanıtlar:


94

Bu sorunun üç yaşında olduğunu biliyorum ama çözmekle de ilgilendiğim bir şey. Bir Web araması beni Emacs'ın kabuk modunda tamamlamak için bash kullanmasını sağlayan bir elisp parçasına yönlendirdi. Her durumda benim için çalışıyor.

Https://github.com/szermatt/emacs-bash-completion adresinden kontrol edin .


6
Üç yaşındaki bir çocuğa cevap verecek cesarete sahip olmak için +1, ancak yine de tamamen alakalı bir soru. Teşekkürler!
djhaskin987

3
Bu zaten melpa melpa.org/#/bash-completion'da , kurulum kullanımı basit M-x package-list-packages, ama sonunda benim için işe yaramadı , nedenini bilmiyorum , emac'lerim olabilir (24.3.1) veya bash (4.3.30) sürümü. Belgeler "bash-complete.el, işletim sistemi ve BASH sürümüne oldukça duyarlıdır ..." diyor ve ardından sürümlerimin olmadığı bir liste.
boclodoa

Maalesef 6 numaralı sorunu beklemekte olan bu CLI araçlarının mevcut kesimi için pek kullanışlı görünmüyor.
Jesse Glick

Bu sorun 6, <en azından çoğunlukla düzeltildi / çalışmama örneğine ihtiyaç duyulduğu için> kapatıldı (başka kelimelerle ifade edildi).
Matthew Elvey

20

Emacs kabuğunda, aslında otomatik tamamlamayı yapıyor, bash değil. Kabuk ve emacs senkronize değilse (örneğin, kabuğun geçerli dizinini değiştiren pushd, popd veya bazı bash kullanıcı işlevlerini kullanarak), otomatik tamamlama çalışmayı durdurur.

Bunu düzeltmek için, kabuğa 'dirs' yazmanız yeterlidir ve her şey yeniden senkronize olur.

Emac'lerimde de şu bilgiler var:

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

Daha sonra Esc-return tuşuna basmak otomatik tamamlamayı yeniden senkronize eder.


9
Bu, farklı bir soruya güzel bir cevap!
Chris Conway

Teşekkürler. Otomatik atlama kullanıyorum ve dizinlerin uyumsuzluğunun nedeni buydu.
Plankalkül


15

Bunun cevabını bilmiyorum. Ancak beklediğiniz gibi çalışmamasının nedeni muhtemelen emacs kabuklarındaki tamamlamanın dahili olarak emacs tarafından (comint-dynamic-complete işlevi tarafından) ele alınması ve bu akıllı tamamlama işlevlerinin yerleşik olarak bulunmamasıdır.

Korkarım düzeltmesi kolay bir şey değil.

Düzenleme: njsf'nin terim kipini kullanma önerisi muhtemelen olabildiğince iyidir. İle başlayın

Mx terimi
Standart emacs dağıtımına (ve en azından Ubuntu ve Debian'da emacs21-common veya emacs22-common'a) dahildir.


2
Sekme tamamlama ile daha da kötü M-x term.
mcandre

7

Lütfen, M-x term2011'de problemle karşılaştığımda yaptığım gibi başka bir modu düşünün . Bu soru da dahil olmak üzere Bash tamamlama ile kabuk çalışması yapmak için o sırada Inet üzerinden tüm çabaları toplamaya çalıştım. Ama karşımda alternatif term-modebulduğumdan beri denemek bile istemiyorum eshell.

Tam terminal emülatörüdür, böylece Midnight Commander gibi interaktif programı içeride çalıştırabilirsiniz. Veya geçiş yapzsh Emacs yapılandırmasında zaman kaybetmemek tamamlamaya .

Bash'de ücretsiz olarak TAB tamamlama elde edersiniz. Ancak daha da önemlisi, artımlı veya önekli komut araması gibi tam Readline gücüne sahip olursunuz . Bu kurulumu daha rahat hale getirmek için .inputrc , .bashrc , .emacs’lerimi kontrol edin .

Aşağıdakilerin temel kısmı .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! Bash'de herhangi bir kelimeden itibaren dabbrev var ~/.bash_history):

set -o emacs

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

.emacs terim tamponunda gezinmeyi rahat hale getirmek için:

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

C-x oUçbirim öykünme modunda çalışmadığı için her zamanki komutlar gibi , tuş eşlemesini şununla genişlettim:

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

superAnahtarı kullandığımı term-raw-mapve muhtemelen diğer herhangi bir tuş eşlemesinin anahtar bağlamalarımla çakışmadığını unutmayın. superSol tuştan Winanahtar yapmak için kullanıyorum .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

Sadece 2 komutu hatırlamanız gerekir: C-c C-j- normal Emacs düzenleme moduna girmek için (tampon metninde kopyalama veya grepleme için), C-c C-k- terminal öykünme moduna dönmek için.

Fare seçimi ve Shift-Insertolduğu gibi çalışın xterm.


1
Teşekkür ederim, bu altın! özellikle .inputrckısım!
cmantas

6

Matli'nin dediği gibi, bash --noediting ile başladığından ve TAB comint-dynamic-complete'e bağlı olduğundan bu kolay bir iş değildir.

Muhtemelen TAB'yi kabuk-komand-kancalı kendi kendine ekleme komutuna yerel set anahtarıyla yeniden bağlayabilir ve kabuk modunun --noediting tarafından Mx custom-variable RET explicit-bash-args ile başlamaması mümkün olabilir, ancak ben bundan şüpheleniyorum diğer tüm düzenlemelerle uyumlu olmayacaktır.

Terim kipini denemek isteyebilirsiniz, ancak başka bir dizi problemi vardır, çünkü diğer bazı normal tuş atamaları terim kipi tarafından geçilir.

DÜZENLEME: Diğer normal anahtar tekliflerinin terim modu tarafından geçilmesi ile, tamponları değiştirebilmek için bir kaçış haline gelen Cc dışındaki her şeyi kastediyorum. Dolayısıyla, tamponu öldürmek için Cx k yerine Cc Cx k gerekir. Ya da başka bir arabelleğe geçmek için 'Cc Cx o' veya 'Cc Cx 2'


self-insert-command bu değildir: SEKME tuşunu Bash'e geçirmek yerine TAB karakterini ekler.
Chris Conway

Terim modu komutum yok ve nereden alacağımı bulamıyorum.
Chris Conway


1

Prelude kullanıyorum ve Meta + Tab'a bastığımda benim için tamamlanıyor.

Ayrıca Ctrl + i aynı şeyi yapıyor gibi görünüyor.


0

Dümen modunu kullanıyorum. Bu işleve sahiptir ("SEKME" ye bastıktan sonra): görüntü açıklamasını buraya girin


-2

Bir emacs uzmanı olduğumu iddia etmiyorum, ancak bu, sorununuzu çözmeli:

Oluştur: ~ / .emacs

Buna ekleyin:

('kabuk-komutu gerektirir) (kabuk-komut-tamamlama-modu)

Emacs kabuğu ele geçirdiğinden BASH ayarları uygulanmaz. Bu, EMACS için otomatik tamamlamayı ayarlayacaktır.


Hayır, bu sorunu çözmez. Sadece kabuk-komutunda çalışır, kabuk kipinde değil. Ayrıca soruda istenen akıllı tamamlamayı etkinleştirmez (yalnızca komutları ve dosya adlarını tamamlayacaktır).
matli

1
kabuk-komut-tamamlama-modu dosya adı tamamlama yapar ve varsayılan olarak etkindir. Bash'in tamamlama özelliğini istiyorum (örneğin, apt-get ve svn için alt komutları içerecek şekilde genişletilebilir).
Chris Conway
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.