Many commands in Emacs are general, and not tied to any specific mode. For instance, M-x kill-region can be used in pretty much any mode that has editable text, and commands that display information (like M-x list-buffers) can be used in pretty much any context.
Many other commands, however, are specifically tied to a mode, and
make no sense outside of that context. For instance, M-x
dired-diff
will just signal an error if used outside of a Dired
buffer.
Emacs therefore has a mechanism for specifying what mode (or modes) a command “belongs” to:
(defun dired-diff (...) ... (interactive "p" dired-mode) ...)
This will mark the command as applicable to dired-mode
only (or
any modes that are derived from dired-mode
). Any number of
modes can be added to the interactive
form.
Specifying modes affects command completion in M-S-x
(execute-extended-command-for-buffer
, see Interactive Call). It may also affect completion in M-x, depending on the
value of read-extended-command-predicate
.
For instance, when using the
command-completion-default-include-p
predicate as the value of
read-extended-command-predicate
, M-x won’t list commands
that have been marked as being applicable to a specific mode (unless
you are in a buffer that uses that mode, of course). This goes for
both major and minor modes. (By contrast, M-S-x always omits
inapplicable commands from the completion candidates.)
By default, read-extended-command-predicate
is nil
, and
completion in M-x lists all the commands that match what the
user has typed, whether those commands are or aren’t marked as
applicable to the current buffer’s mode.
Marking commands to be applicable to a mode will also make C-h m list these commands (if they aren’t bound to any keys).
If using this extended interactive
form isn’t convenient
(because the code is supposed to work in older versions of Emacs that
don’t support the extended interactive
form), the following
equivalent declaration (see The declare
Form) can be used instead:
(declare (modes dired-mode))
Which commands to tag with modes is to some degree a matter of taste, but commands that clearly do not work outside of the mode should be tagged. This includes commands that will signal an error if called from somewhere else, but also commands that are destructive when called from an unexpected mode. (This usually includes most of the commands that are written for special (i.e., non-editing) modes.)
Some commands may be harmless, and “work” when called from other
modes, but should still be tagged with a mode if they don’t actually
make much sense to use elsewhere. For instance, many special modes
have commands to exit the buffer bound to q, and may not do
anything but issue a message like "Goodbye from this mode" and then
call kill-buffer
. This command will “work” from any mode,
but it is highly unlikely that anybody would actually want to use the
command outside the context of this special mode.
Many modes have a set of different commands that start the mode in
different ways (e.g., eww-open-in-new-buffer
and
eww-open-file
). Commands like that should never be tagged as
mode-specific, as they can be issued by the user from pretty much any
context.