Emacs 셸 모드에서 Bash 자동 완성


93

그놈 터미널에서 Bash는 스마트 자동 완성을 수행합니다. 예를 들면

apt-get in<TAB>

된다

apt-get install

Emacs 셸 모드에서이 자동 완성 기능은 내가 명시 적으로 /etc/bash_completion. 위의 예 in는 유효한 apt-get명령 옵션이 아닌 현재 디렉토리의 파일 이름 으로 고정 되거나 자동 완성됩니다 . 아마도 이것은 Emacs가 Tab 키 누르기를 가로 채기 때문일 것입니다. 에서 스마트 자동 완성을 활성화하려면 어떻게해야 shell-mode합니까?


emacs를 처음 접하는 사람을 위해 ... emacs에는 다른 모드가 있습니다. 같은 eshell-mode어떤 탭 완성을 가지고있다. 여기에 더 많은 정보 : masteringemacs.org/articles/2010/11/01/…
Ross

3
eshell의 자동 완성 기능은 로컬 디렉토리에서만 작동합니다. 다른 컴퓨터로 ssh하면 갑자기이 기능을 잃게됩니다.
hajovonta

답변:


92

저는이 질문이 3 년 전이라는 것을 알고 있지만 저도 해결하는 데 관심이있었습니다. 웹 검색은 Emacs가 셸 모드에서 완료를 위해 bash를 사용하도록하는 elisp의 일부로 안내했습니다. 어쨌든 그것은 나를 위해 작동합니다.

https://github.com/szermatt/emacs-bash-completion 에서 확인 하세요 .


6
3 살이지만 여전히 완전히 관련이있는 질문에 답할 용기가 있다는 점에 +1. 감사!
djhaskin987

3
이것은 이미 melpa melpa.org/#/bash-completion 에 있으며 설치는을 사용하여 간단 M-x package-list-packages하지만 결국 작동하지 않았고 이유를 모르겠습니다. 이맥스 (24.3.1) 또는 bash (4.3.30) 버전. 문서에 "bash-completion.el은 OS 및 BASH 버전에 매우 민감합니다 ..."라고 나와 있으며 내 버전이없는 목록입니다.
boclodoa 2014 년

안타깝게도 이슈 # 6 이 보류 중이며 현재의 CLI 도구에는 그다지 유용하지 않은 것 같습니다.
Jesse Glick

21

emacs 셸에서는 실제로 bash가 아니라 자동 완성을 수행하는 emacs입니다. 쉘과 emacs가 동기화되지 않으면 (예 : pushd, popd 또는 쉘의 현재 디렉토리를 변경하는 일부 bash 사용자 기능을 사용하여) 자동 완성이 작동을 멈 춥니 다.

이 문제를 해결하려면 셸에 'dirs'를 입력하면 모든 것이 다시 동기화됩니다.

내 .emacs에 다음이 있습니다.

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

그런 다음 Esc-return을 누르면 자동 완성이 다시 동기화됩니다.


9
이것은 다른 질문에 대한 좋은 대답입니다!
Chris Conway

감사. 나는 autojump를 사용하고 그것이 dirs가 동기화되지 않은 문제였습니다.
Plankalkül

Chris Conway, 그렇습니다. emacs.stackexchange.com/questions/30550/… :-)
unhammer

15

나는 이것에 대한 답을 모른다. 그러나 예상대로 작동하지 않는 이유는 아마도 emacs 셸의 완성이 내부적으로 (comint-dynamic-complete 함수에 의해) emacs에 의해 처리되고 스마트 완성 기능이 내장되어 있지 않기 때문일 것입니다.

고치는 것이 쉬운 일이 아닌 것 같습니다.

편집 : njsf의 용어 모드 사용 제안은 아마도 좋은 것입니다. 시작

MX 기간
표준 emacs 배포판에 포함되어 있습니다 (최소한 Ubuntu 및 Debian의 emacs21-common 또는 emacs22-common).


2
탭 완성은 M-x term.
mcandre 2013

6

Matli가 말했듯이 bash는 --noediting으로 시작되고 TAB은 comint-dynamic-complete에 바인딩되어 있기 때문에 쉬운 작업이 아닙니다.

