lambda consulting

俺、ちゃんと全部管理してます(org-modeでinit.elを管理する)

November 20, 2015

Emacs

init.el(昔で言うところの.emacs)で管理していたEmacsの設定をorg-modeで管理する方法について。

init.elでありがちな問題

まず、init.elだけで管理する場合に問題になるのは:

結果的に、「よくこれで動いてるなあ。。」と不安なファイルになるのだが、毎日それに依存して生きていかなければならない。

数年毎に訪れる「俺、生まれ変わろう」という衝動により、init.elへの大胆な外科手術を行うのだが、半分以上の行が無くなってしまい、「なんか前と挙動が違うけど、気にするな!」と自分を諭しながら、強制的に生まれ変わる。

そんな、無駄な生まれ変わりを繰り返してきてしまったが、ご長寿Emacsには、これからもお世話になる予定なので、自分の設定もマネージブルにしたい。そこで、この問題を解決できる(かもしれない)のが、おなじみの org-mode である。

org-modeにするといいところ

詳しくは述べないが、とにかくorg-modeは、すごい。「いったいお前の目的は何なんだ?」と言うくらい、いろんなことができてしまう。まあ、そもそもEmacs自体がそういうヤツだ (そうだお前は最高だ! Atomが何だ! vimなんぞ来世でも敵じゃ! と必死に言い聞かせてEmacsを使い続ける。。)

とはいえ、org-modeのすごいところは、その基本機能である(折り畳み式)アウトライン機能だ。そして、コードブロックを内包することもできる。すると:

と、言葉だけでは、伝わらないかもしれないが、すごくいい。なんといっても、精神的にいい。
どういう風に塊に分けるかが大きな問題だが、それを試行錯誤していくためにも、init.elで管理するより、init.orgで管理する方がよいと思う。

init.orgでの管理方法(org-modeでのEmacs設定)

(1) init.el

org-modeで管理するので、設定内容の本体は、init.orgで記述することになる。しかし、起動時にEmacsが直接org-modeのファイルを解釈できないので、init.elには、「init.orgを解釈してくれ!」という内容を記述する。

(require 'org-install)
(defvar my-config-dir (concat user-emacs-directory "my-config/"))
(org-babel-load-file (expand-file-name "init.org" my-config-dir))

3行目が実行されると、init.org内のコードブロックだけを抜き出した、init.elが、同じディレクトリ(~/.emacs.d/my-config/)に作成される。

my-configとかディレクトリを作らずに、init.elと同じ~/.emacs.d/にorgファイルを配置したい場合は、コードブロック抽出後のファイル名が、元のinit.elと衝突するので、init.orgというファイル名は使えない。my-init.orgなど適宜別名にする必要がある。

~/.emacs.d/init.elに、上記以外の設定を書いても良いが、意味があるとは思えない。なので、init.elの内容は、上記の3行のみ。

(2) init.org

org-modeでは、行頭の*でアウトラインを表現できる(塊がつくれる)。また、行頭の*の数(MAX:6)でレベルを定義できる。
なので、例えば:

#+TITLE: Emacsの設定
#+STARTUP: overview
* 基本設定
** 言語設定
** 画面表示
*** フレーム関連
*** バッファ関連
** キーバインディング
* ユーティリティー
** DICT
** DDSKK
** yasnipet
** MEW
* プログラミング
** web-mode
** ruby-mode
** python-mode
...

という感じで自分の管理したい単位で項目を階層化していく(レベルは、簡単に上にも下にも変えられるので、あまり気にしなくていい。はじめは、とにかく、やみくもにでも前に進むことが重要)。すると、それぞれの行で<TAB>することにより、展開/収縮がトグルできる。

ちなみに、1行目と2行目は、org-modeへのOPTIONだが、2行目のSTARTUPに、overviewを指定しているため、ファイルを開いた際の初期表示は、*が1つの行だけに収縮された状態で表示される。その後、自分のみたいところを<TAB>で展開していく流れになる。(これらのOPTIONは、いらなければ、なくてもいい。)

どのレベル(*の数)でも構わないので、その下に設定内容を書くことにしたい場合、次のようにする。

#+BEGIN_SRC emacs-lisp
  ;; ここに設定コード(elisp)を書く
#+END_SRC

たとえば、こんな感じ:

** キーバインディング
  *** シェルと同様に C-h は直前の文字を削除
    #+BEGIN_SRC emacs-lisp
      (global-set-key (kbd "C-h") 'delete-backward-char)
    #+END_SRC
  *** F7 で行の折り返し表示を切り換え
    #+BEGIN_SRC emacs-lisp
      (global-set-key (kbd "<f7>") 'toggle-truncate-lines)
    #+END_SRC

この例では、ひとつのコードブロックに1文しか書いていないが、好みで塊の大きさを決めていけばいい。
尚、この例では、まったくシンタックスハイライト(色付け)されていないが、Emacs上では、org-modeのアウトラインも、elispのコードブロックも適切に色付けされるので、かなり見やすい。

後は、Emacs起動時に、コードブロックを抜き出して、解釈してくれるので、構造上は以上なのだが、init.orgを編集していく際の編集方法をいくつか。

コードブロックの挿入

コードブロックを挿入したい場合は、<s とタイプしてから、<TAB>で、#+BEGGIN_SRC…#+END_SRCへ展開してくれる。
但し、emacs-lispだけは、自分でタイプする必要がある。(それも面倒なら、yasnipetで)

<s (ここで<TAB>すると、、)
以下に展開される
#+BEGIN_SRC

#+END_SRC

コードの記述(これ最高!)

コードブロックの中にelispで設定内容を書けばいいのだが、このまま書いてもインデントされないし、対応する括弧も教えてくれない。。特に複数行あると、elispではかなりきついし、5,6行超えたら、もうアウト。。

そこで、コードブロックの中にいるときに、

すると、当該バッファは閉じられ、init.orgにもどる。もちろん、コードはきれいに反映されている。
設定をorg-modeにする際に、「これは失敗か。。」と少し不安になりかけたば、この機能があることを知ると「うお、こりゃええ、」と流れが変わった。