Next: , Previous: , Up: Major Modes   [Contents][Index]

24.2.4 Defining Derived Modes

The recommended way to define a new major mode is to derive it from an existing one using define-derived-mode. If there is no closely related mode, you should inherit from either text-mode, special-mode, or prog-mode. See Basic Major Modes. If none of these are suitable, you can inherit from fundamental-mode (see Major Modes).

Macro: define-derived-mode variant parent name docstring keyword-args… body…

This macro defines variant as a major mode command, using name as the string form of the mode name. variant and parent should be unquoted symbols.

The new command variant is defined to call the function parent, then override certain aspects of that parent mode:

  • The new mode has its own sparse keymap, named variant-map. define-derived-mode makes the parent mode’s keymap the parent of the new map, unless variant-map is already set and already has a parent.
  • The new mode has its own syntax table, kept in the variable variant-syntax-table, unless you override this using the :syntax-table keyword (see below). define-derived-mode makes the parent mode’s syntax-table the parent of variant-syntax-table, unless the latter is already set and already has a parent different from the standard syntax table.
  • The new mode has its own abbrev table, kept in the variable variant-abbrev-table, unless you override this using the :abbrev-table keyword (see below).
  • The new mode has its own mode hook, variant-hook. It runs this hook, after running the hooks of its ancestor modes, with run-mode-hooks, as the last thing it does, apart from running any :after-hook form it may have. See Mode Hooks.

In addition, you can specify how to override other aspects of parent with body. The command variant evaluates the forms in body after setting up all its usual overrides, just before running the mode hooks.

If parent has a non-nil mode-class symbol property, then define-derived-mode sets the mode-class property of variant to the same value. This ensures, for example, that if parent is a special mode, then variant is also a special mode (see Major Mode Conventions).

You can also specify nil for parent. This gives the new mode no parent. Then define-derived-mode behaves as described above, but, of course, omits all actions connected with parent. Conversely, you can use derived-mode-set-parent and derived-mode-add-parents, described below, to explicitly set the ancestry of the new mode.

The argument docstring specifies the documentation string for the new mode. define-derived-mode adds some general information about the mode’s hook, followed by the mode’s keymap, at the end of this documentation string. If you omit docstring, define-derived-mode generates a documentation string.

The keyword-args are pairs of keywords and values. The values, except for :after-hook’s, are evaluated. The following keywords are currently supported:

:syntax-table

You can use this to explicitly specify a syntax table for the new mode. If you specify a nil value, the new mode uses the same syntax table as parent, or the standard syntax table if parent is nil. (Note that this does not follow the convention used for non-keyword arguments that a nil value is equivalent with not specifying the argument.)

:abbrev-table

You can use this to explicitly specify an abbrev table for the new mode. If you specify a nil value, the new mode uses the same abbrev table as parent, or fundamental-mode-abbrev-table if parent is nil. (Again, a nil value is not equivalent to not specifying this keyword.)

:interactive

Modes are interactive commands by default. If you specify a nil value, the mode defined here won’t be interactive. This is useful for modes that are never meant to be activated by users manually, but are only supposed to be used in some specially-formatted buffer.

:group

If this is specified, the value should be the customization group for this mode. (Not all major modes have one.) The command customize-mode uses this. define-derived-mode does not automatically define the specified customization group.

:after-hook

This optional keyword specifies a single Lisp form to evaluate as the final act of the mode function, after the mode hooks have been run. It should not be quoted. Since the form might be evaluated after the mode function has terminated, it should not access any element of the mode function’s local state. An :after-hook form is useful for setting up aspects of the mode which depend on the user’s settings, which in turn may have been changed in a mode hook.

Here is a hypothetical example:

(defvar-keymap hypertext-mode-map
  "<down-mouse-3>" #'do-hyper-link)

(define-derived-mode hypertext-mode
  text-mode "Hypertext"
  "Major mode for hypertext."
  (setq-local case-fold-search nil))

Do not write an interactive spec in the definition; define-derived-mode does that automatically.

Function: derived-mode-p modes

This function returns non-nil if the current major mode is derived from any of the major modes given by the list of symbols in modes. Instead of a list, modes can also be a single mode symbol.

Furthermore, we still support a deprecated calling convention where the modes were passed as separate arguments.

When examining the parent modes of the current major mode, this function takes into consideration the current mode’s parents set by define-derived-mode, and also its additional parents set by derived-mode-add-parents, described below.

Function: provided-mode-derived-p mode modes

This function returns non-nil if mode is derived from any of the major modes given by the list of symbols in modes. Like with derived-mode-p, modes can also be a single symbol, and this function also supports a deprecated calling convention where the modes were passed as separate symbol arguments.

When examining the parent modes of mode, this function takes into consideration the parents of mode set by define-derived-mode, and also its additional parents set by derived-mode-add-parents, described below.

The graph of a major mode’s ancestry can be accessed and modified with the following lower-level functions:

Function: derived-mode-set-parent mode parent

This function declares that mode inherits from parent. This is the function that define-derived-mode calls after defining mode to register the fact that mode was defined by reusing parent.

Function: derived-mode-add-parents mode extra-parents

This function makes it possible to register additional parents beside the one that was used when defining mode. This can be used when the similarity between mode and the modes in extra-parents is such that it makes sense to treat mode as a child of those modes for purposes like applying directory-local variables and other mode-specific settings. The additional parent modes are specified as a list of symbols in extra-parents. Those additional parent modes will be considered as one of the modes parents by derived-mode-p and provided-mode-derived-p.

Function: derived-mode-all-parents mode

This function returns the list of all the modes in the ancestry of mode, ordered from the most specific to the least specific, and starting with mode itself. This includes the additional parent modes, if any, added by calling derived-mode-add-parents.

Next: Basic Major Modes, Previous: Getting Help about a Major Mode, Up: Major Modes   [Contents][Index]