Top - 環境設定のための Emacs Lisp 入門
はじめに
Emacs では環境設定する場合、最近ではカスタマイズやパッケージ管理機能などで簡単にできるようになってきています。 しかし、細かい設定をしたい時には、 コードを設定ファイルに書く必要があり、 このコードはLisp というプログラミング言語で書きます。Lisp 自体は Emacs よりも古くからある言語で Scheme 、 Common Lisp 、 Clojure といった多くの方言を持っています。 Emacs で使われる Lisp も Emacs に特化された Lisp です。(以降 Emacs 用の Lisp を elisp と呼びます)
Emacs の設定にはこの elisp の知識が必要なため、 Emacs は設定が大変だからと敬遠したり、 使っていても細かい設定はできないという人も多いのではないでしょうか。
とはいえ、 elisp を身に付けるのは少し大変です。 そこで環境設定に必要な内容に絞り、 なるべく早く elisp で設定ができるような入門を書いてみました。
ただし、範囲は絞っていますが、 説明している部分に関してはなぜそうしているのかということがわかるように深く説明しているつもりです。
対象読者
Emacs はプログラミング言語のコーディングに使われることが多いので、 Emacs を使う人はほとんどプログラミング経験者だとは思います。 ただ、Emacs はそれ以外のテキスト編集にも使われるため、 なるべくプログラミング未経験者にもわかるように書いたつもりです。ただし、 Emacs 自体はある程度使ったことがあることを前提に書いています。
また、設定でも正規表現はまれに使うことがあります。
正規表現についてはここでは解説していませんので、 必要な場合は以前の記事を見て下さい。
設定ファイル
Emacs の設定は基本的に ~/.emacs.d/init.el に記述します。ただし、以前は ~/.emacs.el、 ~/.emacs などのファイルが使われており、 このファイル名のファイルがあると init.el はロードされないので、注意して下さい。
また、これら以外にも少し使えるファイルもあります。 詳しく知りたい場合は以下のリンクを見て下さい。
式の構文と評価法 - 環境設定のための Emacs Lisp 入門
elisp 入門の最初として 今回は Emacs lisp の式の構文と Emacs での式の評価法を説明します。
Hello World !
『 K&R 』以来、プログラミングの入門では Hello World で始めるのが慣例です。 ここでも Hello World で始めましょう。まず、 Emacs を起動した時に表示される*scratch*バッファーに 以下のように記述して下さい。
(message "Hello World!")

次に行の最後で C-j を押してみましょう。 ミニバッファーに "Hello World!" の文字が表示されるはずです。
これから、この仕組みについて少しづつ解説してみたいと思います。
式の構文
最初に elisp で使われる式の構文について説明します。式と評価
Lisp では式は以下の形式で、一般的なプログラムの関数とは少し書き方が違っています。(関数 値 ...)(例) 使用言語の設定
(set-language-environment "Japanese")