TAB을 local-set-key를 사용하여 shell-comand-hook에서 self-insert-command로 리 바인딩하고 쉘 모드를 Mx customize-variable RET explicit-bash-args로 --noediting으로 시작하지 않도록 할 수 있지만 다른 모든 편집과 잘 어울리지 않습니다.

기간 모드를 시도해 볼 수도 있지만 다른 일반 키 바인딩 중 일부가 기간 모드에 의해 추월되기 때문에 또 다른 문제가 있습니다.

편집 : 기간 모드에 의해 추월되는 다른 일반 키 입찰에 의해 버퍼를 전환 할 수있는 탈출구가되는 Cc를 제외한 모든 것을 의미합니다. 따라서 버퍼를 죽이려면 Cx k 대신 Cc Cx k를 사용해야합니다. 또는 다른 버퍼 'Cc Cx o'또는 'Cc Cx 2'로 전환하려면


self-insert-command가 아닙니다. TAB 키 누름을 Bash로 전달하는 대신 TAB 문자를 삽입합니다.
Chris Conway

기간 모드 명령이없고 어디서 구할 수 있는지 알 수 없습니다.
Chris Conway

6

M-x term2011 년에 문제가 발생했을 때했던 것처럼 다른 모드를 고려해보십시오 .이 질문을 포함하여 Bash 완성으로 쉘 작업을 수행하기 위해 당시 Inet에 대한 모든 노력을 모 으려고 노력했습니다. 그러나 term-mode나는 대안을 발견하기 때문에 시도조차하고 싶지 않습니다 eshell.

완전한 터미널 에뮬레이터이므로 Midnight Commander와 같은 대화 형 프로그램을 내부에서 실행할 수 있습니다. 또는 zsh완료로 전환하여 Emacs 구성에 시간을 낭비하지 않도록하십시오.

무료로 bash에서 TAB 완성을 얻습니다. 그러나 더 중요한 것은 증분 또는 접두사 명령 검색 과 같은 완전한 Readline 기능을 얻는 것 입니다. 이 설정을보다 편리하게하려면 .inputrc , .bashrc , .emacs를 확인하십시오 .

필수 부분 .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에는의 모든 단어에서 dabbrev가 있습니다 ~/.bash_history) :

set -o emacs

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

.emacs 용어 버퍼에서 탐색을 편안하게하려면 :

(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 o터미널 에뮬레이션 모드에서 작동하지 않는 일반적인 명령으로 키맵을 다음과 같이 확장했습니다.

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

super키를 사용 하므로 term-raw-map다른 키맵이 키 바인딩과 충돌하지 않습니다. super왼쪽 키에서 키 를 만들려면 다음을 Win사용합니다 .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

두 가지 명령을 기억해야합니다 C-c C-j.-일반 Emacs 편집 모드로 들어가기 (버퍼 텍스트에서 복사 또는 grepping), C-c C-k-터미널 에뮬레이션 모드로 돌아 가기.

마우스 선택과 Shift-Insert같이 작업 xterm.


1
감사합니다. 이것은 금입니다! 특히 .inputrc부분!
cmantas

1

Prelude를 사용하고 Meta + Tab을 누르면 완료됩니다.

또한 Ctrl + i는 같은 일을하는 것 같습니다.



0

투구 모드를 사용합니다. 다음 기능이 있습니다 ( "TAB"을 누른 후). 여기에 이미지 설명 입력


-2

나는 emacs 전문가라고 주장하지 않지만 이것이 당신의 문제를 해결할 것입니다.

만들기 : ~ / .emacs

추가 :

( 'shell-command 필요) (shell-command-completion-mode)

Emacs가 셸을 인수하므로 BASH 설정이 적용되지 않습니다. 이것은 EMACS 자체에 대한 자동 완성을 설정합니다.


아니요, 문제가 해결되지 않습니다. 쉘 모드가 아닌 쉘 명령에서만 작동합니다. 또한 질문에서 요청한 스마트 완성 기능을 활성화하지 않습니다 (명령과 파일 이름 만 완성합니다).
matli

1
shell-command-completion-mode는 파일 이름 완성을 수행하며 기본적으로 활성화됩니다. Bash의 완성 기능 (예 : apt-get 및 svn에 대한 하위 명령을 포함하도록 확장 가능)을 원합니다.
Chris Conway
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.