font-lock-studio 20170127.1251(in MELPA)
interactive debugger for Font Lock keywords.

概要

Emacsには font-lock という、テキスト色付け機能があります。

各言語のソースコードに自動的に適切な色がつくのは、
font-lockが働いているからです。

その設定は変数 font-lock-keywords でするのですが、
これが難しいこと難しいこと…

正規表現ベースで色付けしようにも、Emacsの正規表現自体が
「可読性などいらん!」
とばかりに腐敗しきってるので、これまた難しいです。

正規表現を作るするには rx マクロとか
M-x re-builder が便利ですが、
出来上がった正規表現は読めたものではありません。

正直、俺も何も見ずにfont-lock-keywordsは書けません(笑)

僕は新しい言語のメジャーモードを書くことなどないので、
既存のfont-lock-keywordsをパクったり改造するのが精一杯です。

font-lockは魔境というくらい
デバッグはとても難しいです。

そこで、font-lockがどのような挙動をするのか 見える化 するのが、
font-lock-studio.el です。

インストール

パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。

(package-initialize)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "http://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")))

初めてfont-lock-studioを使う方は
以下のコマンドを実行します。

M-x package-install font-lock-studio

アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。

M-x package-install package-utils (初めてアップグレードする場合のみ)
M-x package-utils-upgrade-by-name font-lock-studio

使い方

設定なしでM-x font-lock-studioを実行します。

ここではhtml-modeの例にしますが、
実行後は以下のようなバッファができます。

    ========================
    === Font Lock Studio ===
    ========================
--------------------------------------------------
"<\\([!?][_:[:alpha:]][-_.:[:alnum:]]*\\)"
  (1 font-lock-keyword-face)
--------------------------------------------------
"</?\\([_[:alpha:]][-_.[:alnum:]]*\\)\\(?::\\([_:[:alpha:]][-_.:[:alnum:]]*\\)\\)?"
  (1
   (if
       (match-end 2)
       sgml-namespace-face font-lock-function-name-face))
  (2 font-lock-function-name-face nil t)
--------------------------------------------------
"\\(?:^\\|[ \t]\\)\\([_[:alpha:]][-_.[:alnum:]]*\\)\\(?::\\([_:[:alpha:]][-_.:[:alnum:]]*\\)\\)?=[\"']"
  (1
   (if
       (match-end 2)
       sgml-namespace-face font-lock-variable-name-face))
  (2 font-lock-variable-name-face nil t)
--------------------------------------------------
"[&%][_:[:alpha:]][-_.:[:alnum:]]*;?"
  (0 font-lock-variable-name-face)
--------------------------------------------------
"<\\(b\\(?:ig\\|link\\)\\|cite\\|em\\|h[1-6]\\|rev\\|s\\(?:mall\\|trong\\)\\|t\\(?:itle\\|t\\)\\|var\\|[bisu]\\)\\([ \t][^>]*\\)?>\\([^<]+\\)</\\1>"
  (3
   (cdr
    (assoc-string
     (match-string 1)
     sgml-tag-face-alist t))
   prepend)
==================================================
Public state:
  Debug on error     : NO
  Debug on quit      : NO
  Explain rules      : YES
  Show compiled code : NO

このようにfont-lock-keywordsの内容をひとつひとつ
分解しています。

あとはSPCを押し続けていくと、次々とマッチ部分がわかります。

20150114065836.png
Fig1: M-x font-lock-studio起動直後

20150114065843.png
Fig2: SPCを押すとどの設定がマッチしているかを表示

20150114065854.png
Fig3: どんどんSPCを押していくとタグにマッチ

20150114065917.png
Fig4: 要素にマッチ

20150114065942.png
Fig5: 重要な部分にアンダーラインが引かれるところにマッチ

bでブレークポイント、
gで終了まで実行、
nで次の設定
というふうに、デバッガとして標準的な操作方法が使えます。

aで最初からやり直し、
qで終了します。

他にもfont-lock関係の関数を edebug にかけることもできたりします。

?で使えるコマンドの一覧が出てきます。


本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。