Next: Auto Major Mode, Up: Major Modes
The code for every major mode should follow various coding conventions, including conventions for local keymap and syntax table initialization, function and variable names, and hooks.
If you use the define-derived-mode
macro, it will take care of
many of these conventions automatically. See Derived Modes. Note
also that Fundamental mode is an exception to many of these conventions,
because it represents the default state of Emacs.
The following list of conventions is only partial. Each major mode should aim for consistency in general with other Emacs major modes, as this makes Emacs as a whole more coherent. It is impossible to list here all the possible points where this issue might come up; if the Emacs developers point out an area where your major mode deviates from the usual conventions, please make it compatible.
The documentation string may include the special documentation substrings, ‘\[command]’, ‘\{keymap}’, and ‘\<keymap>’, which allow the help display to adapt automatically to the user's own key bindings. See Keys in Documentation.
kill-all-local-variables
. This runs the normal hook
change-major-mode-hook
, then gets rid of the buffer-local
variables of the major mode previously in effect. See Creating Buffer-Local.
major-mode
to the
major mode command symbol. This is how describe-mode
discovers
which documentation to print.
mode-name
to the
“pretty” name of the mode, usually a string (but see Mode Line Data, for other possible forms). The name of the mode appears
in the mode line.
indent-line-function
to a suitable function, and probably customize other variables
for indentation. See Auto-Indentation.
use-local-map
to install this local map. See Active Keymaps, for more information.
This keymap should be stored permanently in a global variable named
modename-mode-map
. Normally the library that defines the
mode sets this variable.
See Tips for Defining, for advice about how to write the code to set up the mode's keymap variable.
A major mode can also rebind the keys M-n, M-p and M-s. The bindings for M-n and M-p should normally be some kind of moving forward and backward, but this does not necessarily mean cursor motion.
It is legitimate for a major mode to rebind a standard key sequence if
it provides a command that does the same job in a way better
suited to the text this mode is used for. For example, a major mode
for editing a programming language might redefine C-M-a to
move to the beginning of a function in a way that works better for
that language. The recommended way of tailoring C-M-a to the
needs of a major mode is to set beginning-of-defun-function
(see List Motion) to invoke the function specific to the mode.
It is also legitimate for a major mode to rebind a standard key sequence whose standard meaning is rarely useful in that mode. For instance, minibuffer modes rebind M-r, whose standard meaning is rarely of any use in the minibuffer. Major modes such as Dired or Rmail that do not allow self-insertion of text can reasonably redefine letters and other printing characters as special commands.
-mode-syntax-table
. See Syntax Tables.
-mode-abbrev-table
. If the
major mode command defines any abbrevs itself, it should pass t
for the system-flag argument to define-abbrev
.
See Defining Abbrevs.
font-lock-defaults
(see Font Lock Mode).
imenu-generic-expression
, for the two variables
imenu-prev-index-position-function
and
imenu-extract-index-name-function
, or for the variable
imenu-create-index-function
(see Imenu).
eldoc-documentation-function
to tell ElDoc mode how to handle
this mode.
completion-at-point-functions
. See Completion in Buffers.
make-local-variable
in the major mode command, not
make-variable-buffer-local
. The latter function would make the
variable local to every buffer in which it is subsequently set, which
would affect buffers that do not use this mode. It is undesirable for a
mode to have such global effects. See Buffer-Local Variables.
With rare exceptions, the only reasonable way to use
make-variable-buffer-local
in a Lisp package is for a variable
which is used only within that package. Using it on a variable used by
other packages would interfere with them.
-mode-hook
. The very last thing the major mode command
should do is to call run-mode-hooks
. This runs the normal
hook change-major-mode-after-body-hook
, the mode hook, the
function hack-local-variables
(when the buffer is visiting a file),
and then the normal hook after-change-major-mode-hook
.
See Mode Hooks.
define-derived-mode
macro, but this is not required. Such a mode should call the parent
mode command inside a delay-mode-hooks
form. (Using
define-derived-mode
does this automatically.) See Derived Modes, and Mode Hooks.
change-major-mode-hook
(see Creating Buffer-Local).
mode-class
with value special
, put on as
follows:
(put 'funny-mode 'mode-class 'special)
This tells Emacs that new buffers created while the current buffer is in
Funny mode should not be put in Funny mode, even though the default
value of major-mode
is nil
. By default, the value of
nil
for major-mode
means to use the current buffer's major
mode when creating new buffers (see Auto Major Mode), but with such
special
modes, Fundamental mode is used instead. Modes such as
Dired, Rmail, and Buffer List use this feature.
The function view-buffer
does not enable View mode in buffers
whose mode-class is special, because such modes usually provide their
own View-like bindings.
The define-derived-mode
macro automatically marks the derived
mode as special if the parent mode is special. Special mode is a
convenient parent for such modes to inherit from; See Basic Major Modes.
auto-mode-alist
to select
the mode for those file names (see Auto Major Mode). If you
define the mode command to autoload, you should add this element in
the same file that calls autoload
. If you use an autoload
cookie for the mode command, you can also use an autoload cookie for
the form that adds the element (see autoload cookie). If you do
not autoload the mode command, it is sufficient to add the element in
the file that contains the mode definition.
defvar
or defcustom
to set mode-related
variables, so that they are not reinitialized if they already have a
value (see Defining Variables).