彼女からは、おいちゃんと呼ばれています

ウェブ技術や日々考えたことなどを綴っていきます

Emacs のシェルモード比較 - shell、ansi-term、multi-term

最近ちょこちょこと Carbon EmacsEmacs 22.3)のシェルモードのいくつかを試してきました。そろそろひと区切りつけたいと思うので、まとめておきます。

試したのは次の 4つのモードです。

  • 標準シェルモード(shell)
  • ansi-term(term)
  • multi-term
  • eshell

そもそもどういう使い方をしているのか

ところでそもそも Emacs のシェルモードを普段どう使っているかというと、主に作業ログをまとめるのに使っています。

PythonRuby の対話モードであれやった、これやったとか、MacPorts からこれをインストールしようとしてうまくいった、いかなかったとかいう記録をあとで見やすいように適当に整形して Evernote へ放り込む。Evernote へ放り込む前の「整形」時には、ターミナルからコピペするよりも Emacs のシェルモードを使ったほうが断然早いよね、というのが使っている理由です。

結構手に馴染む標準シェルモード

というわけで、まずは標準のシェルモード。

M-x shell

で起動できます。

つまらないスペルミスのコマンドとかを打ってしまってもその場で出力結果ごと消せば良いし、コマンドを打ちたいときに以前の出力結果などをキル&ヤンクできるし、何かと手に馴染みます。コマンドの出力結果を編集したりバッファに貼り付ける用途には標準のシェルモードが一番適しているような気がします。

それでもタブキーによる補完機能が弱かったり、コマンドライン履歴からの検索もデフォルトではできないため、巷ではあまり評価は高くないようです。

このモードはターミナルとしての機能に制限があります。端的には[tab]による補完なども機能しませんし,「ターミナルソフトウェア」としては不完全なものです。多くの場合,このモードはあまり役に立たないと思われます。

ひどい言われようですね(笑)。僕もひとつだけ不満を言うと、git diff のときにどうしてカラー表示が無視されるのか不思議。


ansi-term は本当にシェルですね

次。ansi-term(term)は、Emacs Lisp で書かれた端末エミュレータです。

M-x ansi-term(または M-x term)

で起動します。端末エミュレータなので、シェルの機能をほぼそのまま利用できます。Bash だけはなく Zsh なども使えるそうです。

使った感じ、良くも悪くもシェルそのまんまでした。使い慣れたターミナルとほとんど同じ挙動なので、違和感なく扱える一方、出力結果をバッファに貼り付けたりといった「編集」機能は扱いづらかったです。

また、Emacsキーバインドも結構奪われたりしたので、

それだったら、シェルを別個に使ったほうがいいかなー

という感想に至りました。


ansi-term の欠点を補った multi-term

ansi-term は優秀ですが Emacs との親和性が低いので、拡張モードがつくられました。それが multi-term です。

multi-term は term を拡張したモードになります。term は確かに優れたモードですがいくつかの問題も存在しています。

  • 複数起動ができません
  • Emacs の標準的なキーを多数奪ってしまいます
  • exit してもバッファが消えません
  • Emacs 終了時に term 内の shell を終了していないと自動で終了してくれません
  • デバッグプログラムのための専用ウィンドウを持ちません

これらを解決するために multi-term.el を利用します。

multi-term は標準では使えませんが、下記 URL からダウンロードできます。

初期化ファイル(~/.emacs 等)に

(require 'multi-term)

を記述しておいて、

M-x multi-term

で起動します。

実はこのモードはつい最近まで知らなくって、id:tomoya さんに教えてもらいました。試してみて、なんというか、確かに shell と ansi-term の良いとこ取りな感じがします。出力結果を自由に編集できるし、補完機能も使えます。

しかし、例えば「ls」コマンドを打とうとして誤って「ll」って打った後に「l」をひとつ消してから「s」を追加しコマンドを実行したとします。誤った「l」を delete ボタンで消したときには意図したとおり「ls」コマンドが実行されるのですが、C-h に割り当てている delete-backward-char コマンドで消したときには

lls: command not found

と怒られてしまいます...というのは一例ですが、他にも チッ(-。-;) となるような挙動がいくつかありました。multi-term は端末エミュレータなのでキー入力がそのままプロセスに行き渡るのが原因だと思うのですが、ansi-term では同様のバグ(?)はなかったので、なんだかなーと思ってしまいました。

あと、僕の環境では下記のような見映えとなり、ちょっとげんなり。

いや、もちろん設定を変更してやれば済むハナシなんですが、今はちょっとそこに割く時間がつくり出せないので今回はパスしました。

eshell、ごめんなさい

最後、eshell

M-x eshell

で起動します。Emacs Lisp のみで実装されたシェルモードです。Emacs Lisp でかなり高度にカスタマイズできるようですが、逆にその点が使いこなすのに時間がかかりそうに感じてしまいパスしました。ヘタレでごめんなさい。

結論 - 出力結果の編集用途には標準シェルモードが一番

結局、どのシェルモードを使うべきかは使い途によると思うのですが、僕のように出力結果の編集に特化した使い方だと標準シェルモードがお手軽で素晴らしいと思いました。少なくとも現時点の自分には分相応という感じがします。巷の意見とは結構異なるところがありますが、そういう人もいるよということで。

ではでは。

おまけ - あの「るびきち」さんは、どうしているんだろう??

ちなみに、日本の Emacs 第一人者るびきちさんは、本の中で下記のように書かれていました。参考まで。

Emacsテクニックバイブル ?作業効率をカイゼンする200の技?

Emacsテクニックバイブル ?作業効率をカイゼンする200の技?

Emacs でシェルは動かしません。筆者は zsh を使っているので、M-x shell の補完の弱さは我慢できません。昔は使っていましたが、zsh の熟練度が上がるにつれてデメリットの方が上回ったのです。M-x multi-term も遅いので使っていません。