98

GNOME ターミナルでは、Bash がスマートなオートコンプリートを行います。例えば

apt-get in<TAB>

になる

apt-get install

Emacs シェルモードでは、明示的に source した後でも、このオートコンプリートは機能しません/etc/bash_completion。上記の例は、有効なコマンド オプションinではなく、現在のディレクトリ内のファイル名として固定またはオートコンプリートします。apt-getおそらく、これは Emacs が Tab キーの押下をインターセプトしているためです。でスマート オートコンプリートを有効にするにはどうすればよいshell-modeですか?

4

9 に答える 9

96

この問題は 3 年も前からあることはわかっていますが、解決したいと思っていた問題でもあります。Web 検索で、Emacs がシェル モードでの補完に bash を使用するようにする elisp の一部にたどり着きました。いずれにせよ、それは私にとってはうまくいきます。

https://github.com/szermatt/emacs-bash-completionで確認してください。

于 2011-11-16T13:52:48.953 に答える
21

emacs シェルでは、実際には bash ではなく、自動補完を行う emacs です。シェルと emacs が同期していない場合 (たとえば、pushd、popd、またはシェルの現在のディレクトリを変更する bash ユーザー関数を使用した場合)、オートコンプリートは機能しなくなります。

これを修正するには、シェルに「dirs」と入力するだけで同期がとれます。

.emacs には次のものもあります。

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

次に、Esc-return を押すだけで、オートコンプリートが再同期されます。

于 2008-10-21T06:24:00.700 に答える
16

これに対する答えはわかりません。しかし、期待どおりに動作しない理由は、おそらく emacs シェルの補完が emacs によって内部的に (comint-dynamic-complete 関数によって) 処理され、それらのスマートな補完関数が組み込まれていないためです。

簡単に修正できるものではないのではないかと心配しています。

編集: term-mode を使用するという njsf の提案は、おそらく最高です。から始めましょう

Mx ターム
これは、標準の emacs ディストリビューション (および少なくとも Ubuntu と Debian の emacs21-common または emacs22-common) に含まれています。

于 2008-10-02T18:09:29.513 に答える
9

2011年に問題が発生したときにこれを行ったように、別のモードを検討してくださいM-x term。当時、この質問を含め、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(はい! の任意の単語から Bash に dabbrev があります~/.bash_history):

set -o emacs

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

.emacsterm バッファでのナビゲーションを快適にする:

(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

次の 2 つのコマンドを覚えておく必要があります。C-c C-j- 通常の Emacs 編集モード (バッファー テキストのコピーまたは grep 用) に入るC-c C-k- 端末エミュレーション モードに戻る。

マウス選択とShift-Insertのように動作しxtermます。

于 2015-02-19T23:06:28.060 に答える
6

Matli が言ったように、bash は --noediting で開始され、TAB は comint-dynamic-complete にバインドされているため、簡単な作業ではありません。

local-set-key を使用して shell-comand-hook で TAB を self-insert-command に再バインドし、Mx Customize-variable RET explicit-bash-args による --noediting で shell-mode を開始しないようにすることもできますが、私はそれを疑っています。他のすべての編集とうまく調和しません。

term-mode を試してみたいと思うかもしれませんが、他の通常のキーバインドのいくつかが term-mode に取って代わられるため、別の問題があります。

編集: 他の通常のキー入札が term-mode に追い越されるということは、バッファを切り替えることができるエスケープになる Cc 以外のすべてを意味します。したがって、Cx k でバッファーを削除する代わりに、Cc Cx k を実行する必要があります。または別のバッファに切り替えるには 'Cc Cx o' または 'Cc Cx 2'

于 2008-10-03T02:55:07.053 に答える
1

Prelude を使用しており、Meta+Tab を押すと完了します。

また、Ctrl+i でも同じことができるようです。

于 2013-04-16T02:45:21.393 に答える
-2

私はemacsの専門家であるとは主張しませんが、これで問題が解決するはずです:

作成: ~/.emacs

それに追加します:

(require 'shell-command) (シェルコマンド補完モード)

Emacs がシェルを引き継ぐため、BASH 設定は引き継がれません。これにより、EMACS 自体のオートコンプリートが設定されます。

于 2008-10-02T19:16:17.980 に答える