Здесь мы описываем функции для создания клавиатурных карт.
Эта функция создаёт и возвращает новую разреженную клавиатурную карту без записей.
(Разреженная клавиатурная карта — это тот вид карты, который вам обычно нужен.) Новая
карта не содержит символьной таблицы, в отличие от make-keymap, и
не связывает никакие события.
(make-sparse-keymap)
⇒ (keymap)
Если вы указываете prompt, он становится общей строкой приглашения для клавиатурной карты. Вам следует указывать это только для карт меню (см. Определение меню). Клавиатурная карта с общей строкой приглашения всегда будет показывать меню мыши или клавиатурное меню, если она активна для поиска следующего входного события. Не указывайте общую строку приглашения для основной карты главного или второстепенного режима, потому что это заставит командный цикл каждый раз показывать клавиатурное меню.
Эта функция создаёт и возвращает новую полную клавиатурную карту. Эта карта
содержит символьную таблицу (см. Символьные таблицы) с ячейками для всех
символов без модификаторов. Новая карта изначально связывает все
эти символы с nil и не связывает никакие другие виды
событий. Аргумент prompt задаёт
строку приглашения, как в make-sparse-keymap.
(make-keymap)
⇒ (keymap #^[nil nil keymap nil nil nil …])
Полная клавиатурная карта эффективнее разреженной, когда она содержит много связываний; для небольшого числа связываний лучше разреженная карта.
Вы можете создать клавиатурную карту с помощью описанных выше функций, а затем
использовать 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"
["Выход" quit-window t]
["Перезагрузить" 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 возвращает этот символ, а не саму карту.
Наиболее частое действие с клавиатурной картой — это связывание её с
переменной. Именно так поступают практически все режимы — режим
foo почти всегда имеет переменную с именем foo-mode-map.
Этот макрос определяет name как переменную, передаёт options
и pairs в define-keymap и использует результат как
значение по умолчанию для переменной. Он сигнализирует об ошибке, если
в pairs есть повторяющиеся связывания клавиш.
options подобен ключевым словам в define-keymap, но
есть дополнительное ключевое слово :doc, которое задаёт строку
документации для определяемой переменной.
Вот пример:
(defvar-keymap eww-textarea-map :parent text-mode-map :doc "Клавиатурная карта для текстовой области eww." "RET" #'forward-line "TAB" #'shr-next-link)
Каждая команда в клавиатурной карте может быть помечена как «повторяемая», т.е. пригодная
для использования в repeat-mode, путём добавления к ней свойства repeat-map,
например:
(put 'undo 'repeat-map 'undo-repeat-map)
где значением свойства является карта, используемая repeat-mode.
Чтобы избежать повторяющихся вызовов put, defvar-keymap
также имеет ключевое слово :repeat, которое можно использовать для указания,
какие команды в клавиатурной карте могут использоваться repeat-mode.
Доступны следующие значения:
tЭто означает, что все команды в клавиатурной карте являются повторяемыми, и это наиболее распространённый способ использования.
(:enter (commands ...) :exit (commands ...) :hints ((command . "подсказка") ...))Это указывает, что команды в списке :enter входят в
repeat-mode, а команды в списке :exit выходят из
режима повторения.
Если список :enter пуст, то все команды в карте входят в
repeat-mode. Указание одной или нескольких команд в этом списке
полезно, если есть команда, которой нет в определяемой карте,
но которая должна иметь свойство repeat-map.
Если список :exit пуст, то ни одна команда в карте не выходит из
repeat-mode. Указание одной или нескольких команд в этом списке
полезно, если определяемая клавиатурная карта содержит команду, которая не должна
иметь свойства repeat-map.
Список :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)
Последний способ предпочтительнее, когда в карте много команд, и все они должны быть повторяемыми.
Эта функция возвращает копию keymap. Это почти никогда не требуется. Если вам нужна клавиатурная карта, похожая на другую, но с небольшими изменениями, вам следует использовать наследование карт, а не копирование. Т.е. что-то вроде:
(let ((map (make-sparse-keymap))) (set-keymap-parent map <их-карта>) (keymap-set map ...) ...)
При выполнении copy-keymap любые клавиатурные карты, которые
непосредственно присутствуют как связывания в keymap, также рекурсивно копируются,
и так далее на любое количество уровней. Однако рекурсивное копирование не
выполняется, когда определением символа является символ, чьё
определение функции является клавиатурной картой; тот же символ появляется в новой копии.
(setq map (copy-keymap (current-local-map))) ⇒ (keymap
;; (Это реализует meta-символы.)
(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