EmacsシェルモードでのBashオートコンプリート


92

GNOMEターミナルでは、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/...
ロス・

2
eshellのオートコンプリートはローカルディレクトリに対してのみ機能します。別のマシンにsshすると、突然この機能を失います。
hajovonta

回答:


92

この質問が3歳であることは知っていますが、これも解決に興味を持っている問題です。Web検索で、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、結局それは私にとってはうまくいきませんでした、なぜだかわかりません、それは私のemacs(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が同期しなくなった問題でした。
プランカルキュール


15

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

簡単に修正できるとは思えません。

編集:term-modeを使用するという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に再バインドし、シェルモードを--noeditingでMx Customize-variable RET explicit-bash-argsで開始しないようにすることもできますが、他のすべての編集ではうまく機能しません。

term-modeを試してみることもできますが、他の通常のキーバインドの一部がterm-modeに追い越されるため、別の問題が発生します。

編集:term-modeに追い越される他の通常のキービッドによって、私は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年に問題が発生したときにこれを行ったように、別のモードを検討してください。その時点で、この質問を含め、Inetを介してBash完了でシェルを動作させるためのあらゆる努力を集めようとしました。しかし、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にはの単語からの略語があります~/.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

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

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


1
ありがとう、これは金です!特に.inputrc一部!
cmantas 2017年

1

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

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



0

ヘルムモードを使用しています。それはこの機能を持っています(「TAB」を押した後): ここに画像の説明を入力してください


-2

私はemacsのエキスパートであるとは主張していませんが、これで問題が解決するはずです。

作成:〜/ .emacs

それに追加:

( 'shell-commandが必要です)(shell-command-completion-mode)

Emacsがシェルを引き継ぐので、BASH設定は引き継がれません。これにより、EMACS自体の自動補完が設定されます。


いいえ、これで問題は解決しません。シェルモードではなく、シェルコマンドでのみ機能します。また、質問で要求されたスマートコンプリーションは有効になりません(コマンドとファイル名のみが補完されます)。
matli 2008年

1
shell-command-completion-modeはファイル名の補完を行い、デフォルトで有効になっています。Bashの補完機能(たとえば、apt-getやsvnのサブコマンドを含めるように拡張可能)が欲しいのですが。
Chris Conway、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.