Next: Auto Major Mode, Previous: Major Mode Conventions, Up: Major Modes
基本(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文字集合では48
)
(while (< i ?0)
(modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
(setq i (1+ i)))
...
;; 他の文字の構文を設定する
(modify-syntax-entry ? " " emacs-lisp-mode-syntax-table)
(modify-syntax-entry ?\t " " emacs-lisp-mode-syntax-table)
...
(modify-syntax-entry ?\( "() " emacs-lisp-mode-syntax-table)
(modify-syntax-entry ?\) ")( " emacs-lisp-mode-syntax-table)
...))
;; lispモード向けの略語表を作る
(define-abbrev-table 'lisp-mode-abbrev-table ())
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) ; これによりdescribe-mode
は
; 説明文を探し出せる
(setq mode-name "Lisp") ; モード行に表示される
(lisp-mode-variables t) ; さまざまな変数を定義する
(setq imenu-case-fold-search t)
(set-syntax-table lisp-mode-syntax-table)
(run-hooks 'lisp-mode-hook)) ; フックによるモードの
; カスタマイズをユーザーに許す