GNU Info

Info Node: (elisp)Example Major Modes

(elisp)Example Major Modes


Next: Auto Major Mode Prev: Major Mode Conventions Up: Major Modes
Enter node , (file) or (file)node

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.
       "Keymap for Text mode.
     Many other modes, such as Mail mode, Outline mode and Indented Text mode,
     inherit all the commands defined in this map.")
     
     (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 "\e\t" 'ispell-complete-word)
       (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...
      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)
       (make-local-variable 'indent-line-function)
       (setq indent-line-function 'indent-relative-maybe)
       (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...")
     
     (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
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.


automatically generated by info2www version 1.2.2.9