Emacsでオレオレ言語やオレオレフォーマットにシンタックスハイライトを

#はじめに
これは香川大学工学部サークルSLP(学生プログラミング研究所)の[アドベントカレンダー](https://adventar.org/calendars/2492) 2日目の記事です。1日目の先輩に微力ながら対抗してみます。
サークル生やOBのみなさんが記事を書いて繋いで行きますので、他の記事も是非目を通していただければと思います。
では本題へ。よく話が長いと言われる私なので、頑張ってテンポよく行きたいと思います。

#事の発端
[1日目の記事](http://maxmellon.hateblo.jp/entry/2017/11/30/204604)を見ていただけるとわかるのですが、私たちのサークルなどでは不思議なフォーマット(以下tmng-format)で議事録やらなんやらを書くというルールがあります。この記事の後半で紹介されている[vim-tmng](https://github.com/TomiLabo/vim-tmng)には、tmng-formatのテキストに対してシンタックスハイライトしてくれる機能があります。
色がつくと見やすい、書きやすいというのは、プログラミングでも同じです。
ただし、このplug-in、1つだけ大きな問題があります。それはVim plug-inであるということです。私にはVimは難しすぎる...

この機能使いたい！でもこれってVimでしか動かないじゃん！私はVim使えない！じゃあemacs-tmngを作ろう！
というわけですね。

#Emacs
有名なテキストエディタですね。環境とかって言われることもありますが。
多分この記事を読んでいる方は知ってると思いますので、さっさと次に行きましょう！

#Emacs Lisp
Emacsの実装で使用されているプログラミング言語です。名前の通り、Lispの仲間みたいなものですね。Elispとも呼ばれたりしますが、emacsのカスタマイズをする時にも使用します。.emacsとか.emacs.elとかinit.elとかってファイルを編集したことがあると思います。

ちなみに、私はinit.el以外で書いた(コピペ)ことはなかったですし、そもそも関数型すら...
なので今回の記事も、間違ってるところがあれば指摘していただけると嬉しいです。

#emacs-tmng.elを作成
下の方に今回のコードを載せて簡単に説明していきます。
EmacsにはModeというものがあります。これを切り替えることで、言語などに応じた操作、シンタックスハイライトなどを提供しています。c-modeとかorg-modeとかがそうですね。
今回はtmng-format用のMajor Modeとしてtmng-modeというものを実装してシンタックスハイライトをつけます。
テンプレ的というか、このあたりはかなり決まった形式があるみたいですね。
適当にコメントアウトで補足してますが、基本的には名前modeの名前である"オレオレ-mode"にすればいいと思います。

そして、大事な部分であるsyntax-tableとハイライトしたい単語の指定です。
`tmng-mode-syntax-table`という関数で構文の設定をします。
私はとりあえず色がつけばいいやと思っていたので、syntax-tableは少ししか書いていませんが...
多分単語の区切りとか構文の区切りを設定するものだろうとなんとなく思ってます。

次に、`tmng-mode-font-lock-keywords`という関数を作って、シンタックスハイライトの設定をします。これは以下のように複数に分けて書くこともできます。今回の書き方だと、`tmng-mode-font-lock-keywords-2`に対して、`tmng-mode-font-lock-keywords-1`をappendして、`tmng-mode-font-lock-keywords-2`を登録しているという感じですね。
elispの正規表現は "\" の数がえげつないですね...

ちなみに、どれかの正規表現に該当した部分は、それ以降別の正規表現に該当しても、その部分だけ上書きみたいなことができない？みたいです。リージョンで指定して上書きみたいな機能があるとできるのかなと思うんですが...
なので、複数該当する可能性がある場合は順番を意識する必要がありそうです。

最後に読み込む名前を指定したら完成です。
あとは、init.elなどの設定ファイルから読み込む設定をです。

```el:emacs-tmng.el
(defun tmng-mode ()
  "Tmng Mode"
  (interactive)    ; M-x tmng-mode RET で呼び出せるようにする
  (kill-all-local-variables)    ; これまでのmodeの状態を綺麗に
  (setq mode-name "tmng-mode")    ; Emacs上に表示される名前
  (setq major-mode 'tmng-mode)    ; 現在のModeの設定
  (set-syntax-table tmng-mode-syntax-table)    ; syntax-tableの登録
  ; デフォルトのハイライトリストにtmng-mode-font-lock-keywords-2を追加 
  (set (make-local-variable 'font-lock-defaults) '(tmng-mode-font-lock-keywords-2))
  (run-hooks 'tmng-mode-hook))

(defvar tmng-mode-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?# "<" st)
    (modify-syntax-entry ?\n ">" st)
    st)
  "Syntax table for `tmng-mode'.")

;--色をつける部分の正規表現と指定する色の種類
(defconst tmng-mode-font-lock-keywords-1
  	  (list
	   '("[0-9]\\{4\\}\\.[0-9]\\{2\\}\\.[0-9]\\{2\\}(\\(月\\|火\\|水\\|木\\|金\\|土\\|日\\|__\\))" . font-lock-function-name-face)
	   '("[0-9]\\{2\\}\\.[0-9]\\{2\\}(\\(月\\|火\\|水\\|木\\|金\\|土\\|日\\|__\\))" . font-lock-function-name-face)
	   '("[0-9]\\{2\\}:[0-9]\\{2\\}-[0-9]\\{2\\}:[0-9]\\{2\\}" . font-lock-function-name-face)
	   '("(.*)" . font-lock-variable-name-face)
	   '("{.*}" . font-lock-variable-name-face)
	   '("<.*>" . font-lock-variable-name-face)
	   '("\\[.*\\]" . font-lock-variable-name-face)
	   )
	  "highlighting1 for Tmng mode")


(defconst tmng-mode-font-lock-keywords-2
  (append tmng-mode-font-lock-keywords-1
	  (list
	   '("\\(月例発表\\)" . font-lock-warning-face)
	   '("\\(定例会合\\|個人作業\\|委託業務\\|定例活動\\|週間予定\\|個人報告\\|週直担当\\|研究会合\\)" . font-lock-keyword-face)
	   '("\\(■\\|□\\|●\\|◎\\|○\\).*" . font-lock-string-face)
	   '("\\(■\\|□\\|●\\|◎\\|○\\)" . font-lock-string-face)
	   ))
  "highlighting2 for Tmng mode")


(provide 'emacs-tmng)    ; 読み込む名前
```

#設定ファイルに自作のMajor Modeを読み込むための設定
先ほど作ったファイルを読み込むために以下を追加します。

やっていることは、1行目でファイルを置いている場所にパスを通します。
パスが通っているところでないと、作成したファイルを読み込めません。
最後に読み込みたいファイルの最後に書いた`(provide 'emacs-tmng)`の名前の部分をrequireしたら完了です。
`M-x tmng-mode RET`で作成したMajor-Modeの起動ができると思います。

```el:init.el
(add-to-load-path "~/.emacs.d/elisp")
(require 'emacs-tmng)
```

#まとめ
色が着くだけで、なんとなく楽しい気持ちになりますし、普段楽しくないことが、少しでも楽に楽しくなればいいなと思います。

初めてまともに書こうとしたけど、Emacs Lisp 難しい...
急がないけど、もうちょっと書けるようになりたい...
あと、括弧が括弧で括弧なので対応する括弧にいい感じに色をつけてくれる[rainbow-delimiters](https://github.com/Fanael/rainbow-delimiters)がすごくいい。