(lispref.info)Example Major Modes

Next: Auto Major Mode Prev: Major Mode Conventions Up: Major Modes

Major Mode Examples

   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" 'tab-to-tab-stop)
       (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.
      Special commands: \\{text-mode-map}

     Turning on text-mode runs the hook `text-mode-hook'."

     (use-local-map text-mode-map)     ; This provides the local keymap.
       (setq mode-name "Text")           ; This name goes into the mode line.
       (setq major-mode 'text-mode)      ; This is how `describe-mode'
                                         ;   finds the doc string to print.
       (setq local-abbrev-table text-mode-abbrev-table)
       (set-syntax-table text-mode-syntax-table)
       (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)
       ;; The `lisp-syntax' argument is `nil' in Emacs Lisp mode,
       ;;   and `t' in the other two Lisp modes.
       (cond (lisp-syntax
              (if (not lisp-mode-syntax-table)
                  ;; The Emacs Lisp mode syntax table always exists, but
                  ;;   the Lisp Mode syntax table is created the first time a
                  ;;   mode that needs it is called.  This is to save space.

     (progn (setq lisp-mode-syntax-table
                            (copy-syntax-table emacs-lisp-mode-syntax-table))
                         ;; Change some entries for Lisp mode.
                         (modify-syntax-entry ?\| "\"   "
                         (modify-syntax-entry ?\[ "_   "
                         (modify-syntax-entry ?\] "_   "

     (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 '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-l' to `run-lisp', but the other
Lisp modes do not.  However, all Lisp modes have some commands in
common.  The following function adds these common commands to a given

     (defun lisp-mode-commands (map)
       (define-key map "\e\C-q" 'indent-sexp)
       (define-key map "\177" 'backward-delete-char-untabify)
       (define-key map "\t" 'lisp-indent-line))

   Here is an example of using `lisp-mode-commands' to initialize a
keymap, as part of the code for Emacs Lisp mode.  First we declare a
variable with `defvar' to hold the mode-specific keymap.  When this
`defvar' executes, it sets the variable to `nil' if it was void.  Then
we set up the keymap if the variable is `nil'.

   This code avoids changing the keymap or the variable if it is already
set up.  This lets the user customize the keymap if he or she so wishes.

     (defvar emacs-lisp-mode-map () "")
     (if emacs-lisp-mode-map
       (setq emacs-lisp-mode-map (make-sparse-keymap))
       (define-key emacs-lisp-mode-map "\e\C-x" 'eval-defun)
       (lisp-mode-commands emacs-lisp-mode-map))

   Finally, here is the complete major mode function definition for
Emacs Lisp mode.

     (defun emacs-lisp-mode ()
       "Major mode for editing Lisp code to run in Emacs.
     Delete converts tabs to spaces as it moves back.
     Blank lines separate paragraphs.  Semicolons start comments.

     Entry to this mode runs the hook `emacs-lisp-mode-hook'."
       (use-local-map emacs-lisp-mode-map)    ; This provides the local keymap.
       (set-syntax-table emacs-lisp-mode-syntax-table)

     (setq major-mode 'emacs-lisp-mode)     ; This is how `describe-mode'
                                              ;   finds out what to describe.
       (setq mode-name "Emacs-Lisp")          ; This goes into the mode line.
       (lisp-mode-variables nil)              ; This define various variables.
       (run-hooks 'emacs-lisp-mode-hook))     ; This permits the user to use a
                                              ;   hook to customize the mode.

automatically generated by info2www