[ < ] | [ > ] | [ << ] | [ 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 モード行の%
記法。
symbol
t
や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進数を`%'のあとに追加できます。
%b
buffer-name
で得られたカレントバッファ名。 see 節 26.3 バッファ名。
%f
buffer-file-name
で得られた訪問したファイルの名前。 see 節 26.4 バッファファイル名。
%F
%c
%l
%*
buffer-read-only
を参照)、buffer-modified-p
を参照)、%+
buffer-modified-p
を参照)、buffer-read-only
を参照)、%&
%s
process-status
で得たカレントバッファに属するサブプロセスの状態。 see 節 36.6 プロセス情報。
%t
%p
%P
%n
narrow-to-region
を参照)。
%[
%]
%%
%
記法を許す文字列に`%'をそのまま含めるための方法である。
%-
つぎの2つの%
記法はまだ使えますが、 変数mode-name
やglobal-mode-string
を 使って同じ効果を得られるのでこれらは廃れた記法です。
%m
mode-name
の値。
%M
global-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
の各要素はつぎのいずれかの形です。
regexp
font-lock-keyword-face
を使って強調表示する。
;; 孤立した`foo'の出現は
;;
|
関数regexp-opt
(see 節 33.2.1 正規表現の構文)は、 異なる複数個のキーワードに一致する最適な正規表現を 計算するのに有用である。
function
font-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-face
font-lock-string-face
font-lock-keyword-face
for
やif
のように構文的に重要な名前に使われる。
font-lock-builtin-face
font-lock-function-name-face
font-lock-variable-name-face
font-lock-type-face
font-lock-constant-face
font-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
を直接使わないこと。 それだけでは不十分である。
[ << ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |