init.elのスリム化を目指す (Part2)

# はじめに

これは[.emacs Advent Calendar 2016](http://qiita.com/advent-calendar/2016/dot-emacs)の21日目の記事です。
`init-loader.el`の採用とその後について書いています。

> `init-loader.el`は分割されたEmacsの設定ファイルを、
> ファイル名の命名規則に従い、Emacsの起動時に読み込み、
> 設定を反映してくれるパッケージです。

昨年の.emacs Advent Calendar 2015では、[init.elのスリム化を目指す](http://qiita.com/hiroakit/items/2199ade2e93d162b118b)ということで
init-loader.elを採用して、init.el (Emacsの設定ファイル) のスリム化を図りました。

しかし、私は増加した設定ファイルの管理が億劫になり、Emacsの設定が面倒に感じるようになりました。
これは致命的であります。

そこで、私は設定をファイル分割せず、`init.el`にまとめるという方針に変更しました。
工夫としては、自作関数を書いて、`after-init-hook`や`emacs-startup-hook`で読み込むというものです。

# init-loaderの再考

`init-loader.el`を使うと以下の利点を得られます。

- Emacsの設定を読み込む順番をコントロールできる
- Emacsの設定を目的毎に用意したelispファイルに記述できる

これらの点は、elispの書き方がイマイチわからなかった当時の私にとっては、とても魅力でした。
ただ、Emacsを使う人の嗜好によっては、以下の点に遭遇するでしょう。

> 1. ファイルのロード順の変更がめんどい (ファイルのリネームが必要)
> 2. 設定変更時に別ファイルを開き直すのがめんどい
> 3. 連番の管理や「帯域1」の記憶がめんどい
> 4. 複数の言語やパッケージにまたがる設定をどこに書くか悩みが生じる
> 5. 設定の加除によって「コメントしかないファイル」が生まれる
>
> [init-loaderって必要なの? ほんとに? - Qiita](http://qiita.com/tadsan/items/181a352edcda740582ec)

私は上記のすべてに当てはまります。
設定を複数のファイルに別けたことで、面倒になっていたのです。

さて、どうしたものか。

# 何をしたか

init-loader.elをやめ、分散していた設定ファイルをinit.elにまとめました。
私はinit.elを以下のように書き換えています。下記は例です。

```lang:init.el
(add-hook 'after-init-hook
          (lambda ()                    
            ;; load-pathを設定する.
            (hp-load-load-path-config)
            :
            :
            :
            ))

(add-hook 'emacs-startup-hook
          (lambda ()
            ;; helmに関する設定を読み込む.
            (hp-load-helm-config)
            
            ;; org-modeに関する設定を読み込む. 
            (hp-load-org-mode-config)
            :
            :
            :
            ))                                                  

(defun hp-load-load-path-config ()
  :
  :
  :
  )

(defun hp-load-helm-config ()
  :
  :
  :
  )

(defun hp-load-org-mode-config ()
  :
  :
  :
  )
```

上記の例だと、org-modeの設定を読み込みたくない場合は、`(hp-load-org-mode-config)`をコメントアウトします。
また、org-modeの設定をhelm-modeよりも前に読み込みたい場合は、記述順序をその通りにします。

## init.elの動き

下記のinit.elで初期化動きを確認してみます。

```lang:init.el
(message "loading init.el, start")

(add-hook 'after-init-hook
          (lambda ()                    
            (message "run after-init-hook")))

(add-hook 'emacs-startup-hook
          (lambda ()                    
            (message "run emacs-startup-hook")))

(message "loading init.el, end")
```

上記のelispを読み込むと、以下の順序でEmacsはmessageを出力します。

1. loading init.el, start
2. loading init.el, end
3. run after-init-hook
4. run emacs-startup-hook

ということは、`add-hook`する後に自作の関数を書いても問題なさそうです。

```lang:init.el
(message "loading init.el, start")

(add-hook 'after-init-hook
          (lambda ()                    
            (message "run after-init-hook")
            (run my-function)))

(add-hook 'emacs-startup-hook
          (lambda ()                    
            (message "run emacs-startup-hook")))

(defun my-function ()
  (message "run my-function"))

(message "loading init.el, end")
```

上記のelispを読み込むと、以下の順序でEmacsはmessageを出力します。

1. loading init.el, start
2. loading init.el, end
3. run after-init-hook
4. run my-function
5. run emacs-startup-hook

ということは、`add-hook`を使えば、`init-loader.el`で魅力に思っていた以下の点を維持できそうです。

- Emacsの設定を読み込む順番をコントロールできる
- Emacsの設定を目的毎に用意したelispファイルに記述できる

なので、以下の方法で設定をいじりやすくなりました。

1. add-hook内で呼ぶ関数の記述順序を変えれば、設定の読み込み順序を変更できる
2. add-hook内で呼んでいる関数をコメントアウトすれば、その設定を読み込まないようにできる


# まとめ

以上の通り、Emacsの設定は分散して書くのではなく、init.elにまとめて書くスタイルに変更しました。
このスタイルではinit.elの行数は増えますが、以下のメリットがあります。

- どのファイルに何を書いたのか把握しておく必要がない
- 仮に設定の変更が必要な場合は、init.elで検索(helm-swoopなど)をして該当箇所に移動すれば良い

皆様がご存知の通り、Emacsはスマートフォン、タブレットと同様に生活必需品の1つであります。
本エントリーが読者様のEmacsライフに少しでもお役に立てれば幸いです。