違いを理解していなかったので整理した。
以下の三種類に大別できる。
- M-x shell
- M-x term
- ansi-term, multi-term, vterm などの亜種がある
- M-x eshell
M-x shell
- 38.2 Interactive Subshell
- Emacs のバッファと I/O が繋がったサブシェルを立ち上げる
- メジャーモードは shell-mode
- 大半の Emacs キーバインドが使える
- そのかわり端末エミュレーター上でシェルを使う際の一般的なキーバインドは使えない(
C-r
とか) - shell-mode 内でシェルの履歴を操作するキーバインド 38.5.1 Shell History Ring
- そのかわり端末エミュレーター上でシェルを使う際の一般的なキーバインドは使えない(
- なんだかんだで使い勝手が良いが
vim
とかless
を実行すると終了できずに慌てたりするq
だけではサブシェルにキーが送られないのでq RET
とすればよい
M-x term
- Emacs 内で動く端末エミュレーター 38.8 Emacs Terminal Emulator
- 他に ansi-term, multi-term, vterm などの亜種があるが、どれも「Emacs 内で動く端末エミュレーター」というコンセプトは同じ
- Emacs のバッファと I/O が繋がったサブシェルを立ち上げる
- メジャーモードは term-mode
- term-mode は内部に二つのモードを持つ
- The terminal emulator uses Term mode, which has two input modes. In line mode, Term basically acts like Shell mode (see Shell Mode). In char mode, each character is sent directly to the subshell, as terminal input; the sole exception is the terminal escape character, which by default is C-c (see Term Mode).
- In term-mode (which multi-term uses) there are two input modes:
- この StackOverflow コメントで知った
- line mode
- shell-mode と同じような挙動をする
- char mode
- 大半のキーは直接端末エミュレーターを介してシェルに送られる
- 大半の Emacs キーバインドは使えない(
C-p
はカーソルの移動ではなくコマンド履歴を遡る)
- 大半の Emacs キーバインドは使えない(
- 大半のキーは直接端末エミュレーターを介してシェルに送られる
- char mode から line mode へ切り替え
C-c C-j
(M-x term-line-mode)
- line mode から char mode へ切り替え
C-c C-k
(M-x term-char-mode)
- line mode と char mode を使い分ければ shell-mode を内包するので万能
- うっかり line mode のとき
vim
やless
を実行してもC-c C-k
で char mode に切り替えてq
で終了したりできる
- うっかり line mode のとき
M-x eshell
- Emacs Lisp で実装されたシェル
- サブシェルを起動しない
- 独自路線、いろいろ独特
- Eshell のマニュアルは Emacs のマニュアルとは独立している https://www.gnu.org/software/emacs/manual/html_node/eshell/index.html#Top
余談
- 歴史的には
ansi-term
はterm
の改良版という位置づけだったが、現在は実質的に大差ないらしい - Spacemacs 内で一度でも
multi-term
を立ち上げるとC-c C-j
(term-line-mode
) のキーバインドが消えてしまい、その後term
やansi-term
を立ち上げ直しても消えたままになってしまった。元に戻すには Emacs の再起動が必要。 - term-mode の char mode で
C-h
が効かないのがストレス- なんとなく
bind-key*
との兼ね合いな予感。もう少し調べる - ビンゴ。しかし
bind-key
にしたら、 ivy を有効化したC-x C-f
(find-file) バッファ内でC-h
が効かなくなってしまった- ivy が
C-x C-f
をcounsel-find-file
に置き換えるが、このモードにC-h
が効いてない (bind-key "C-h" 'counsel-up-directory counsel-find-file-map)
を足すことで解決した- helm 使ってたとき似たような設定をしていた名残があった
(bind-key "C-h" nil helm-map)
- helm 使ってたとき似たような設定をしていた名残があった
- ivy が
- なんとなく
(defun dotspacemacs/user-config () (bind-key "C-h" 'backward-delete-char) ;; (bind-key* "C-h" 'backward-delete-char) ;; NG (bind-key "C-h" 'counsel-up-directory counsel-find-file-map) (add-hook 'term-mode-hook (lambda () (bind-key "C-h" 'term-send-backspace term-raw-map) ;; 上記のように bind-key と組み合わせると OK。 bind-key* と組み合わせると NG。 (bind-key "C-y" 'term-paste term-raw-map) )) )
- かつては eshell をメインで使っていたなぁ... https://blog.kyanny.me/search?q=eshell