Spec-Zone.ru › Elisp

Создание карт клавиш

Здесь описаны функции для создания карт клавиш.

Функция: 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API