« 2010年12月 | メイン | 2011年03月 »

2011年01月 アーカイブ

2011年01月18日

(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で長文の一部を修正する時は便利かも知れない。

続きを読む "(Emacs) Faceを使って部分的に見た目を変える" »

(Emacs) Font Lockのルールを追加する

前のエントリーからの続きである。

Font Lock modeの追加ルールを設定するには、font-lock-add-keywordsという関数を使う。ルールは、正規表現のパターンとそれにマッチする部分に適用するface、の組み合わせとして定義する。モード毎の設定が基本だが、現在のバッファのみの設定もできる。

font-lock-add-keywords関数の書式は、

(font-lock-add-keywords モード名 ルールのリスト)
である。モード名をnilにすると、現在のバッファに対する設定になる。
ルールの書式はいくつかの種類がある。
  • a. MATCHER
  • b. (MATCHER . SUBEXP)
  • c. (MATCHER . FACENAME)
  • d. (MATCHER . HIGHLIGHTER)
  • e. (MATCHER HIGHLIGHTER1 HIGHLIGHTER2 ...)
  • f. (eval . FORM)
(参考:font-lock-add-keywordsのhelpと、Emacs LispのinfoのFont Lock ModeのSearch-based Fontificationの項)
a.とb.はfaceを指定しない場合(font-lock-keyword-faceが使われる)、c.はfaceのみを指定する場合(MATCHERにマッチする部分全体に適用される)、f.は正規表現の代わりにfaceの変更対象を検索する関数を別途定義する場合に使用するもので、a.〜c.はd.で代用でき、d.はe.で代用でき、f.は特殊なので、1つ覚えるならe.の形式が良いと思う。

HIGHLIGHTERの書式は、主に(SUBEXP FACENAME [OVERRIDE])である。SUBEXPは正規表現に()を使う場合の何番目の()の部分かの意味で、全体なら0とする。OVERRIDEは別のルールが適用済でも適用するかどうかである。

例えば、次のようにすると、java-modeの時に、TABの部分がunderline、2バイトスペースや行末の空白部分がtrailing-whitespaceというface(これらはfaces.elに定義されている)になる。

(font-lock-add-keywords 'java-mode '(
  ("\t" . 'underline)
  (" " . 'trailing-whitespace)
  ("[ \t]+$" . 'trailing-whitespace)
))
実行前

実行後

次のようにすると、java-modeに限らず、全モードで有効になる。

(defadvice font-lock-mode (before my-font-lock-mode ())
  (font-lock-add-keywords
   nil   ;現在のバッファのみ
    '(("\t" 0 'underline append)
      (" " . 'trailing-whitespace)
      ("[ \t]+$" . 'trailing-whitespace)
     )))
(ad-enable-advice 'font-lock-mode 'before 'my-font-lock-mode)
(ad-activate 'font-lock-mode)
なお、上の3行目の部分をnilでなくmajor-modeと書いている例をよく見かけるが、そのようにすると、バッファが開く度にfont-lock-add-keywordsが実行され、font-lock-keywords-alistが肥大化してしまうので、nilの方がいいと思う。


HIGHLIGHTERの書式には、他に、MATCHERがマッチした後の行末までの部分を対象に、別のパターンの検索を行う、anchoredな形式がある。
ANCHORED-MATCHERを使う場合は、HIGHLIGHTERの書式が(ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...)となる。PRE-FORMは、このANCHORED-MATCHERの検索が始まる前に実行され、POST-FORMは、行末までこのANCHORED-MATCHERが探された後に実行される。これを使うと、以下のようなことができる。

■コメント部分の特定キーワードの表示を変える
筆者は試行錯誤中のコードをコメントアウトして残す癖があり、作成中のコードには使用中のコードの3〜4倍のコードがコメントに存在することが普通にあるが、デフォルトのルールでは大体それらがコメント色1色になってしまうので、たまに痛い時がある。

(font-lock-add-keywords nil '(
 (";"
  ("face\\|frame"
   nil  ;PRE-FORM
   (goto-char (match-end 0))  ;POST-FORM: pointを";"の直後に戻す
   (0 font-lock-type-face t))
  ("default"
   nil  ;PRE-FORM
   nil  ;POST-FORM
   (0 font-lock-builtin-face t))
  )))
実行前

実行後(コメント中の"face", "frame", "default"に色が付いている)

■CやJavaの"if"の後の"="を警告表示にする

(add-hook 'c-mode-common-hook
  '(lambda ()
    (font-lock-add-keywords major-mode '(
      ("\\<if\\>"
       ("[^<>=]\\(=\\)[^=]" nil nil (1 font-lock-warning-face))
       )))
))
実行前

実行後

過去にそんなミス滅多に無いだろ、みたいなことを書いたが、筆者はExcel VBAを書いた直後だとやってしまうことに気付いた。

■"\x1b\x24\x42"〜"\x1b\x28\x42"とその間の16進数に着色する

(font-lock-add-keywords nil '(
 ("\\\\x\\(1b\\)\\\\x\\(24\\)\\\\x\\(42\\).*?\\\\x\\(1b\\)\\\\x\\(28\\)\\\\x\\(42\\)"
  (1 font-lock-function-name-face t) ;"1b"の部分
  (2 font-lock-function-name-face t) ;"24"の部分
  (3 font-lock-function-name-face t) ;"42"の部分
  (4 font-lock-constant-face t)  ;"1b"の部分
  (5 font-lock-constant-face t)  ;"28"の部分
  (6 font-lock-constant-face t)  ;"42"の部分
  ("[0-9a-f]"  ;ANCHORED
   (progn  ;PRE-FORM
    (goto-char (match-end 3)) ;3つ目の後に移動
    (match-beginning 4))  ;4つ目の先頭までに限る
   nil  ;POST-FORM
   (0 font-lock-type-face t))
)))
実行前

実行後

続きを読む "(Emacs) Font Lockのルールを追加する" »

(Emacs) Hi-lock modeを使う

前のエントリーからの続きである。

Hi-lock modeは、Font Lock modeのバッファ毎の追加ルールを手軽にインタラクティブに設定できるI/Fである。
Font Lock modeを有効にしていると、C-sで検索すると、マッチする部分がハイライト表示される。それが便利なので、ハイライト表示するためだけにいちいちC-sで検索することがあるのは筆者だけではないであろう。検索を抜けるとハイライトが解除されてしまい、またハイライトするために検索してしまう。そんな時はHi-lock modeである。

M-x highlight-regexp(既にHi-lock modeならC-x w h)を実行して、ハイライトするパターンを入力すると、マッチする箇所がハイライトされる。何かマッチすると、自動的にHi-lock modeが有効になる。もしFace Lock modeがOFFだと、自動的にFace Lock modeもONになる。

・実行前(Hi-lock modeでない)

・"x"をhighlight-regexpした状態(Hi-lock mode、mode-lineに"Hi"が追加されているのに注目)

検索パターンを単にxとするのでなく\<x\>とすると、単語の一部でなく単独で現れるxを対象にできる。
・"\<x\>"をhighlight-regexpした状態

続けてC-x w hして別のパターンをハイライトすることもできる。
・さらに"\<y\>"をhighlight-regexpした状態

C-x w l(highlight-lines-matching-regexp)を使うと、パターンを含む行全体をハイライトできる。
・さらに"draw"をhighlight-lines-matching-regexpした状態

1つのパターンのハイライトを解除するには、C-x w r(unhighlight-regexp)を実行する。全て解除するなら、M-x hi-lock-modeとしてHi-lock modeをOFFにすれば良い。

C-x w b(hi-lock-write-interactive-patterns)とすると、そのモードに定義されたコメント形式で、現在のハイライト設定が挿入される。
・上の状態から続けてhi-lock-write-interactive-patternsを実行した状態

c-modeなら、/*〜*/で括られたものが挿入される。これを残しておくと、次にこのファイルでHi-lock modeがONになった時に同じハイライトがなされる。

ハイライトを解除した後で、コメントに書かれたHi-lock設定を読み込むには、C-x w i(hi-lock-find-patterns)とする。

コメント形式のHi-lock設定はFont Lock modeのルールと同じなので、これを書き換えると、結構複雑な設定も書ける。
・"draw"のルールを書き換え中("draw_に続く単語を赤太字、"draw_"より後ろの"r"をピンクでハイライトするつもり)

・C-x w i(hi-lock-find-patterns)を実行した状態

続きを読む "(Emacs) Hi-lock modeを使う" »

About 2011年01月

2011年01月にブログ「Weblog on mebius.tokaichiba.jp」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2010年12月です。

次のアーカイブは2011年03月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35