次: Auto Major Mode, 前: Major Mode Conventions, 上: 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)) ; フックによるモードの
; カスタマイズをユーザーに許す