Spec-Zone.ru › Elisp

Карты клавиш для преобразования последовательностей событий

Когда функция read-key-sequence считывает последовательность клавиш (см. раздел Ввод последовательностей клавиш), она использует карты трансляции клавиш для преобразования одних последовательностей событий в другие. Карты трансляции клавиш — это input-decode-map, local-function-key-map и key-translation-map (в порядке приоритета).

Карты трансляции клавиш имеют ту же структуру, что и другие карты клавиш, но используются иначе: они задают преобразования, выполняемые при считывании последовательностей клавиш, а не привязки для полных последовательностей клавиш. По мере считывания каждой последовательности клавиш она проверяется по каждой карте трансляции. Если одна из карт трансляции клавиш связывает k с вектором v, то всякий раз, когда k встречается как подпоследовательность в любом месте последовательности клавиш, эта подпоследовательность заменяется событиями из v.

Например, терминалы VT100 отправляют ESC O P при нажатии клавиши клавиатуры PF1. На таких терминалах Emacs должен преобразовать эту последовательность событий в одно событие pf1. Для этого в input-decode-map последовательность ESC O P связывается с [pf1]. Таким образом, когда вы вводите C-c PF1 в терминале, терминал отправляет последовательность символов C-c ESC O P, а read-key-sequence преобразует её обратно в C-c PF1 и возвращает как вектор [?\C-c pf1].

Карты трансляции начинают действовать только после того, как Emacs декодирует ввод с клавиатуры (с помощью системы кодирования ввода, заданной в keyboard-coding-system). См. раздел Кодирование ввода-вывода терминала.

Переменная: input-decode-map

Эта переменная содержит карту клавиш, описывающую последовательности символов, отправляемые функциональными клавишами обычного посимвольного терминала.

Значение input-decode-map обычно задаётся автоматически в соответствии с записью терминала в Terminfo или Termcap, однако иногда для этого требуются файлы Lisp, специфичные для данного терминала. Emacs поставляется с файлами для многих распространённых терминалов; их основное назначение — добавлять записи в input-decode-map, которые нельзя вывести из Termcap и Terminfo. См. раздел Инициализация для конкретного терминала.

Переменная: local-function-key-map

Эта переменная содержит карту клавиш, подобную input-decode-map, но описывающую последовательности клавиш, которые следует преобразовывать в альтернативные интерпретации, обычно предпочтительные. Она применяется после input-decode-map и до key-translation-map.

Записи в local-function-key-map игнорируются, если они конфликтуют с привязками в картах клавиш второстепенных режимов, локальной или глобальной карте. Иными словами, переназначение применяется только в том случае, если исходная последовательность клавиш иначе не имела бы никакой привязки.

local-function-key-map наследуется от function-key-map. Последнюю следует изменять только в том случае, если привязка должна применяться во всех терминалах, поэтому почти всегда предпочтительнее использовать первую.

Переменная: key-translation-map

Эта переменная представляет собой ещё одну карту клавиш, которая используется так же, как input-decode-map, для преобразования входных событий в другие события. Она отличается от input-decode-map тем, что начинает действовать после завершения работы local-function-key-map, а не до неё; она получает результаты преобразования, выполненного с помощью local-function-key-map.

Как и input-decode-map, но в отличие от local-function-key-map, эта карта клавиш применяется независимо от того, имеет ли входная последовательность клавиш обычную привязку. Однако обратите внимание, что фактические привязки клавиш могут влиять на key-translation-map, даже если эта карта имеет приоритет над ними. Действительно, фактические привязки клавиш имеют приоритет над local-function-key-map и поэтому могут изменить последовательность клавиш, которую получает key-translation-map. Очевидно, лучше избегать таких ситуаций.

Предполагается, что key-translation-map будет использоваться для преобразования одного набора символов в другой, в том числе обычных символов, обычно привязанных к self-insert-command.

С помощью input-decode-map, local-function-key-map и key-translation-map можно задавать не только простые псевдонимы: для преобразования клавиши можно использовать функцию вместо последовательности клавиш. В этом случае для вычисления преобразования этой клавиши вызывается функция.

Функция преобразования клавиш получает один аргумент — подсказку, заданную в read-key-sequence, или nil, если последовательность клавиш считывается циклом команд редактора. В большинстве случаев значение подсказки можно игнорировать.

Если функция сама считывает ввод, она может изменить следующее за ним событие. Например, вот как определить C-c h, чтобы следующий символ стал символом Hyper:

(defun hyperify (prompt)
  (let ((e (read-event)))
    (vector (if (numberp e)
                (logior (ash 1 24) e)
              (if (memq 'hyper (event-modifiers e))
                  e
                (add-event-modifier "H-" e))))))

(defun add-event-modifier (string e)
  (let ((symbol (if (symbolp e) e (car e))))
    (setq symbol (intern (concat string
                                 (symbol-name symbol))))
    (if (symbolp e)
        symbol
      (cons symbol (cdr e)))))

(keymap-set local-function-key-map "C-c h" 'hyperify)

Функции преобразования клавиш может понадобиться менять своё поведение в зависимости от параметров событий внутри последовательности клавиш, содержащей события, не являющиеся клавишами (см. раздел Входные события). Эти сведения доступны через переменную current-key-remap-sequence, которой присваивается подпоследовательность клавиш, преобразуемая в ходе вызовов функций преобразования клавиш.

  • Взаимодействие с обычными картами клавиш

Взаимодействие с обычными картами клавиш

Конец последовательности клавиш определяется, когда эта последовательность либо привязана к команде, либо Emacs определяет, что никакое дополнительное событие не может привести к последовательности, привязанной к команде.

Это означает, что, хотя input-decode-map и key-translation-map применяются независимо от того, имела бы исходная последовательность клавиш привязку или нет, такая привязка всё же может помешать преобразованию. Например, вернёмся к приведённому выше примеру с VT100 и добавим в глобальную карту привязку для C-c ESC; теперь, когда пользователь нажмёт C-c PF1, Emacs не сможет декодировать C-c ESC O P как C-c PF1, поскольку прекратит считывать клавиши сразу после C-c ESC, оставив O P на потом. Это необходимо на случай, если пользователь действительно нажал C-c ESC; тогда Emacs не должен ждать следующую клавишу, чтобы определить, действительно ли пользователь нажал ESC или PF1.

По этой причине лучше не привязывать команды к последовательностям клавиш, если конец последовательности является префиксом преобразуемой последовательности клавиш. Основные проблемные суффиксы/префиксы — это ESC, M-O (то есть ESC O) и M-[ (то есть ESC [).

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/Translation-Keymaps.html

Spec-Zone.ru

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