Указание режимов для команд
Многие команды в Emacs являются универсальными и не привязаны к какому-либо конкретному режиму. Например, M-x kill-region можно использовать практически в любом режиме, где есть редактируемый текст, а команды, отображающие информацию (например, M-x list-buffers), можно использовать почти в любом контексте.
Однако многие другие команды привязаны к определённому режиму и не имеют смысла вне этого контекста. Например, M-x
dired-diff просто выдаст ошибку, если использовать её вне буфера Dired.
Поэтому в Emacs есть механизм, позволяющий указать, к какому режиму (или режимам) «относится» команда:
(defun dired-diff (...) ... (interactive "p" dired-mode) ...)
Это пометит команду как применимую только к dired-mode (или к любым режимам, производным от dired-mode). В форму interactive можно добавить любое количество режимов.
Указание режимов влияет на автодополнение команд в M-S-x (execute-extended-command-for-buffer, см. Интерактивный вызов). Оно также может влиять на автодополнение в M-x в зависимости от значения read-extended-command-predicate.
Например, если использовать предикат command-completion-default-include-p в качестве значения read-extended-command-predicate, M-x не будет выводить команды, помеченные как применимые к определённому режиму (если только вы не находитесь в буфере, использующем этот режим, разумеется). Это относится и к основным, и к вспомогательным режимам. (В отличие от этого, M-S-x всегда исключает неприменимые команды из списка вариантов автодополнения.)
По умолчанию read-extended-command-predicate равно nil, и автодополнение в M-x показывает все команды, соответствующие введённому пользователем тексту, независимо от того, помечены ли эти команды как применимые к режиму текущего буфера.
Пометка команд как применимых к режиму также приводит к тому, что C-h m выводит эти команды (если они не привязаны ни к каким клавишам).
Если использовать эту расширенную форму interactive неудобно (например, потому что код должен работать в старых версиях Emacs, не поддерживающих расширенную форму interactive), вместо неё можно использовать следующее эквивалентное объявление (см. Форма declare):
(declare (modes dired-mode))
Выбор команд, которые следует пометить режимами, в некоторой степени зависит от предпочтений, но команды, которые явно не работают вне режима, следует помечать. К ним относятся команды, которые выдают ошибку при вызове из другого контекста, а также команды, деструктивные при вызове из неожиданного режима. (Обычно сюда относится большинство команд, написанных для специальных (то есть не предназначенных для редактирования) режимов.)
Некоторые команды могут быть безвредными и «работать» при вызове из других режимов, но их всё равно следует пометить режимом, если их использование в других режимах не имеет особого смысла. Например, во многих специальных режимах есть команды для выхода из буфера, привязанные к q. Они могут лишь выводить сообщение вроде «Работа в этом режиме завершена», а затем вызывать kill-buffer. Эта команда будет «работать» в любом режиме, но вряд ли кто-то захочет использовать её вне контекста этого специального режима.
Во многих режимах есть набор различных команд, запускающих режим разными способами (например, eww-open-in-new-buffer и eww-open-file). Такие команды никогда не следует помечать как специфичные для режима, поскольку пользователь может вызвать их практически из любого контекста.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Command-Modes.html