Text mode is perhaps the simplest mode besides Fundamental mode. Here are excerpts from `text-mode.el' that illustrate many of the conventions listed above:
;; Create mode-specific tables.
(defvar text-mode-syntax-table nil
"Syntax table used while in text mode.")
(if text-mode-syntax-table
() ; Do not change the table if it is already set up.
(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) ; Create a mode-specific keymap.
(if text-mode-map
() ; Do not change the keymap if it is already set up.
(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))
Here is the complete major mode function definition for Text mode:
(defun text-mode ()
"Major mode for editing text intended for humans to read@enddots{}
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)) ; Finally, this permits the user to
; customize the mode with a hook.
The three Lisp modes (Lisp mode, Emacs Lisp mode, and Lisp Interaction mode) have more features than Text mode and the code is correspondingly more complicated. Here are excerpts from `lisp-mode.el' that illustrate how these modes are written.
;; Create mode-specific table variables.
(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) ; Do not change the table
; if it is already set.
(let ((i 0))
(setq emacs-lisp-mode-syntax-table (make-syntax-table))
;; Set syntax of chars up to 0 to class of chars that are
;; part of symbol names but not words.
;; (The number 0 is 48 in the ASCII character set.)
(while (< i ?0)
(modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
(setq i (1+ i)))
...
;; Set the syntax for other characters.
(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)
...))
;; Create an abbrev table for lisp-mode.
(define-abbrev-table 'lisp-mode-abbrev-table ())
Much code is shared among the three Lisp modes. The following function sets various variables; it is called by each of the major Lisp mode functions:
(defun lisp-mode-variables (lisp-syntax) (cond (lisp-syntax (set-syntax-table lisp-mode-syntax-table))) (setq local-abbrev-table lisp-mode-abbrev-table) ...
Functions such as forward-paragraph use the value of the
paragraph-start variable. Since Lisp code is different from
ordinary text, the paragraph-start variable needs to be set
specially to handle Lisp. Also, comments are indented in a special
fashion in Lisp and the Lisp modes need their own mode-specific
comment-indent-function. The code to set these variables is the
rest of 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))
Each of the different Lisp modes has a slightly different keymap. For
example, Lisp mode binds C-c C-z to run-lisp, but the other
Lisp modes do not. However, all Lisp modes have some commands in
common. The following code sets up the common commands:
(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))
And here is the code to set up the keymap for Lisp mode:
(defvar lisp-mode-map ()
"Keymap for ordinary Lisp mode@enddots{}")
(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))
Finally, here is the complete major mode function definition for Emacs Lisp mode.
(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) ; Select the mode's keymap.
(setq major-mode 'lisp-mode) ; This is how describe-mode
; finds out what to describe.
(setq mode-name "Lisp") ; This goes into the mode line.
(lisp-mode-variables t) ; This defines various variables.
(setq imenu-case-fold-search t)
(set-syntax-table lisp-mode-syntax-table)
(run-hooks 'lisp-mode-hook)) ; This permits the user to use a
; hook to customize the mode.
Go to the first, previous, next, last section, table of contents.