EmacsLispことはじめ 設定を書く~hookと自作コマンド~


はじめに

この記事は、SLP_KBITその2 Advent Calendar 2016 - Qiitaの2日目の記事です。
SLP_KBIT Advent Calendar 2016 - Qiitaの1日目の記事の続きです。

hubotについて書くと言っていたのですがやっぱりElispについて書くことにしました!

前回は、EmacsLispを普通のプログラミング言語と同じように使って、プログラムの作成を行いました。
しかし、EmacsLispは本来はEmacsの設定や機能を書くための言語...なので、今回は実際にEmacsの設定を書いていこうと思います!
目指せ脱コピペinit.el !

scratchでEmacsLispを記述する

前回の記事では、EmacsLispをscript言語のように実行するオプション--scriptで実行していました。
今回は、きちんとEmacs内で実行します。
通常、emacsを起動した際には、scratchというバッファが開かれています。
C-x C-b -> C-x o -> scratchを選択 -> Enterでscratchバッファに移動することが出来ます。
ここでは、EmacsLispの式を書いた後、行末でC-jを押すことで、その式が評価されます。
例: (message "Hello")と書いて、行末でC-jを押すと、Emacs下部の領域(エコー領域)と式の直下に"Hello"と表示されると思います。
こうして、逐次実行結果を確認しながら書くことが出来ます。

関数の定義

EmacsLispでの関数の定義は、以下の形式で記述することが出来ます。

(defun 関数名 (引数1 引数2 ...) 処理)

例えば、"Hello"と表示するだけの関数my-messageを、以下のような処理で記述します。

init.el
(defun my-message ()
  (message "Hello"))

hook

Emacsには、本体に様々なhookが用意されています。
hookとは、特定のイベントのタイミングで、指定した処理を実行する仕組みです。
まずは、簡単にemacs起動時に先程の関数を実行するようにhookしてみましょう。
hookの追加は、add-hook関数で実行します。emacs起動終了のhookは、emacs-startup-hookです。
以下の設定を追加しましょう。

init.el
(add-hook 'emacs-startup-hook 'my-message)

これで、起動した際にエコー領域にHelloと表示されるようになったと思います。

シングルクォート

先程の設定には、'my-messageのように、関数名やhook名の直前に、シングルクォートが書かれていたと思います。
これは、quote関数の省略記法です。
quote関数は、引数に与えられた値を評価せずに、シンボルを返却する関数です。(2016.12.03 追記1)
quoteは、引数に与えられた値を評価せずに、シンボルを返却する 特殊形式 と呼ばれるものの1つです。
シンボルとは、簡単に言うと引数そのもののことです。
以下に例を示します。

(setq hoge 1)
=> 1

hoge
=> 1

(quote hoge)
=> hoge

'hoge
=> hoge

上記の通り、quoteを付けた場合には、値ではなくhogeという変数自体が返却されています。

setqも、実は(set (quote 変数) 値)と同様な意味を持つ特殊記法です。(*1)
例えば、以下を実行しようとしたとき、2行目では、変数hogeが展開され、8となり、81を代入しようとするよくわからない式になってしまいます。
quoteを使うことで、hogeというシンボルに8を代入するという式になります。

(setq hoge 8)
(set hoge 1)

関数をコマンドにする

先程のmy-message関数は、コード内からは呼び出せますが、ユーザから呼び出すことが出来ません。
これを、my-messageというコマンドとして、ユーザから呼び出せるようにしてみましょう。
やることは、関数の本体の直前に(interactive)という式を挿入するだけです。

init.el
(defun my-message ()
  (interactive)
  (message "Hello"))
(add-hook 'emacs-startup-hook 'my-message)

結果

無事、新しいコマンドを作成することが出来ました!(パチパチパチ

おわりに

今回は、hookと自作コマンドについて取り上げました。
非常に簡単な内容なので、物足りない人がいたらごめんなさい。( )
hookはinit.el書いていてもよく見かけるので、覚えておいて損はないです!
次回ぐらいには、もっと便利な設定を書けるように精進してきます。


  1. quotesetqは、関数ではなく特殊形式と呼ばれるものでした。 @tadsan さんからのコメント頂いたため、変更をしました。