(Emacs) Faceを使って部分的に見た目を変える

Emacsのfaceとは、フォント名や太字/斜体/下線といったフォント属性や文字色といったフォント設定をまとめたものであり、バッファ内のテキストの一部分に適用する事ができる。Emacsでソースコードを開くと、予約語やコメント部分や文字列部分に色が付くが、これは、そういう色で文字を表示するというfaceがそれぞれ定義されており、それらの部分にそれぞれのfaceが適用されている状態である。

Emacsでフォントの設定をしていると、時々faceという単語が出てくる。意味がわからないままでもフォントの設定はできたが、特にX resourcesでフォントセットの定義をすると、何に使われるのかわからなくても、default, bold, italic, bold-italicの4つ分を定義させられる。これらのフォントも、テキストにそういうfaceが適用されると使用されるが、そういうfaceが適用されないと、使われる事がない。
筆者はC, Java, Perl, Pythonなどのプログラム言語のソースコードをEmacsで開くことがあるが、キーワードや特定パターンに色が付くのはよく見るが、太字や斜体になるのは滅多に見ない。目にするのは、helpやinfoを開いた時くらいである。最も多く編集するのはテキストファイルであるが、text-modeでは色も付かない。

せっかく設定したものがほとんど使われず、しかもどうやれば使えるのかがわからないのは、気になる。そこで、faceの使い方を少し調べることにした。


Emacsで開いているテキストの一部分のfaceを変える方法としては、主に
・facemenu-*関数を使う
・Font Lock modeを使う
・Hi-lock modeを使う
・Highlight Changes modeを使う
がある。他にも、Emacs23ならtext-scale-*関数があったり、色々あるようであるが、Emacs22のinfoですぐ見つかるのはこれくらいである。(10年くらい前にEmacsを使っていた時はhilit19.elというのにお世話になったが、今ではobsoleteのようである)


■facemenu.elを使う
範囲選択してfacemenu-set-*関数を実行すれば、その範囲にfaceを適用できる。

これは、Carbon Emacs 22.3で3文字ずつM-o o(facemenu-set-face)してみた例である。適用したfaceは順に、highlight, lazy-highlight, link, match, query-replace, custom-button, custom-button-pressed, custom-face-tagである。加えて、"abc"はM-o bでboldに、"def"はM-o iでitalicにしてある。


これは、後述のfacify-iroha-regionマクロで、1文字ずつ異なるfaceを適用してみたものである。

キャラクターベースのリモート端末でも、これくらいカラフルになる。

(EmacsはDebianのemacs21-nox、ターミナルソフトはPuTTY、設定はほぼvt100のdefault)

しかし、Font Lock modeがONになっていると使えない。昨今のPCの性能では、もはやFont Lock modeをOFFにして使用することは少ないと思うので、あまり使えなさそうである。
また、これによって設定されたfaceはバッファローカルであり、編集したテキストと共に保存される訳ではないので、あまりこれによるテキスト装飾を手作業でがんばる意味は無い。失われることを前提に一時的に装飾するのに使うものである。
ただ、上のようにマクロで好き勝手に装飾したい時は、使えそうである。


■font-lock-mode.elを使う
何らかのソースコードを開いて自動的に色が付くなら、まず間違いなく、Font Lock modeが有効になっている。予め設定されたルールに従って自動的にfaceが適用されるモードである。
大体、c-modeとかperl-modeとかの言語毎のモードに入ると、自動的にその言語特有のルールが追加される。
有効でない場合は、.emacs等に

(global-font-lock-mode t)
と書けば有効になる。

追加ルールの設定については、長くなったので、次のエントリーに書く。


■Hi-hock modeを使う
長くなったので、次の次のエントリーに書く。


■Highlight Changes modeを使う
変更部分に自動的にfaceが適用されるモードである。ファイルを開いてからM-x highlight-changes-modeとするか、.emacs等に

(global-highlight-changes 1)
と書くと有効になる。

次の画像は、テキストファイルの編集にHighlight Changes modeを使った画面の例である。

黒以外の部分が、M-x highlight-changes-modeを実行してから変更した部分である。色違いは、highlight-changes-rotate-facesで世代を切り替えたものである。
highlight-changes-previous-changeやhighlight-changes-next-change等の関数を使うと、前の変更部分や次の変更部分にジャンプできるようである。
facemenu.elを使った場合と同様、これによる色はファイルに保存される訳ではない。

保存されていない変更があるかどうかはmode lineの**でわかるし、変更履歴として保存される訳でもないので、使い所が難しい気がする。Font Lock modeを使っていると、編集中の部分に本来の着色がされなくなり、スペルミスの点検ができなくなったりするので、却って不便である。Font Lock modeの効果が少ないText modeで長文の一部を修正する時は便利かも知れない。


■定義されているfaceを一覧表示する方法
M-x list-faces-display
とすれば、そのfaceで表示したサンプルと共に出てくる。
screen sample

キャラクターベースの端末画面で実行すると、default faceと文字色、背景色、太字/下線が違うfaceはあるが、異なるフォントやitalicが表示されるfaceは無いことが多い。おそらく、vt100に明示的にイタリック体を表すエスケープシーケンスが無いからだろう(強調や下線はある、太字が表示されるなら強調の対応している)。これがitalicのfaceがあまり使われない理由なのだと思う。

■facemenu-set-faceで1文字ずつ異なるfaceにするマクロ

(defun facify-iroha-region(beg end)
(interactive "r")
(font-lock-mode 0) ;Font Lock modeをOFFにする
(let ((faces (face-list))) ;定義されている全てのface
(while (< beg end)
(if (= (char-after beg) ?\n) nil
(facemenu-set-face (car faces) beg (+ beg 1)) ;facesの先頭を使用
(setq faces (cdr faces))) ;facesの先頭を除去
(setq beg (+ beg 1)))))