| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
モード(mode)とは、Emacsをカスタマイズする定義の集まりであり、 読者は編集中にそれをオン/オフできます。 モードには2種類あります。 メジャーモード(major mode)は、互いに排他的で、 特定種類のテキストの編集に使います。 マイナモード(minor mode)は、 ユーザーがそれぞれを独立にオンにできる機能を提供します。
本章では、メジャーモードやマイナモードの書き方、 それらをモード行に表示する方法、 ユーザーが指定したフックをモードがどのように実行するかについて述べます。 キーマップや構文テーブルなどの関連事項については、 21. キーマップや34. 構文テーブルを参照してください。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
メジャーモードは、特定種類のテキストの編集向けにEmacsを特化します。 各バッファには、ある時点では1つのメジャーモードしかありません。
もっとも特化されていないメジャーモードは、 基本(fundamental)モードです。 このモードには、モードに固有な定義や変数の設定がありません。 そのため、Emacsの各コマンドはデフォルトのふるまいをし、 各オプションもデフォルトの状態です。 他のすべてのメジャーモードでは、さまざまなキーやオプションを再定義します。 たとえば、lisp対話モードでは、 C-j(eval-print-last-sexp)や TAB(lisp-indent-line)など他のキーに対しても 特別なキーバインディングがあります。
読者の特別な編集作業を補佐するために一群の編集コマンドを書く必要がある場合、 新たなメジャーモードを作ることは一般にはよいことです。 実際、メジャーモードを書くことは (マイナモードを書くことはしばしば難しくなるが、 それに対比すれば)簡単です。
新たなモードが既存のモードに類似していても、 既存のモードを2つの目的を果たすように修正するのは 賢いことではありません。 そのようにすると、使い難く保守し難くなるからです。 そのかわりに、既存のメジャーモードの定義をコピーし名前変えてから、 コピーを変更します。 あるいは、派生モード (derived mode) (see 節 22.1.5 派生モードの定義)を定義します。 たとえば、`emacs/lisp/rmailedit.el'にあるrmail編集モードは、 テキスト(text)モードに非常によく似たメジャーモードですが、 追加コマンドが3つあります。 そのような定義がテキスト(text)モードとの違いになるのですが、 rmail編集モードはテキスト(text)モードから派生したものです。
rmail編集モードは、バッファのメジャーモードを一時的に変更して バッファを別の方法(rmailのコマンドではなく Emacsの普通のコマンド)で編集できるようにする例題です。 そのような場合、一時的なメジャーモードには、普通、 バッファの通常のモード(この場合にはrmailモード)に戻る コマンドがあります。 読者は、再帰編集の中で一時的に再定義し、 ユーザーが再帰編集を抜けるともとに戻す方法に魅了されるかもしれません。 しかし、これを複数のバッファで行うと、 再帰編集はもっとも最近に入った再帰からまず抜けるので、 ユーザーの選択に制約を課すことになり悪い方法です。 別のメジャーモードを使えばこのような制約を回避できます。 See 節 20.11 再帰編集。
標準のGNU Emacs Lispのライブラリのディレクトリには、 `text-mode.el'、`texinfo.el'、`lisp-mode.el'、 `c-mode.el'、`rmail.el'などのファイルに いくつかのメジャーモードのコードが収めてあります。 モードの書き方を理解するためにこれらのライブラリを調べられます。 テキスト(text)モードは、基本(fundamental)モードについで、 もっとも単純なメジャーモードです。 rmailモードは複雑な特化されたモードです。
22.1.1 メジャーモードの慣習 Coding conventions for keymaps, etc. 22.1.2 メジャーモードの例 Text mode and Lisp modes. 22.1.3 メジャーモードの選択方法 How Emacs chooses the major mode automatically. 22.1.4 メジャーモードに関するヘルプ Finding out how to use a mode. 22.1.5 派生モードの定義 Defining a new major mode based on another major mode.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
既存のメジャーモードのコードでは、 ローカルキーマップや構文テーブルの初期化、グローバルな名前、フックなどの さまざまなコーディング上の慣習を踏襲しています。 読者が新たなメジャーモードを定義するときには、 これらの慣習に従ってください。
describe-mode)を使うと、 この説明文字列を表示する。
説明文字列では、`\[command]'、`\{keymap}'、 `\<keymap>'の特別な書き方を使え、 これらはユーザー独自のキーバインディングに自動的に置き換えられる。 see 節 23.3 説明文内のキーバインディングの置換。
kill-all-local-variablesの呼び出しから始めること。 それ以前に有効であったメジャーモードのバッファローカルな変数に 対処するためである。
major-modeにメジャーモードコマンドのシンボルを設定すること。 これにより、describe-modeが表示すべき説明文を捜し出す。
mode-nameにモードの『愛称』を文字列として設定すること。 この文字列がモード行に現れる。
use-local-mapを呼び出して、 そのローカルキーマップを設定すること。 詳しくは、see 節 21.6 活性なキーマップ。
このキーマップは、modename-mode-mapという名前の グローバル変数に恒久的に保持すること。 通常、モードを定義するライブラリでこの変数に設定する。
モードのキーマップ変数に設定するコードの書き方に関する助言については see 節 10.6 変数を堅牢に定義するためのヒント。
メジャーモードにおいては、そのモードによく適合した形で 『同じ仕事』を行うコマンドであるならば、 標準的な意味を持つキー列に当該コマンドを再バインドしても合理的である。 たとえば、プログラム言語編集用のメジャーモードでは、 C-M-aを当該言語にうまく適合した方法で 『関数の先頭へ移動する』コマンドに再定義する。
テキスト挿入を許さないdiredやrmailなどのメジャーモードでは、 英文字や他の印字文字を編集コマンドとして再定義するのも合理的である。 diredもrmailもこうしている。
modename-mode-syntax-tableという名前の変数に保持すること。 see 節 34. 構文テーブル。
modename-mode-abbrev-tableという名前の変数に保持すること。 see 節 35.2 略語表。
font-lock-defaults (see 節 22.5 フォントロック(font-lock)モード)に設定して、 フォントロック(font-lock)モードに対して強調表示の方法を指定すること。
imenu-generic-expressionか imenu-create-index-function(see 節 22.4 iメニュー)に設定して、 iメニューがどのようにバッファ内の定義や節を探すべきかを指定すること。
defvarかdefcustomを使い、 それらに値が設定されている場合には再初期化しないようにする。 (再初期化するとユーザーのカスタマイズを廃棄してしまう。)
make-variable-buffer-localではなく make-local-variableで行う。 前者の関数は、すべてのバッファにおいてそれ以降に設定される当該変数を バッファローカルにしてしまい、 このモードを使わないバッファにも影響する。 モードにそのような大局的な効果があるのは望ましくない。 see 節 10.10 バッファローカルな変数。
単一のLispパッケージ内のみにおいて使われる変数に対しては、 必要ならば、make-variable-buffer-localを使ってもよい。
modename-mode-hookという名前の モードフック(mode hook)があること。 モードコマンドは、最後にrun-hooksを用いてフックを実行すること。 see 節 22.6 フック。
indented-text-modeは、 indented-text-mode-hookに加えてtext-mode-hookも実行する。 自前のフックを実行する直前(つまり設定が終ったあと) にこれらの他のフックを実行するか、より初期の段階で実行してもよい。
change-major-mode-hook(see 節 10.10.2 バッファローカルな束縛の作成と削除) のバッファローカルな値を設定しておく。
mode-classに値specialを設定しておくこと。
(put 'funny-mode 'mode-class 'special) |
これは、カレントバッファがfunnyモードのときに新たなバッファを 作成しても、新しいバッファではfunnyモードを継承しないようにEmacsに指示する。 dired、rmail、バッファ一覧などのモードではこの機能を使っている。
auto-mode-alistに追加する。 モードコマンドを自動ロードと定義する場合、 autoloadを呼び出している同じファイルに そのような要素を追加しておくこと。 そうでなければ、モード定義を収めたファイルに当該要素を入れるだけで十分である。 see 節 22.1.3 メジャーモードの選択方法。
autoloadの例、 auto-mode-alistへの追加方法の例を記載すること。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
基本(fundamental)モードを除くと、 テキスト(text)モードはもっとも単純なモードです。 上に述べた慣習の例示として、`text-mode.el'の抜粋をあげておきます。
;; モード固有の構文テーブルを作る
(defvar text-mode-syntax-table nil
"Syntax table used while in text mode.")
(if text-mode-syntax-table
() ; 構文テーブルが既存ならば変更しない
(setq text-mode-syntax-table (make-syntax-table))
(modify-syntax-entry ?\" ". " text-mode-syntax-table)
(modify-syntax-entry ?\\ ". " text-mode-syntax-table)
(modify-syntax-entry ?' "w " text-mode-syntax-table))
(defvar text-mode-abbrev-table nil
"Abbrev table used while in text mode.")
(define-abbrev-table 'text-mode-abbrev-table ())
(defvar text-mode-map nil) ; モード固有のキーマップを作る
(if text-mode-map
() ; キーマップが既存ならば変更しない
(setq text-mode-map (make-sparse-keymap))
(define-key text-mode-map "\t" 'indent-relative)
(define-key text-mode-map "\es" 'center-line)
(define-key text-mode-map "\eS" 'center-paragraph))
|
つぎは、テキスト(text)モードのメジャーモード関数の完全な定義です。
(defun text-mode ()
"Major mode for editing text intended for humans to read....
Special commands: \\{text-mode-map}
Turning on text-mode runs the hook `text-mode-hook'."
(interactive)
(kill-all-local-variables)
(use-local-map text-mode-map)
(setq local-abbrev-table text-mode-abbrev-table)
(set-syntax-table text-mode-syntax-table)
(make-local-variable 'paragraph-start)
(setq paragraph-start (concat "[ \t]*$\\|" page-delimiter))
(make-local-variable 'paragraph-separate)
(setq paragraph-separate paragraph-start)
(setq mode-name "Text")
(setq major-mode 'text-mode)
(run-hooks 'text-mode-hook)) ; 最後に、フックによるモードの
; カスタマイズをユーザーに許す
|
3つのlispモード(lispモード、emacs-lispモード、lisp対話モード)には、 テキスト(text)モードより多くの機能があり、 それに応じてコードもより複雑です。 これらのモードの書き方を例示する `lisp-mode.el'からの抜粋をあげておきます。
;; モード固有の構文テーブルを作成する
(defvar lisp-mode-syntax-table nil "")
(defvar emacs-lisp-mode-syntax-table nil "")
(defvar lisp-mode-abbrev-table nil "")
(if (not emacs-lisp-mode-syntax-table) ; 構文テーブルが既存ならば
; 変更しない
(let ((i 0))
(setq emacs-lisp-mode-syntax-table (make-syntax-table))
;; 0までの文字に、単語構成文字ではないが
;; シンボル名構成文字であるクラスを設定する
;; (文字0は、ASCII文字集合では
|
3つのlispモードは多くのコードを共有しています。 つぎの関数はさまざまな変数に設定します。 lispモードの各メジャーモード関数が呼び出します。
(defun lisp-mode-variables (lisp-syntax)
(cond (lisp-syntax
(set-syntax-table lisp-mode-syntax-table)))
(setq local-abbrev-table lisp-mode-abbrev-table)
...
|
forward-paragraphなどの関数は、 変数paragraph-startの値を使います。 Lispのコードは普通のテキストとは異なるので、 Lispを扱えるように変数paragraph-startを特別に設定する必要があります。 また、Lispではコメントの字下げは特殊な形なので、 各lispモードには独自のモード固有のcomment-indent-functionが必要です。 これらの変数に設定するコードが、 lisp-mode-variablesの残りの部分です。
(make-local-variable 'paragraph-start) (setq paragraph-start (concat page-delimiter "\\|$" )) (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) ... (make-local-variable 'comment-indent-function) (setq comment-indent-function 'lisp-comment-indent)) |
各lispモードでは、キーマップが多少異なります。 たとえば、lispモードではC-c C-zをrun-lispにバインドしますが、 他のlispモードではそうしません。 つぎのコードは、共通するコマンドを設定します。
(defvar shared-lisp-mode-map ()
"Keymap for commands shared by all sorts of Lisp modes.")
(if shared-lisp-mode-map
()
(setq shared-lisp-mode-map (make-sparse-keymap))
(define-key shared-lisp-mode-map "\e\C-q" 'indent-sexp)
(define-key shared-lisp-mode-map "\177"
'backward-delete-char-untabify))
|
つぎはlispモード向けのキーマップを設定するコードです。
(defvar lisp-mode-map ()
"Keymap for ordinary Lisp mode....")
(if lisp-mode-map
()
(setq lisp-mode-map (make-sparse-keymap))
(set-keymap-parent lisp-mode-map shared-lisp-mode-map)
(define-key lisp-mode-map "\e\C-x" 'lisp-eval-defun)
(define-key lisp-mode-map "\C-c\C-z" 'run-lisp))
|
最後に、emacs-lispモードのメジャーモード関数の完全な定義を示します。
(defun lisp-mode ()
"Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
Commands:
Delete converts tabs to spaces as it moves back.
Blank lines separate paragraphs. Semicolons start comments.
\\{lisp-mode-map}
Note that `run-lisp' may be used either to start an inferior Lisp job
or to switch back to an existing one.
Entry to this mode calls the value of `lisp-mode-hook'
if that value is non-nil."
(interactive)
(kill-all-local-variables)
(use-local-map lisp-mode-map) ; モードのキーマップを選択する
(setq major-mode 'lisp-mode) ; これにより
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsは、ファイル名やファイル自体の情報をもとに、 当該ファイルを訪問するときの新しいバッファに対する メジャーモードを自動的に選択します。 また、ファイル内のテキストで指定されたローカル変数も処理します。
fundamental-modeはフックを実行しないため、 読者はカスタマイズできない。 (Emacsの基本(fundamental)モードのふるまいを変えたければ、 Emacsの大局的な状態を変える必要がある。)set-auto-modeを呼び出し、 続いて、ファイルのローカル変数を必要に応じて解析、束縛、評価するために hack-local-variablesを実行する。
normal-modeに対する引数find-fileがnil以外であると、 normal-modeはfind-fileから呼び出されたと仮定する。 その場合、ファイルの末尾や`-*-'の形式の行にある ローカル変数リストを処理することもある。 変数enable-local-variablesは、この処理を行うかどうかを制御する。 ファイル内でのローカル変数リストの構文については、 See 節 `ファイルにローカルな変数' in
読者が対話的にnormal-modeを実行すると 引数find-fileは通常nilである。 その場合、normal-modeは、ローカル変数リストを無条件に処理する。
normal-modeは、メジャーモード関数を呼び出す周りでは condition-caseを使うので、エラーを補足して `File mode specification error'にもとのエラーメッセージを続けて エラーを報告する。
tは、ローカル変数リストを無条件に処理することを意味する。 nilは、それらを無視することを意味する。 それ以外の値であると、各ファイルごとにユーザーに問い合わせる。 デフォルト値はtである。このリストに加えて、 属性risky-local-variableがnil以外の値である変数も無視されます。
tは、それらを無条件に処理することを意味する。 nilは、それらを無視することを意味する。 それ以外の値であると、各ファイルごとにユーザーに問い合わせる。 デフォルト値はmaybeである。auto-mode-alistを使って)訪問したファイルの名前、 (interpreter-mode-alistを使って)`#!'行、 ファイルのローカル変数リストをもとに決定する。 しかし、この関数はファイルの末尾付近にある ローカル変数`mode:'は調べないが、 関数hack-local-variablesは調べる。 See 節 `メジャーモードの選択方式' in
fundamental-modeである。
default-major-modeの値がnilであると、 Emacsは(以前の)カレントバッファのメジャーモードを 新たなバッファのメジャーモードとする。 しかし、メジャーモードコマンドのシンボルの属性mode-classの 値がspecialであると、新たなバッファのメジャーモードにはせず、 かわりに基本(fundamental)モードを使う。 この属性を持つモードは、 特別に準備したテキストに対してのみ有用であるdiredやrmailなどである。
default-major-modeの値とする。 この変数がnilであると、 (適切ならば)カレントバッファのメジャーモードを使う。
バッファを作成する低レベルの基本関数ではこの関数を使わないが、 switch-to-bufferやfind-file-noselectなどの 中レベルのコマンドではバッファを作成するときにこのコマンドを使う。
lisp-interaction-modeである。(regexp . mode-function)の形である。
たとえばつぎのとおり。
(("\\`/tmp/fol/" . text-mode)
("\\.texinfo\\'" . texinfo-mode)
("\\.texi\\'" . texinfo-mode)
("\\.el\\'" . emacs-lisp-mode)
("\\.c\\'" . c-mode)
("\\.h\\'" . c-mode)
...)
|
展開したファイル名(see 節 24.8.4 ファイル名を展開する関数)がregexpに一致する ファイルを訪問すると、 set-auto-modeは対応するmode-functionを呼び出す。 この機能により、Emacsはほとんどのファイルに対して 適切なメジャーモードを選択する。
auto-mode-alistの要素が(regexp function t)の 形であると、functionを呼び出したあとで、 Emacsはファイル名のそれまで一致しなかった部分についてauto-mode-alistを 再度探索する。 この機能は解凍パッケージには有用である。 ("\\.gz\\'" function t)の形の要素で、 ファイルを解凍し、`.gz'を除いたファイル名に従って 解凍済みファイルを適切なモードにできる。
auto-mode-alistにいくつかのパターン対を追加する方法を示す。 (この種の式を読者のファイル`.emacs'に使える。)
(setq auto-mode-alist
(append
;; ドットで始まる(ディレクトリ名付きの)ファイル名
'(("/\\.[^/]*\\'" . fundamental-mode)
;; ドットのないファイル名
("[^\\./]*\\'" . fundamental-mode)
;; `.C'で終るファイル名
("\\.C\\'" . c++-mode))
auto-mode-alist))
|
(interpreter . mode)の形の要素から成る リストであること。 たとえば、デフォルトには("perl" . perl-mode)の要素がある。 各要素は、ファイルが指定するインタープリタがinterpreterに 一致したらモードmodeを使うことを意味する。 interpreterの値は、実際には正規表現である。
auto-mode-alistが使用すべきメジャーモードが 指定しなかった場合にのみこの変数を使う。
normal-modeで述べたenable-local-variablesの処理は、 実際にはここで行う。 引数forceは、通常、 normal-modeに与えられた引数find-fileからくる。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
関数describe-modeは、メジャーモードに関する情報を 得るために使います。 通常、C-h mで呼び出されます。 関数describe-modeはmajor-modeの値を使いますが、 そのために各メジャーモード関数が 変数major-modeに設定する必要があるのです。
関数describe-modeは、major-modeの値を引数として 関数documentationを呼び出す。 そうして、メジャーモード関数の説明文字列を表示する。 (see 節 23.2 説明文字列の参照。)
describe-modeは、 メジャーモードの説明文として当該関数の説明文字列を使う。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
既存のメジャーモードを用いて新たなメジャーモードを定義できると便利です。 これを行う簡単な方法はdefine-derived-modeを使うことです。
新たなコマンドvariantは、関数parentを呼び出してから 親モードの特定の機能を無効にするように定義される。
variant-mapという名前の 独自のキーマップを持つ。 define-derived-modeは、 このキーマップが定義済みでなければ、 parent-mapから継承するようにこのキーマップを初期化する。
variant-syntax-tableに 独自の構文テーブルを保持する。 この変数が定義済みでなければ、 parent-syntax-tableをコピーしてこの変数を初期化する。
variant-abbrev-tableに 独自の略語表を保持する。 この変数が定義済みでなければ、 parent-abbrev-tableをコピーしてこの変数を初期化する。
variant-hookがあり、 通常どおり最後にこれを実行する。 (新たなモードでは、parentを呼び出すことの一部として parentのモードフックも実行する。)さらに、bodyでparentの他の部分を無効にする方法を指定できる。 コマンドvariantは、variant-hookを呼び出す直前、 通常の無効化処理を終えてからbodyのフォームを評価する。
引数docstringは、新たなモードに対する説明文字列を指定する。 docstringを省略すると、 define-derived-modeは説明文字列を生成する。
仮想的な例を示す。
(define-derived-mode hypertext-mode
text-mode "Hypertext"
"Major mode for hypertext.
\\{hypertext-mode-map}"
(setq case-fold-search nil))
(define-key hypertext-mode-map
[down-mouse-3] 'do-hyper-link)
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
マイナモード(minor mode)は、メジャーモードの選択とは独立に ユーザーがオン/オフできる機能を提供します。 マイナモードは、個別にも組み合わせてもオンにできます。 マイナモードは、長すぎますが『汎用的に使えるオプション機能のモード』と 命名したようがよいかもしれません。
マイナモードは、普通、1つのメジャーモードを変更するだけではありません。 たとえば、自動詰め込みモード(auto-fillモード)は、 テキスト挿入を許す任意のメジャーモードで使えます。 汎用的であるためには、マイナモードは メジャーモードが行うこととは実質的に独立である必要があります。
マイナモードは、メジャーモードに比べて、実装するのがしばしば困難です。 1つの理由は、任意の順でマイナモードをオン/オフできるようにする 必要があるからです。 マイナモードは、メジャーモードや他のオンになっているマイナモードとは 無関係にその望みの効果を発揮できる必要があります。
しばしば、マイナモードを実装するうえでもっとも大きな問題は、 Emacsの残りの部分に対して必要なフックを探すことです。 マイナモードキーマップにより、従来に比べて簡単になります。
22.2.1 マイナモードを書くための慣習 Tips for writing a minor mode. 22.2.2 キーマップとマイナモード How a minor mode can have its own keymap. 22.2.3 Easy-Mmode A convenient facility for defining minor modes.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
メジャーモードに対するのと同じように、 マイナモードを書くうえでの慣習があります。 メジャーモードの慣習には、マイナモードにも適用されるものがあります。 つまり、モードを初期化する関数の名前、 グローバルシンボルの名前、キーマップやその他のテーブルや表の使い方です。
それらに加えて、マイナモードに固有な慣習もあります。
nil、オンにするにはそれ以外に)設定 すること。
可能ならば、変数に設定すると 自動的にモードがオン/オフされるようにモードを実装する。 そうすると、マイナモードコマンドは、 変数に設定する以外にはなにもしないでよくなる。
この変数は、モード行にマイナモード名を表示するために minor-mode-alistでも使われる。 マイナモードキーマップを活性にしたり非活性にしたりもする。 各コマンドやフックもこの変数の値を検査する。
各バッファごとに別々にマイナモードをオンにしたい場合には、 この変数をバッファローカルにする。
当該コマンドは、省略可能な引数を1つ受け取ること。 引数がnilであればモードをトグル (オンであればオフに、オフであればオンに)する。 さもなければ、引数が、正整数、nil以外のシンボル、 -、あるいは、CARがそのような整数やシンボルであるようなリストの 場合にはモードをオンにする。 それ以外ではモードをオフにする。
transient-mark-modeの定義から引用した例を示す。 モードのふるまいをオン/オフする変数としての transient-mark-modeの使い方、 および、生の前置引数に基づいたマイナモードの オン/オフ/トグルの仕方を示す。
(setq transient-mark-mode
(if (null arg) (not transient-mark-mode)
(> (prefix-numeric-value arg) 0)))
|
minor-mode-alistに追加する (see 節 22.3.2 モード行に使われる変数)。 この要素はつぎの形のリストであること。
(mode-variable string) |
ここで、mode-variableはマイナモードのオン/オフを制御する変数であり、 stringはモード行でモードを表す短い空白で始まる文字列である。 同時に複数のモードを表示できるように、これらの文字列は短いこと。
minor-mode-alistに要素を追加するときには、 重複を防ぐために既存の要素を検査するassqを使うこと。 たとえばつぎのとおり。
(or (assq 'leif-mode minor-mode-alist)
(setq minor-mode-alist
(cons '(leif-mode " Leif") minor-mode-alist)))
|
このリストに要素を1回だけ追加するならばadd-to-listも使えます (see 節 10.8 変数値の変更)。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
各マイナモードは、モードがオンのときに活性になる独自のキーマップを持てます。 マイナモード向けのキーマップを設定するには、 minor-mode-map-alistに要素を追加します。 See 節 21.6 活性なキーマップ。
マイナモードキーマップの1つの用途は、 ある種の自己挿入文字のふるまいを変更して、 自己挿入に加えてなにかを行わせるようにすることです。 一般に、self-insert-commandをカスタマイズする機構は (略語モードや自動詰め込みモード向けに設計された)特別な場合に限られるので、 このようなことを行う唯一の方法です。 (標準のself-insert-commandの定義を読者独自の定義で置き換えないこと。 エディタコマンドループはこの関数を特別扱いしている。)
マイナモードでバインドしているキー列は、C-cで始まり、 {、}、<、>、:、;以外の 句読点文字の1つが続くようにします。 (除外した句読点文字はメジャーモード向けに予約されている。)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
パッケージeasy-mmodeは、マイナモードを実装する便利な方法を提供します。 これを使うと、単純なマイナモードを1つの自己完結した定義に指定できます。
このマクロは、マイナモードをトグルする modeという名前のコマンドを定義し、 その説明文字列をdocとする。
また、modeという名前の変数も定義する。 この変数はモードのオン/オフにしたがってt/nilに設定される。 この変数はinit-valueに初期化される。
文字列mode-indicatorは、モードがオンのときにモード行に 表示される文字列である。 それがnilであるとモード行にはモードを表示しない。
省略可能な引数keymapは、マイナモードのキーマップを指定する。 これは、値がキーマップであるような変数の名前か、 つぎの形のバインディングを指定した連想リストであること。
(key-sequence . definition) |
easy-mmode-define-minor-modeを使った例を示します。
(easy-mmode-define-minor-mode hungry-mode
"Toggle Hungry mode.
With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode.
When Hungry mode is enabled, the control delete key
gobbles all preceding whitespace except the last.
See the command \\[hungry-electric-delete]."
;; 初期値
nil
;; モード行への表示
" Hungry"
;; マイナモードのバインディング
'(("\C-\^?" . hungry-electric-delete)
("\C-\M-\^?"
. (lambda ()
(interactive)
(hungry-electric-delete t)))))
|
これは、『hungryモード』という名前のマイナモードを定義します。 モードをトグルするコマンドの名前はhungry-mode、 モードのオン/オフを表す変数の名前はhungry-mode、 モードがオンのときに活性なキーマップを保持する 変数の名前はhungry-mode-mapです。 C-DELとC-M-DELに対するキーバインディングで キーマップを初期化します。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsの(ミニバッファ専用ウィンドウを除く)各ウィンドウにはモード行があって、 ウィンドウに表示しているバッファに関する状態情報を表示しています。 モード行には、バッファ名、対応するファイル、再帰編集の深さ、 メジャーモードとマイナモードなどのバッファに関する情報が含まれます。
本節では、モード行の内容の制御方法について述べます。 モード行に表示される情報のほとんどは オンになっているメジャーモードとマイナモードに関係するので、 本章に含めます。
mode-line-formatは、カレントバッファのモード行に表示する 雛型を保持しているバッファローカルな変数です。 同一バッファに対するすべてのウィンドウは同じmode-line-formatを使い、 それらのモード行は(スクロールの割合や行やコラム位置を除いて) 同じように表示されます。
ウィンドウのモード行は、通常、ウィンドウに別のバッファを表示したときや、 バッファの変更状態がnilからtへあるいはその逆の変化をしたときに 更新されます。 mode-line-format(see 節 22.3.2 モード行に使われる変数)が参照する 変数を修正したり、テキストの表示方法に影響するその他の変数やデータ構造 (see 節 38. Emacsの画面表示)を変更したときには、新しい情報を表示したり 新たな方法で表示するためにモード行の更新を強制できます。
モード行は、通常、反転表示されます。 38.12 反転表示のmode-line-inverse-videoを参照してください。
22.3.1 モード行のデータ構造 The data structure that controls the mode line. 22.3.2 モード行に使われる変数 Variables used in that data structure. 22.3.3 モード行の %記法Putting information into a mode line.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
モード行の内容は、バッファローカルな変数mode-line-formatに 保持されたリスト、文字列、シンボル、数から成るデータ構造で制御されます。 このデータ構造をモード行構成(mode line construct)と呼びます。 これは単純なモード行構成から再帰的に構築します。 同じデータ構造はフレームタイトル(see 節 28.4 フレームタイトル)を 構築するためにも使われます。
モード行構成は、定まったテキストの文字列のように単純でもかまいませんが、 普通は、テキストを作るための別の変数の使い方を指定します。 それらの変数の多くはそれ自身、それらの値として モード行構成を持つように定義されています。
mode-line-formatのデフォルト値は、 mode-nameやminor-mode-alistなどの変数の値を使います。 多くの目的には、mode-line-formatが参照するいくつかの変数を 変えるだけで十分です。
モード行構成は、リスト、シンボル、文字列のいずれかです。 その値がリストであれば、その各要素はリスト、シンボル、文字列のいずれかです。
string%記法を除いて、モード行にそのまま表示される。 `%'のうしろの10進数は、右側に空白を埋める (つまりデータは左端に揃えられる)ときのフィールド幅を指定する。 see 節 22.3.3 モード行の%記法。
symboltやnilのシンボル、および、シンボルの値が空のものは 無視する。
例外が1つある: symbolの値が文字列であると、%記法を処理せずに 文字列をそのまま表示する。
(string rest...) or (list rest...)(symbol then else)nil以外であると、 2番目の要素thenをモード行構成として再帰的に処理する。 symbolの値がnilであると、 3番目の要素elseをモード行構成として再帰的に処理する。 elseは省略してもよいが、その場合、 symbolの値がnilであるところの要素はモード行に表示されない。
(width rest...)たとえば、ウィンドウの上端より上にバッファの何割があるかを表示するには、 (-3 "%p")のようなリストを使う。
読者がmode-line-format自体を変更するときには、 新しい値では、デフォルト値(see 節 22.3.2 モード行に使われる変数)に現れる ものと同じ変数を使い、それらの値をコピーして使ったり、 別の書式で情報を表示したりしないでください。 こうしておけば、それらの変数に対する変更を介した ユーザーや(display-timeやメジャーモードなどの)Lispプログラムが行った カスタマイズが効果を発揮できます。
ホスト名やデフォルトディレクトリを含んだ shell-modeに有用なmode-line-formatの例を示します。
(setq mode-line-format
(list "-"
'mode-line-mule-info
'mode-line-modified
'mode-line-frame-identification
"%b--"
;; リストを作るときに評価されることに注意
;; 単なる文字列のモード行構成を作る
(getenv "HOST")
":"
'default-directory
" "
'global-mode-string
" %[("
'mode-name
'mode-line-process
'minor-mode-alist
"%n"
")%]--"
'(which-func-mode ("" which-func-format "--"))
'(line-number-mode "L%l--")
'(column-number-mode "C%c--")
'(-3 . "%p")
"-%-"))
|
(変数line-number-mode、column-number-mode、 which-func-modeは特定のマイナモードをオンにする。 通常どおり、これらの変数の名前はマイナモードコマンドの名前でもある。)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、mode-line-formatの標準値でモード行のテキストに 含められる変数について述べます。 これらの変数に関しては、本来特別なことはありません。 別の変数を使うようにmode-line-formatを変更すれば、 別の変数でもモード行において同じ効果を発揮します。
mode-line-modifiedのデフォルト値は("%1*%1+")である。 これは、バッファが変更されていると`**'を、 未変更ならば`--'を、読み出し専用ならば`%%'を、 読み出し専用でしかも変更されていれば`%*'を モード行に表示することを意味する。
この変数を変更してもモード行の更新を強制しない。
" "であり、 ある時点で1つのフレームしか表示できない普通の端末を使用している場合には "-%F "である。("%12b")であり、 空白で埋めて最低12コラムでバッファ名を表示する。display-timeは、 global-mode-stringが時刻と負荷情報を含んだ 変数display-time-stringを参照するように設定する。
`%M'記法はglobal-mode-stringの値を使うが、 この変数はmode-line-formatでモード行に含まれるため `%M'は廃れた記法である。
minor-mode-alistの各要素は、2要素リストであること。
(minor-mode-variable mode-line-string) |
より一般的には、mode-line-stringはどのようなモード行指定でもよい。 それは、minor-mode-variableの値がnil以外のときに モード行に現れ、さもなければ現れない。 これらの文字列は、繋がらないように空白で始まること。 慣習的には、特定モードに対するminor-mode-variableは、 当該マイナモードがオンであるとnil以外に設定される。
minor-mode-alistのデフォルト値はつぎのとおり。
minor-mode-alist
=> ((vc-mode vc-mode)
(abbrev-mode " Abbrev")
(overwrite-mode overwrite-mode)
(auto-fill-function " Fill")
(defining-kbd-macro " Def")
(isearch-mode isearch-mode))
|
minor-mode-alist自体はバッファローカルではない。 マイナモードが各バッファごとにオンにできる場合には、 連想リストに指定した対応する各変数はバッファローカルであること。
(":%s")であり、 シェルがその状態をメジャーモードとともに`(Shell: run)'のように 表示できる。 通常、この変数はnilである。mode-line-formatを変更していないバッファの デフォルトのmode-line-formatの値を保持する。 これは(default-value 'mode-line-format)と同じである。
default-mode-line-formatのデフォルト値はつぎのリストである。
("-"
mode-line-mule-info
mode-line-modified
mode-line-frame-identification
mode-line-buffer-identification
" "
global-mode-string
" %[("
mode-name
mode-line-process
minor-mode-alist
"%n"
")%]--"
(which-func-mode ("" which-func-format "--"))
(line-number-mode "L%l--")
(column-number-mode "C%c--")
(-3 . "%p")
"-%-")
|
vc-modeは、 バッファで訪問したファイルが版管理されているか、 そうならばその方式を記録している。 版管理されていない場合はその値はnil、 さもなければモード行に表示される文字列である。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
%記法%記法"へのコメント(無し)
以下は、認識される%記法とその意味の表です。 `%%'以外の記法では、 最大表示文字数を指定する10進数を`%'のあとに追加できます。
%bbuffer-nameで得られたカレントバッファ名。 see 節 26.3 バッファ名。
%fbuffer-file-nameで得られた訪問したファイルの名前。 see 節 26.4 バッファファイル名。
%F%c%l%*buffer-read-onlyを参照)、buffer-modified-pを参照)、%+buffer-modified-pを参照)、buffer-read-onlyを参照)、%&%sprocess-statusで得たカレントバッファに属するサブプロセスの状態。 see 節 36.6 プロセス情報。
%t%p%P%nnarrow-to-regionを参照)。
%[%]%%%記法を許す文字列に`%'をそのまま含めるための方法である。
%-つぎの2つの%記法はまだ使えますが、 変数mode-nameやglobal-mode-stringを 使って同じ効果を得られるのでこれらは廃れた記法です。
%mmode-nameの値。
%Mglobal-mode-stringの値。 現在、display-timeはglobal-mode-stringの値を変更する。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
iメニュー(Imenu)とは、ユーザーが バッファ内の定義や節の一覧からその1つを選ぶと バッファ内の当該箇所へ直接移動できる機能です。 iメニューは、 バッファ内の定義や部分の名前や位置を表すバッファインデックスを 構築しておくことで動作し、 当該箇所へ移動するためにユーザーがそれらの1つを選べるようにします。 本節ではメジャーモードに対するiメニューをカスタマイズする方法を説明します。
普通のもっとも単純な方法は、 変数imenu-generic-expressionに設定することです。
nil以外であると、 iメニュー向けの定義を探すための正規表現を指定する。 もっとも単純な場合、要素はつぎのような形である。
(menu-title regexp subexp) |
ここで、menu-titleがnil以外であると、 この要素に一致したものはバッファインデックスのサブメニューに置くことを 意味する。 menu-title自体はサブメニューの名前を指定する。 menu-titleがnilであると、 この要素に一致したものはバッファインデックスのメニューに直接置かれる。
リストの2番目の要素regexpは正規表現 (see 節 33.2 正規表現)であり、 これに一致した箇所がバッファインデックスに現れる定義になる。 3番目の要素subexpは、 定義の名前に一致するregexpの部分式である。
要素はつぎの形でもよい。
(menu-title regexp index function arguments...) |
この要素に一致するものは、バッファインデックスの特別な項目になり、 ユーザーが当該項目を選ぶと、 item-name、バッファ位置、argumentsを引数として functionを呼び出す。
emacs-lispモード向けには、patternはつぎのようになる。
((nil "^\\s-*(def\\(un\\|subst\\|macro\\|advice\\)\
\\s-+\\([-A-Za-z0-9+]+\\)" 2)
("*Vars*" "^\\s-*(def\\(var\\|const\\)\
\\s-+\\([-A-Za-z0-9+]+\\)" 2)
("*Types*"
"^\\s-*\
(def\\(type\\|struct\\|class\\|ine-condition\\)\
\\s-+\\([-A-Za-z0-9+]+\\)" 2))
|
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。
tであり、大文字小文字を区別せずに一致をとる。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。
imenu-generic-expressionを処理中に カレントバッファの構文テーブルに優先する 構文テーブルの変更部分の連想リストである。 各要素はつぎの形であること。
(characters . syntax-description) |
CARのcharactersは、文字か文字列である。 それらの文字は、指定した構文syntax-descriptionであることを意味する。 これはmodify-syntax-entry(see 節 34.3 構文テーブル向け関数)に 渡される。
この機能は典型的には、 通常のシンボル構成文字を単語構成文字として扱い、 imenu-generic-expressionを単純化し一致処理を速くする。 たとえば、fortranモードではつぎのように使っている。
(setq imenu-syntax-alist '(("_$" . "w")))
|
こうすると、imenu-generic-expressionのパターンでは、 `\\(\\sw\\|\\s_\\)+'のかわりに`\\sw+'を使える。 この技法は、名前の先頭文字の集合を名前の残りの文字の集合よりも 小さく制限する必要があるモードで使うには不便であることに注意してほしい。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。
メジャーモードのiメニューをカスタマイズする別の方法は、 変数imenu-prev-index-position-functionや imenu-extract-index-name-functionに設定することです。
nil以外であると、その値は、 バッファインデックスに置くつぎの定義を ファイルで後向きに探すための関数であること。
その関数は、バッファインデックスの項目に対応する箇所にポイントを置くこと。 項目がみつからなければnilを返すこと。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。
nil以外であると、その値は、 ポイントが変数imenu-prev-index-position-functionが返した 定義の部分にあると仮定して、当該定義の名前を返す関数であること。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。
メジャーモードのiメニューをカスタマイズする最後の方法は、 変数imenu-create-index-functionに設定することです。
save-excursionの内側から呼ばれるので、 その関数がポイントをどこに置こうと関係ない。
デフォルト値は、インデックスの連想リストを生成するために imenu-generic-expressionを使う関数である。 読者が別の関数を指定すれば、imenu-generic-expressionは使われない。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。
連想リストの単純な要素は(index-name . index-position) のような形である。 このような単純な要素を選ぶと、 バッファ内でindex-positionへ移動する効果がある。
特別な要素は(index-name position function arguments...)のような形である。 このような特別な要素を選ぶと、 つぎのようなフォームを実行する。
(funcall function index-name position arguments...) |
入れ子になった部分連想リストの要素は (index-name sub-alist)のような形である。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フォントロック(font-lock)モードとは、 バッファ内の特定部分に対して、それらの構文上の役割に応じた 属性faceを自動的に付加する機能のことです。 バッファを解析する方法はメジャーモードに依存しますが、 ほとんどのメジャーモードでは、 どの文脈でどのフェイスを使うかを指示する条件を定義します。 本節では、特定の言語向けに、いいかえれば、 特定のメジャーモード向けに フォントロックをカスタマイズする方法を説明します。
フォントロック(font-lock)モードは、強調表示すべきテキストを 2つの方法で、つまり、構文テーブルに基づいた構文解析、あるいは、 (通常、正規表現による)探索で探します。 構文解析による処理を最初に行ってコメントや文字列定数を探し、 font-lock-comment-faceやfont-lock-string-face (see 節 22.5.5 フォントロックのフェイス)を使ってそれらを強調表示します。 探索による処理がこれに続きます。
22.5.1 フォントロック(font-lock)の基本 22.5.2 探索に基づくフォント選択 22.5.3 その他のフォントロック変数 22.5.4 フォントロックのレベル 22.5.5 フォントロックのフェイス 22.5.6 構文的なフォントロック
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フォントロック(font-lock)モードがテキストを強調表示する方法を 制御する変数がいくつかあります。 しかし、メジャーモードでこれらの変数を直接に設定するべきではありません。 そのかわりに、バッファローカルな 変数font-lock-defaultsに設定すべきです。 フォントロック(font-lock)モードがオンになると、 この変数に設定された値を使って他のすべての変数に設定します。
(keywords keywords-only case-fold syntax-alist syntax-begin other-vars...) |
最初の要素keywordsは、 間接的にfont-lock-keywordsの値を指定する。 要素keywordsがシンボルであると、 その変数としての値がfont-lock-keywordsに使われる。 あるいは、要素keywordsがそのようなシンボルのリストであると、 各シンボルが1つのレベルの表示方法を指定する。 最初のシンボルはレベル1の表示方法、 2番目のシンボルはレベル2の表示方法といった具合である。
2番目の要素keywords-onlyは、 変数font-lock-keywords-onlyの値を指定する。 これがnil以外であると(文字列やコメントの)構文による処理を行わない。
3番目の要素case-foldは、 font-lock-case-fold-searchの値を指定する。 これがnil以外であると、フォントロック(font-lock)モードは font-lock-keywordsで指定された探索で 大文字小文字を区別しない。
4番目の要素syntax-alistがnil以外である場合、 それは(char-or-string . string)の形の コンスセルのリストであること。 これらは表示方法を選ぶための構文テーブルの設定に使われる (see 節 34.3 構文テーブル向け関数)。 得られた構文テーブルはfont-lock-syntax-tableに保持される。
5番目の要素syntax-beginは、 font-lock-beginning-of-syntax-functionの値を指定する (下記参照)。
other-vars以降の要素は、 (variable . value)という形である。 この種の要素は、表示方法の選択に影響する その他の変数に設定するために使われる。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フォントロック(font-lock)モードのカスタマイズにおいて もっとも重要な変数はfont-lock-keywordsです。 探索に基づく表示方法の選択における探索条件を指定します。
font-lock-keywordsの各要素は、 特定のテキストの探し方と 当該テキストをどのように強調表示するか指定します。 フォントロック(font-lock)モードは、 font-lock-keywordsの要素を1つ1つ処理し、 各要素において、それに一致するものすべてを探して処理します。 通常、すでに表示方法を選択済みのテキスト部分については、 それ以降の要素に一致しても表示方法を変えません。 しかし、highlighterの要素overrideを使って、 異なるふるまいを指定できます。
font-lock-keywordsの各要素はつぎのいずれかの形です。
regexpfont-lock-keyword-faceを使って強調表示する。
;; 孤立した`foo'の出現は
;;
|
関数regexp-opt(see 節 33.2.1 正規表現の構文)は、 異なる複数個のキーワードに一致する最適な正規表現を 計算するのに有用である。
functionfont-lock-keyword-faceを使って強調表示する。
functionは、探索限界を引数として呼び出される。 みつかればnil以外を返すとともに みつけた部分を表すマッチデータを設定する。
(matcher . match)
;; `fubar'の各出現の`bar'を
;;
|
正規表現matcherを作るためにregexp-optを使った場合、 matchの値を計算するには regexp-opt-depth(see 節 33.2.1 正規表現の構文)を使える。
(matcher . facename)
;; `fubar'の出現は、
|
(matcher . highlighter)
(subexp facename override laxmatch) |
CARのsubexpは、 強調表示すべき一致部分の部分式を指定する整数 (0は一致部分全体を意味する)である。 2番目の要素facenameは、上に述べたようにフェイスを指定する。
highlighterの最後の2つの要素、 overrideとlaxmatchはフラグである。 overrideがtであると、当該要素は、 font-lock-keywordsのまえの要素で決定済みの 表示方法に優先することを表す。 keepであると、他の要素では表示方法が決定していない 各文字の表示方法を表す。 prependであると、 属性faceの先頭にフェイスfacenameを追加する。 appendであると、 属性faceの末尾にフェイスfacenameを追加する。
laxmatchがnil以外であると、 matcherで一致したものの中にsubexp番目の部分式が なくてもエラーとしないことを意味する。
この種の要素とその動作の例を示す。
;; `foo'や`bar'の出現の表示方法がすでに決まっていても ;; |
(matcher highlighters...)(eval . form)font-lock-keywordsのこの値が 始めて使われたときに評価すべき式である。 その値は、この表にあげた形の1つであること。警告: font-lock-keywordsの要素は、 行をまたがって一致するように設計しないこと。 そのような処理は信頼性がない。 font-lock-fontify-bufferは、行にまたがるパターンを正しく扱えるが、 読者がバッファを編集したときの更新処理では、 一度に1行ずつ処理するために正しく扱えない。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、font-lock-defaultsを用いてメジャーモードで 設定できる他の変数について述べます。
nil以外であると、フォントロック(font-lock)モードは、 構文に基づいてコメントや文字列を強調表示すべきでないことを意味する。 font-lock-keywordsに基づく強調表示のみを行う。nil以外であると、font-lock-keywordsの 正規表現探索では大文字小文字を区別しないことを意味する。nil以外であると、 ポイントを構文上の『トップレベル』で文字列やコメントの外側に 後方移動する関数であること。 フォントロック(font-lock)モードは、 構文に基づく処理において正しい結果を得るために 必要に応じてこの関数を使う。
関数は引数なしで呼び出される。 ポイントを構文ブロックの先頭に置くこと。 典型的な値は、 beginning-of-line(行頭は構文ブロックの外側である)、 あるいは、 プログラム向けのモードではbeginning-of-defun、 テキスト向けのモードではbackward-paragraph (モード固有の関数は構文ブロックの外側にポイントを移動する)である。
値がnilであると、バッファの先頭を構文ブロックの外側の位置として使う。 これは誤りではないが、動作を遅くする。
nil以外であると、 コマンドM-g M-g(font-lock-fontify-block)による 再表示のためにテキストの括られた範囲を選ぶために 引数なしで呼ばれ関数であること。
関数は、選んだ範囲にリージョンを設定すること。 正しい結果を得られるように大きめのテキスト範囲を選ぶのがよいが、 再表示処理が遅くならないように大きすぎないこと。 典型的な値は、プログラム向けモードではmark-defun、 テキスト向けモードではmark-paragraphである。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
多くのメジャーモードでは、3段階の表示方法を提供します。 font-lock-defaultsのkeywordsに シンボルのリストを使って複数レベルを定義できます。 各シンボルは1つのレベルの表示方法を指定します。 どのレベルを選ぶかはユーザーの責任です。 指定したレベルのシンボルの値はfont-lock-keywordsの初期化に使われます。
表示方法のレベルを定義する際の慣習をあげておきます。
関数宣言、(includeやimportなどの)ファイル指定、文字列、 コメントを強調表示する。 速さが肝心であり、重要な構文やトップレベルの構成要素のみを強調表示する。
レベル1に加えて、キーワードのようにふるまう型名を含む 当該言語のすべてのキーワード、名前付き定数。 (構文的な、あるいは、意味的な)すべてのキーワードを 適切に強調表示するのが目的。
レベル2に加えて、 関数や変数宣言で定義されたシンボル、適切なすべての組み込み関数の名前。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フォントロック(font-lock)モードでは任意のフェイスを使えますが、 フォントロック(font-lock)モード向けに特別に定義さたフェイスがあります。 これらのシンボルのおのおのは、フェイス名でもあり、 シンボル自身をデフォルト値とする変数でもあります。 つまり、font-lock-comment-faceのデフォルト値は、 font-lock-comment-faceです。 これは、 フェイス名を値に持つような式を書くfont-lock-keywordsなどの場面で、 font-lock-comment-faceと書けることを意味します。
font-lock-comment-facefont-lock-string-facefont-lock-keyword-faceforやifのように構文的に重要な名前に使われる。
font-lock-builtin-facefont-lock-function-name-facefont-lock-variable-name-facefont-lock-type-facefont-lock-constant-facefont-lock-warning-face#error指定に使われる。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フォントロック(font-lock)モードは、 属性syntax-tableを自動更新するためにも使えます。 1つの構文テーブルだけでは十分でないような言語において有用です。
(matcher subexp syntax override laxmatch) |
この要素の各部分には、つぎのfont-lock-keywordsの対応する種類の要素と 同じ意味がある。
(matcher subexp facename override laxmatch) |
しかし、属性faceに使う値facenameを指定するかわりに、 属性syntax-tableに使う値syntaxを指定する。 ここで、syntaxは、構文テーブルを値とする変数、 (syntax-code . matching-char)の形の構文テーブルの項目、 あるいは、この2種類のどちらかを値とする式である。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フック(hook)とは、既存のプログラムから特定の場面で 呼び出される(1つか一連の)関数を収めた変数です。 Emacsは、カスタマイズのためにフックを用意しています。 ほとんどの場合、フックはファイル`.emacs'で設定しますが、 Lispプログラムが行ってもかまいません。 標準のフック関数一覧については、See 節 F. 標準のフック。
Emacsの多くのフックはノーマルフック(normal hook)です。 これらの変数は、引数なしで呼び出される関数のリストを保持しています。 フック名が`-hook'で終っていると、ノーマルフックを意味します。 読者がそれらを単一の方法で使えるように、 可能な限りノーマルフックにするように心掛けています。
各メジャーモード関数は、 その初期化の最終段階でモードフック(mode hook)と呼ばれる ノーマルフックを実行すると期待されます。 これにより、モードがすでに設定したバッファローカルな変数を上書きすることで、 ユーザーがモードのふるまいをカスタマイズしやすくしています。 しかし、フックは別の場面でも使われています。 たとえば、フックsuspend-hookは、 Emacsが自身を一時休止する直前に実行されます。 (see 節 37.2.2 Emacsの休止)。
ノーマルフックにフック関数を追加する推奨方法は、 add-hook(下記参照)を呼ぶことです。 フック関数は、funcall(see 節 11.1 関数とはなにか)が 受け付けるならばどんな種類の関数でもかまいません。 ほとんどのノーマルフック変数は最初は空ですが、 add-hookはその扱い方を知っています。
フック変数の名前が`-hook'で終らない場合、 それがアブノーマルフック(abnormal hook)であることを表します。 読者は、そのようなフックの正しい使い方を説明書で調べるべきです。
変数名が`-functions'や`-hooks'で終っていると、 その値は関数のリストですが、 それらの関数を引数ありで呼び出したり、 関数の戻り値をどこかで使うという意味でアブノーマル(異常)なのです。 リストに関数を追加するにはadd-hookを使えますが、 関数を書くときには注意する必要があります。 (これらの変数のうち、実際にはノーマルフックであるものもある。 ノーマルフックには`-hook'を使うという慣習を 確立するまえに命名したものである。)
変数名が`-function'で終っていると、 その値は、関数のリストではなく、1つの関数です。
lisp対話モードで自動詰め込み(auto-fill)モードをオンにするために モードフックを使った例を示します。
(add-hook 'lisp-interaction-mode-hook 'turn-on-auto-fill) |
適当な時期に、Emacsは関数run-hooksを使って 特定のフックを実行します。 この関数は、add-hookで追加されたフック関数を呼び出します。
フック変数がnil以外の値であると、 その値は、関数か関数のリストである。 値が関数(ラムダ式や関数定義を持つシンボル)であると、それを呼び出す。 値がリストであると、順番にその要素を呼び出す。 フック関数は、引数なしで呼び出される。 現在、フック変数に1つの関数を入れることは廃れかけている。 つねに関数のリストを使うべきである。
例として、emacs-lisp-modeがそのモードフックをどのように 実行するかを示す。
(run-hooks 'emacs-lisp-mode-hook) |
nilを返すまで、 各フック関数に引数argsを渡して呼び出す。 nilが返ってくるとnilで戻る。 さもなければ、nil以外の値を返す。nil以外を返すまで、 各フック関数に引数argsを渡して呼び出す。 nil以外が返ってくると 最後に呼び出したフック関数の戻り値を返す。
(add-hook 'text-mode-hook 'my-text-hook-function) |
は、text-mode-hookというフックに my-text-hook-functionを追加する。
add-hookは、ノーマルフックに加えてアブノーマルフックにも使える。
フック関数は実行順序に依存しないように設計するのが最良である。 実行順序に依存すると『トラブルを呼び込む』ようなものである。 しかし、順序は予測できる。 通常、functionはフックリストの先頭に置かれるので、 (ほかにadd-hookの呼び出しがなければ)最初に実行される。 省略可能な引数appendがnil以外であると、 新たなフック関数はフックリストの末尾に置かれ、 最後に実行される。
localがnil以外であると、 新たなフック関数をカレントバッファにバッファローカルにすることを意味する。 これを行うまえに、(make-local-variableではなく) make-local-hookを呼んで フック自身をバッファローカルにしておく必要がある。 フック自身がバッファローカルでないと、localの値は意味を持たない。 フック関数はつねにグローバルである。
localがnil以外であると、 グローバルなフックリストではなくバッファローカルなフックリストから functionを削除することを指定する。 フック変数自身がバッファローカルでないと、localの値は意味を持たない。
hookをカレントバッファにバッファローカルにする。 フック変数がバッファローカルであると、 バッファローカルなフック関数とグローバルなフック関数を持つことができ、 run-hooksはそれらすべてを実行する。
この関数は、バッファローカルな値の要素をtにすることで動作する。 これは、バッファローカルな値に加えてフック変数のデフォルト値にある フック関数を使うことを表すフラグである。 run-hooksはこのフラグを理解し、 make-local-hookはすべてのノーマルフックを処理できる。 アブノーマルフックに関しては、 tの意味を理解するように更新したものだけが処理できる。
フック変数に対してmake-local-variableを直接使わないこと。 それだけでは不十分である。
| [ << ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |