Создание карт клавиш
Здесь описаны функции для создания карт клавиш.
- Функция: make-sparse-keymap &optional prompt
-
Эта функция создаёт и возвращает новую разреженную карту клавиш без записей. (Разреженная карта клавиш — это тип карты, который обычно требуется.) Новая карта клавиш не содержит таблицу символов, в отличие от
make-keymap, и не связывает ни с какими событиями.(make-sparse-keymap) ⇒ (keymap)Если указать prompt, он становится общей строкой-приглашением для карты клавиш. Указывать её следует только для карт клавиш меню (см. Определение меню). Карта клавиш с общей строкой-приглашением всегда будет отображать меню мыши или меню клавиатуры, если она активна при поиске следующего события ввода. Не указывайте общую строку-приглашение для основной карты главного или второстепенного режима, поскольку это приведёт к тому, что цикл команд будет отображать меню клавиатуры при каждом вызове.
- Функция: make-keymap &optional prompt
-
Эта функция создаёт и возвращает новую полную карту клавиш. Эта карта содержит таблицу символов (см. Таблицы символов) со слотами для всех символов без модификаторов. Новая карта клавиш изначально связывает все эти символы с
nilи не связывает с событиями других типов. Аргумент prompt задаёт строку-приглашение, как и вmake-sparse-keymap.(make-keymap) ⇒ (keymap #^[nil nil keymap nil nil nil ...])Полная карта клавиш эффективнее разреженной, если содержит много привязок; если их всего несколько, лучше использовать разреженную карту.
- Функция: define-keymap &key options... &rest pairs...
-
Можно создать карту клавиш с помощью описанных выше функций, а затем использовать
keymap-set(см. Изменение привязок клавиш), чтобы задать привязки клавиш в этой карте. Однако при написании режимов часто приходится одновременно привязывать большое количество клавиш, а использовать для всех нихkeymap-setможет быть утомительно и чревато ошибками. Вместо этого можно воспользоватьсяdefine-keymap, которая создаёт карту клавиш и привязывает несколько клавиш. Вот очень простой пример:(define-keymap "n" #'forward-line "f" #'previous-line "C-c C-c" #'quit-window)
Эта функция создаёт новую разреженную карту клавиш, определяет в ней нажатия клавиш из pairs и возвращает новую карту. Если в pairs имеются повторяющиеся привязки клавиш, функция сигнализирует об ошибке.
pairs — это список чередующихся привязок клавиш и определений клавиш, принимаемый
keymap-set. Кроме того, клавишей может быть специальный символ:menu; в этом случае определение должно быть определением меню, принимаемымeasy-menu-define(см. Простое меню). Вот краткий пример такого использования:(define-keymap :full t "g" #'eww-reload :menu '("Eww" ["Exit" quit-window t] ["Reload" eww-reload t]))Перед парами клавиша/определение можно указать несколько ключевых слов, чтобы изменить свойства новой карты клавиш. Если при вызове
define-keymapотсутствует какое-либо ключевое слово свойства, для этого свойства используется значение по умолчаниюnil. Вот список доступных ключевых слов свойств::full-
Если значение не равно
nil, создаётся карта клавиш с таблицей символов (как при вызовеmake-keymap), а не разреженная карта клавиш (как при вызовеmake-sparse-keymap(см. Создание карт клавиш). По умолчанию создаётся разреженная карта клавиш. :parent-
Если значение не равно
nil, оно должно быть картой клавиш, используемой в качестве родительской (см. Наследование и карты клавиш). :keymap-
Если значение не равно
nil, оно должно быть картой клавиш. Вместо создания новой карты клавиш изменяется указанная карта. :suppress-
Если значение не равно
nil, карта клавиш будет подавлена с помощьюsuppress-keymap(см. Изменение привязок клавиш). По умолчанию цифры и знак минуса не подавляются, но если значение равноnodigits, цифры и знак минуса подавляются так же, как и другие символы. :name-
Если значение не равно
nil, оно должно быть строкой, используемой в качестве меню карты клавиш, если вы используете её как меню с помощьюx-popup-menu(см. Всплывающие меню). :prefixЕсли значение не равно
nil, оно должно быть символом, используемым в качестве префиксной команды (см. Префиксные клавиши). В этом случаеdefine-keymapвозвращает этот символ, а не саму карту.
- Макрос: defvar-keymap name &key options... &rest pairs...
-
Чаще всего карту клавиш связывают с переменной. Именно так поступают практически все режимы: у режима с названием
fooпочти всегда есть переменная с именемfoo-mode-map.Этот макрос определяет name как переменную, передаёт options и pairs в
define-keymapи использует полученный результат в качестве значения переменной по умолчанию. Если в pairs имеются повторяющиеся привязки клавиш, макрос сигнализирует об ошибке.options во многом подобен ключевым словам в
define-keymap. Кроме того, имеется ключевое слово:doc, задающее строку документации определяемой переменной. Вот пример:(defvar-keymap eww-textarea-map :parent text-mode-map :doc "Keymap for the eww text area." "RET" #'forward-line "TAB" #'shr-next-link)
Ключевое слово
:prefixможет принимать дополнительное значениеt, которое является сокращением для использования name в качестве значения этого параметра. То есть вместо записи(defvar-keymap foo-map :prefix 'foo-map ...)
можно написать
(defvar-keymap foo-map :prefix t ...)
Каждую команду в карте клавиш можно пометить как «повторяемую», то есть доступную в
repeat-mode, добавив к ней свойствоrepeat-map, например:(put 'undo 'repeat-map 'undo-repeat-map)
где значение свойства — это карта, используемая
repeat-mode.Чтобы не вызывать
putмногократно, вdefvar-keymapтакже имеется ключевое слово:repeat, с помощью которого можно указать, какие команды в карте клавиш доступны вrepeat-mode. Доступны следующие значения:t-
Это означает, что все команды в карте клавиш являются повторяемыми; такой вариант используется чаще всего.
(:enter (commands ...) :exit (commands ...):continue (commands ...) :hints ((command . "hint") ...))-
Эти параметры указывают, что команды из списка
:enterзапускаютrepeat-mode, а команды из списка:exitзавершают режим повтора.Если список
:enterпуст, все команды в карте запускаютrepeat-mode. Указание одной или нескольких команд в этом списке полезно, если в определяемой карте отсутствует команда, которая должна иметь свойствоrepeat-map.Если список
:exitпуст, ни одна команда в карте не завершаетrepeat-mode. Указание одной или нескольких команд в этом списке полезно, если определяемая карта клавиш содержит команду, которая не должна иметь свойствоrepeat-map.Список
:continueзадаёт команды, которые не должны запускатьrepeat-mode. Такие команды должны лишь продолжать уже активированную последовательность повторов.Список
:hintsможет содержать пары cons, где CAR — это команда, а CDR — строка, отображаемая в области эха рядом с повторяемой клавишей.
Чтобы, например, клавиша u повторяла команду
undo, эквивалентны следующие два фрагмента:(defvar-keymap undo-repeat-map "u" #'undo) (put 'undo 'repeat-map 'undo-repeat-map)
и
(defvar-keymap undo-repeat-map :repeat t "u" #'undo)
Второй вариант предпочтителен, если в карте много команд и все они должны быть повторяемыми.
- Функция: copy-keymap keymap
-
Эта функция возвращает копию keymap. Такая операция почти никогда не требуется. Если нужна карта клавиш, похожая на другую, но с несколькими изменениями, следует использовать наследование карт, а не копирование. То есть что-то вроде:
(let ((map (make-sparse-keymap))) (set-keymap-parent map <theirmap>) (keymap-set map ...) ...)
При
copy-keymapвсе карты клавиш, непосредственно присутствующие в keymap в качестве привязок, также рекурсивно копируются, и так далее на любое количество уровней. Однако рекурсивное копирование не выполняется, если определением символа является символ, функциональное определение которого — карта клавиш; в новой копии остаётся тот же символ.(setq map (copy-keymap (current-local-map))) ⇒ (keymap
;; (This implements meta characters.) (27 keymap (83 . center-paragraph) (115 . center-line)) (9 . tab-to-tab-stop))(eq map (current-local-map)) ⇒ nil(equal map (current-local-map)) ⇒ t
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/Creating-Keymaps.html