最初の Hello World 例も
message
がミニバッファーに文字列を表示する「関数」で、
"Hello World!"
が「値」です。式を実行することを Lisp では 評価する(eval)と言います。 *scratch* バッファーでは C-j を押すことによって直前の括弧の式が評価されます。 起動時には init.el などに書いた式が順に評価されていくことになります。
また、*scratch* バッファーにも "Hello World!" と出たと思いますが、 こちらは式を評価した戻り値です。
なお、関数の後の値は引数といい、 関数によってとる種類や数が違います。 引数を取らない関数もあります。
;;; ステータスラインに時間を表示する (display-time)
演算子
Lisp では +, * などの演算子も関数として同じ形式で記述します。(例) 四則演算
(* 5 3) ; 15 (* 5 3 2) ; 5 * 3 * 2 = 30 (* 2 (+ 1 3)) ; 2 * (1 + 3) = 8こういった演算子を前に記述する書き方を ポーランド記法や前置法と呼びます。これに対して一般的なプログラミング言語の書き方は中置法と呼ばれています。
[中値法] 1 + 1 [前置法] (+ 1 1)この前置法はとっつきにくかったり、括弧が多くなって見づらくなったりする原因ともなります。
しかし、この記法は式、データなどを統一的に書くことができ、 慣れてくると "美しい" と感じられる書き方でもあります。 おそらく、この設定に絞った入門だと Lisp の美しさまでお伝えできないのではないかと思います。 そこは非常に残念ですが、とりあえずはこういう書き方だと思って我慢して書いていって下さい。
コードの評価(eval)方法
最初の *scratch* バッファーを使った例のように Emacs では書いた elisp の式の評価を試してみる方法が色々と用意されています。 ここでは設定に役に立つ方法を 2 つ紹介します。- C-x C-e
- ファイルのロード
C-x C-e(eval-last-sexp)
C-x C-e(eval-last-sexp) コマンドはカーソルの直前の式を評価し、 結果をミニバッファに表示します。(* 2 (+ 1 3)) ^ 1 + 3 → 4 ^ 2 * 4 → 8
ファイルのロード
Emacs では load-file という elisp ファイルをロード(読み込んで、評価)する コマンドがあります。ただ、それだとちょっと指定が面倒なので、 カレントバッファーのファイルをロードする関数を作成しました。 次のコードを init.el に記述すると [F7] キーでファイルがロードされるようになります。
(defun my-load-current-buffer-file () "Load current buffer file" (interactive) (basic-save-buffer) (load (buffer-file-name))) (add-hook 'emacs-lisp-mode-hook '(lambda () (local-set-key [f7] 'my-load-current-buffer-file)))この入門では拡張用に関数を作るところまでは踏み込みませんが、 キーの設定に関しては後で解説をしています。
elisp 編集に便利な機能
式の評価以外で elisp 編集によく使う機能も紹介しておきます。ヘルプ
設定時のヘルプとして覚えておいた方がよいコマンドは以下の 3 つでしょう。キー | 説明 |
---|---|
C-h k | キーに割り当てられたコマンドの表示 |
C-h f | 関数の説明 |
C-h v | 変数の説明 |
式、変数の補完
Emacs では式や変数の名前は途中で補完することができます。書いている途中で [M-TAB] を押してみて下さい。 補完候補が表示されると思います。
(mess[M-TAB] → (messageまた、 パッケージを使えば、 Visual Studio のように GUI で候補を表示することもできます。 こちらを使いたい場合は以前の記事を参考にしてください。
Emacs を関数電卓に!
Lisp の構文はちょっと慣れが必要です。 そこでお薦めしたいのが Emacs を関数電卓代わりに使うことです。*scratch* バッファーで評価する方法を使えば、 四則演算などの式を書いて計算させることができます。
また、理系の人は知っていると思いますが、 関数電卓は通常の電卓の機能に加えて sin, log, expt(乗数)などの数学的な関数も使えるようになっています。 elisp にもそういった数学関数が用意されています。

その他にも、プログラミングをしていると 2 進数、 16 進数などの変換をしたいことが あると思います。
elisp では #b, #o, #x を使ってそれぞれ 2, 8, 16 進数の数を表現することができ、 それを評価すると 10 進数の値が表示されます。
#b110 6 #o666 438 #xFF 255逆の変換は format 関数を使います。 ただし、 2 進数は用意されていません。
(format "%o" 9) "11" (format "%x" 15) "f" (format "%X" 15) "F"
関数定義 - 環境設定のための Emacs Lisp 入門
Emacs Lisp 入門の第 2 回目です。
今回は関数を自分で作成する方法について説明します。
defun
前回、 *scratch* バッファーを使って Emacs を関数電卓にする話をしました。 関数電卓の中には簡単な関数を自分で登録できる機能を持つものもあります。Emacs でも関数を自分でも定義することにします。 関数を定義する場合には defun を使います。
(defun NAME ARGLIST [DOCSTRING] BODY...)
(defun f (x) "3x^2 + 5x + 2" (+ (* 3 (expt x 2)) (* 5 x) 2)) ; C-j f (f 2) ; C-j 24上記の例では f が関数の「名前(NAME)」で引数(x)を一つ取ります。
引数定義の後の文字列は関数の「説明(DOCSTRING)」で C-h f でヘルプを表示した際に使われます。 この説明は省略可能です。
名前空間
Emacs では関数、変数などの名前空間は一つです。 すなわち、 defun 等で自分で定義するものは Emacs が使っている名前と被らないようする必要があります。一方、 関数の引数名はローカルなものなので、自由につけても問題はありません。
インタラクティブ関数
前節で定義した関数 f は実はコード上からしか呼び出せません。 コードからしか呼び出せないというのは M-x で呼び出したり、キーにセットして呼び出せないということです。 言い換えると関数ですが、コマンドではないと言えます。ユーザーからの呼び出しをできるようにするためには関数をインタラクティブにする必要があります。
(defun hello () "Sample command." (interactive) (message "Hello World!"))上記のコードのように (interactive) を関数の最初に書いていると インタラクティブな関数になり、 M-x hello で呼び出せるようになります。
無名関数(ラムダ式)
lambda を使うと名前のない関数(ラムダ式)を作ることができます。
(lambda (x)
(+ (* 3 (expt x 2)) (* 5 x) 2))
このままだと大して役に立ちませんが、
後で紹介するキーバインディングやホックで関数を呼び出す場合に便利です。