魔法使いの弟子

いつか私もあなたみたいに

emacsのinit.elが長くなってきたあなたへ ~ org-babelを使った管理方法

この記事では⬇️こんな感じに記述量が長くなり設定の確認、修正がしづらくなってきたemacsの設定ファイルを

f:id:aoba17:20190707164349p:plain

⬇️こんな感じにするための方法を紹介します。(設定の記述を折りたたんで必要な時だけ展開できるようにしている。)

f:id:aoba17:20190707201221p:plain

これを実現するためには、emacsにOrgというパッケージを追加する必要があります。 Orgは元々の機能はemacs上でメモや書類を作成するためのパッケージです。 markdown的な書き方ができて、文章などを入れ子構造で書くことができます。 入れ子になっている場合、子要素を折りたたんで隠したり、展開して表示したりといったことが可能です。

察しの良い方はもうお分かりでしょう。ここからはinit.elでずらずらと書いていた設定を Orgのファイルに移管するための手順を3つのステップに分けて説明します。

STEP1 Orgのインストール

まず、Orgをインストールします。 すでにインストール済みの方はこのステップはスキップ。

公式サイトにパッケージリポジトリからのインストール方法が記載されています。

orgmode.org

一応、必要な設定とコマンドは転載しておきます。

(require 'package)
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)

M-x package-install RET org RET

今回はemacsの設定のために使うOrgですがこのパッケージの機能は多岐に渡り、使い方は人それぞれです。 メモ、課題管理、文書作成などの方法が気になる方はググってください。

STEP2 init.elでのorg-babelの設定

STEP1でOrgのインストールが完了しました。 拡張子が".org"というファイルをemacs上で開くとそのバッファのメジャーモードはorg-modeになっているはずです。 (このようなファイルをこれからの説明でOrgファイルと呼びます。)

次のステップに説明の前に、org-babelついて少し知っておく必要があります。 org-babelというのはOrgに備わっている機能の一つで、Orgファイル内にソースコードを記載するためのコードブロックを用意できるようにするものです。 コードブロック内に記載されたコードは所定の方法で実行することができます。 Emacs lispにかぎらず、RubyやR言語などいろんな言語をコードブロック内に書けるらしいです。

org-babelについてなんとなくわかったところで、Orgファイルに記載したEmacs Lispのソースコードを emacs起動時(またはinit.el読み込み時)にロードして設定を読み込むための設定をしましょう。

init.elがあるディレクトリにconfigという名前のディレクトリを作り、その中のconfig.orgというファイルに emacsの設定を書き込みたいときは以下の設定をinit.elを追記してください。

;; Orgファイルからの設定読み込み
(org-babel-load-file (expand-file-name
                      "config.org"
                      (concat user-emacs-directory
                              "config/")))

org-babel-load-file というメソッドは引数として与えられたファイルのEmacs Lispソースコードの読み込みをしてくれる関数です。 expand-file-nameは絶対パス指定のパスネームを作成するための関数です。user-emacs-directoryは通常init.elが置いてあるディレクトリです。

config.orgが空のファイルだったりすると上記の設定を読み込んだときにエラーが出てしまうので、次のステップに進みましょう。

STEP3 Orgファイルへのemacs lispの書き込み

config.orgにコードブロックを作りその中に設定をちょっとだけ移動してみましょう。

記載例は以下の通りです。

* 共通設定
** C-hで文字削除
   #+BEGIN_SRC emacs-lisp
   (keyboard-translate ?\C-h ?\C-?)
   #+END_SRC
* パッケージ設定
** neotree
   #+BEGIN_SRC emacs-lisp
   (use-package neotree
   :bind (("C-q" . neotree-toggle))
   :config
   (setq neo-show-hidden-files t)
   (setq neo-theme (if (display-graphic-p) 'icons 'arrow)))
   #+END_SRC

これは私のemacsの設定なのでそのまま貼り付けるのはオススメしません。 ご自身の設定に置き換えてください。

Orgファイル編集中は、Emacs Lisp編集のためのメジャーモードになっていないため、 インデントなどがうまくいきません。 そんなときは、コードブロックの中にカーソルを合わせて C-c ' を押すと、 ソースコード編集用のバッファが開かれますのでそこで編集するのがいいと思います。

その際、STEP2で書いた設定は持ってきてはいけません。 (また、custom-set-variablesなど自分で書いたわけではなく、emacsが生成している部分も私はそのままinit.elに残しています。)

"*"とか"**"は見出しを作るためのOrgモードの書式です。アスタリスクが多い方が入れ子構造の子要素になります。

emacs上では⬇️のように表示されています。

画像

Orgファイルに書き込んだ設定はinit.elでコメントアウトし、init.elを読み込んでみてその設定が期待通り動いていたら成功です。

大事なのは

#+BEGIN_SRC emacs-lisp
#+END_SRC

このコードブロックの中にEmacs Lispを書き込むというルールを守っていれば、 その外側がどんな構成になっていても構わないということです。

もっと深い入れ子構造にしてもいいし、Orgの書式を利用しTODOリストを書き残しておいたり、 補足情報をメモったりできます。

ちなみに、init.elが読み込まれる際にOrgファイルと同じディレクトリにOrgファイルからEmacs Lispの部分だけを抜き出したファイルが自動生成されるので、これまで通り .el ファイルでの確認もできます。