open コマンドで開くコマンドから学ぶ、とても簡単な Elisp。

簡単なコマンドがすぐに作れるところが、Emacs の魅力のひとつなのですが、実際、Emacs を利用してるけど、Elisp 分かんないし、書いたことないっていう人が多いです。
でも実はプログラミングしたことない人でも、目的の関数のさえ分かればすぐにコマンドを作ることが出来るくらい Elisp は簡単なので、なんか難しそうと毛嫌いしているのは勿体ない話です。
なので、今日は簡単なコマンドを紹介しつつ、Elisp の基本を説明してみましょう。

Mac OSX の open コマンドでバッファを開くコマンド。

簡単な例として、シェルコマンドの open を使ってカレントバッファを開くコマンドを作ってみました。

(defun open ()
  "Open current buffer for OSX command"
  (interactive)
  (shell-command (concat "open " (buffer-file-name))))

このコマンドは、例えば /Users/tomoya/tmp/hoge.html というファイルを編集していた時に M-x open と実行すると、ターミナルで

$ open /Users/tomoya/tmp/hoge.html

と実行したのと同じ結果が得られ、動作は標準のブラウザで hoge.html を開いてくれます。

コマンドの Elisp の説明。

やっている事を箇条書きしてみましょう。

  1. defun 関数で関数を作ります。
  2. 次に引数はないので空の () を用意します。
  3. DOCSTRING と呼ばれる関数の説明分を書きます*1。これは省略可能です。
  4. (interactive) と呼ばれる特殊な宣言をします*2。これによって M-x からコマンドとして呼び出すことが可能になります。
  5. そして、shell-command 関数でシェルコマンドを実行してもらいます。
  6. (buffer-file-name) でカレントバッファのフルパス付きファイル名を取得。
  7. そして、concat 関数で文字列を連結して、コマンドを作っています。

ざっと、こんな感じです。簡単でしょう?
作ったコマンドは設定ファイル(.emacs や init.el)に書いておくことで、今後も利用できるというわけです。
ファイルをシェルに渡すという操作は、色々と応用が効くので、何か自分のコマンドを作ってみるのに最適ではないでしょうか?というわけで、ぜひ自分だけのコマンドを作ってみましょう :-)

追記: ファイルにスペースが入っていると動作しないぞ!

ぜんぜん意識してなかったのですが、rubikitch 大先生からご指摘頂きました。
自分だけが使うコマンドだと、とりあえず動けばいいやでオーケーだけど、広く公開するような場合は、こういうところを気をつけることが大事ですね。

*1:M-x describe-function RET open RET とすると、この説明が表示されます。

*2:詳しくは GNU Emacs Lispリファレンスマニュアル: コマンド定義 interactiveの使い方 を参照。