22.5 Информация из командного цикла

Редакторский командный цикл устанавливает несколько переменных Lisp для ведения записей о своём состоянии и состоянии выполняемых команд. За исключением this-command и last-command, обычно не рекомендуется изменять какие-либо из этих переменных в программе на Lisp.

Переменная: last-command

Эта переменная хранит имя предыдущей команды, выполненной командным циклом (той, что перед текущей командой). Обычно значением является символ с определением функции, но это не гарантируется.

Значение копируется из this-command, когда команда возвращает управление командному циклу, за исключением случая, когда команда задала префиксный аргумент для следующей команды.

Эта переменная всегда локальна для текущего терминала и не может быть локальной для буфера. См. Несколько терминалов.

Переменная: real-last-command

Эта переменная устанавливается Emacs так же, как last-command, но никогда не изменяется программами на Lisp.

Переменная: last-repeatable-command

Эта переменная хранит самую последнюю выполненную команду, которая не была частью события ввода. Это ту команду, которую repeat попытается повторить. См. Повторение в Руководстве по GNU Emacs.

Переменная: this-command

Эта переменная хранит имя команды, выполняемой в данный момент редакторским командным циклом. Как и last-command, это обычно символ с определением функции.

Командный цикл устанавливает эту переменную непосредственно перед выполнением команды и копирует её значение в last-command по завершении команды (если команда не задала префиксный аргумент для следующей команды).

Некоторые команды устанавливают эту переменную во время своего выполнения как флаг для следующей выполняемой команды. В частности, функции для вырезания текста устанавливают this-command в kill-region, чтобы любые команды вырезания, следующие непосредственно за ними, знали, что нужно добавить вырезанный текст к предыдущему вырезанию.

Если вы не хотите, чтобы конкретная команда распознавалась как предыдущая в случае, когда она завершилась ошибкой, вы должны запрограммировать эту команду так, чтобы предотвратить это. Один из способов — установить this-command в t в начале команды и вернуть this-command к правильному значению в конце, например так:

(defun foo (args…)
  (interactive …)
  (let ((old-this-command this-command))
    (setq this-command t)
    …выполнить работу…
    (setq this-command old-this-command)))

Мы не связываем this-command с помощью let, потому что это восстановило бы старое значение в случае ошибки — особенность let, которая в данном случае делает именно то, чего мы хотим избежать.

Переменная: this-original-command

Эта переменная имеет то же значение, что и this-command, за исключением случая, когда происходит переназначение команд (см. Переназначение команд). В этом случае this-command даёт команду, которая выполняется на самом деле (результат переназначения), а this-original-command даёт команду, которая была указана для выполнения, но была переназначена на другую команду.

Переменная: current-minibuffer-command

Эта переменная имеет то же значение, что и this-command, но связывается рекурсивно при входе в минибуфер. Эту переменную можно использовать из хуков минибуфера и подобных им, чтобы определить, какая команда открыла текущий сеанс минибуфера.

Функция: this-command-keys

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

Однако, если команда вызывала read-key-sequence, она возвращает последнюю прочитанную последовательность клавиш. См. Ввод последовательности клавиш. Значением является строка, если все события в последовательности были символами, помещающимися в строку. См. События ввода.

(this-command-keys)
;; Теперь используйте C-u C-x C-e для вычисления этого.
     ⇒ "^X^E"
Функция: this-command-keys-vector

Как this-command-keys, но всегда возвращает события в векторе, так что вам не нужно иметь дело со сложностями хранения событий ввода в строке (см. Размещение событий клавиатуры в строках).

Функция: clear-this-command-keys &optional keep-record

Эта функция очищает таблицу событий для возвращаемого значения this-command-keys. Если keep-record не равен nil, она также очищает записи, которые функция recent-keys (см. Запись ввода) будет возвращать впоследствии. Это полезно после чтения пароля, чтобы предотвратить случайное нежелательное отображение пароля как части следующей команды в некоторых случаях.

Переменная: last-nonmenu-event

Эта переменная хранит последнее событие ввода, прочитанное как часть последовательности клавиш, не считая событий, возникших в результате меню мыши.

Одно из применений этой переменной — указание x-popup-menu, где нужно открыть меню. Она также используется внутренне y-or-n-p (см. Запросы «Да или Нет»).

Переменная: last-command-event

Эта переменная устанавливается равной последнему событию ввода, которое было прочитано командным циклом как часть команды. Основное применение этой переменной — в self-insert-command, которая использует её для определения того, какой символ вставить, и в post-self-insert-hook (см. Команды вставки пользовательского уровня), который использует её для доступа к только что вставленному символу.

last-command-event
;; Теперь используйте C-u C-x C-e для вычисления этого.
     ⇒ 5

Значение равно 5, потому что это код ASCII для C-e.

Переменная: last-event-frame

Эта переменная хранит фрейм, на который было направлено последнее событие ввода. Обычно это фрейм, который был выбран в момент генерации события, но если этот фрейм перенаправил фокус ввода на другой фрейм, значением является фрейм, на который было перенаправлено событие. См. Фокус ввода.

Если последнее событие поступило из макроса клавиатуры, значением является macro.

События ввода должны откуда-то поступать; иногда это макрос клавиатуры, сигнал или unread-command-events, но обычно это физическое устройство ввода, подключённое к компьютеру, управляемое пользователем. Эти устройства называются устройствами ввода, и Emacs связывает каждое событие ввода с устройством ввода, из которого оно произошло. Они идентифицируются по имени, уникальному для каждого устройства ввода.

Возможность определения точного используемого устройства ввода зависит от деталей каждой системы. Когда такая информация недоступна, Emacs сообщает о событиях клавиатуры как исходящих от «"Virtual core keyboard"», а о других событиях как исходящих от «"Virtual core pointer"». (Эти значения используются на всех платформах, потому что X-сервер сообщает их, когда детальная информация об устройстве неизвестна.)

Переменная: last-event-device

Эта переменная хранит имя устройства ввода, на котором было сгенерировано последнее прочитанное событие ввода. Она равна nil, если такого устройства не существует, т.е. последнее событие ввода было прочитано из unread-command-events или поступило из макроса клавиатуры.

При использовании расширения X Input Extension в X Windows имя устройства является строкой, уникальной для каждой физической клавиатуры, указывающего устройства и сенсорного экрана, подключённых к X-серверу. В противном случае это либо строка «"Virtual core pointer"», либо «"Virtual core keyboard"», в зависимости от того, было ли событие сгенерировано указывающим устройством (например, мышью) или клавиатурой.

Функция: device-class frame name

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

Возвращаемое значение является одним из следующих символов («классы устройств»):

core-keyboard

Основная клавиатура; это означает, что устройство похоже на клавиатуру, но другие характеристики неизвестны.

core-pointer

Основной указатель; это означает, что устройство является указывающим устройством, но другие характеристики неизвестны.

mouse

Компьютерная мышь.

trackpoint

Трекпоинт или джойстик (или другое подобное устройство управления).

eraser

Другой конец стилуса на графическом планшете или отдельный ластик.

pen

Заострённый конец пера на графическом планшете, стилус или другое подобное устройство.

puck

Устройство, похожее на компьютерную мышь, но сообщающее абсолютные координаты относительно некоторой другой поверхности.

power-button

Кнопка питания или кнопка громкости (или другое подобное управление).

keyboard

Компьютерная клавиатура.

touchscreen

Компьютерная сенсорная панель.

pad

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

touchpad

Косвенное сенсорное устройство, такое как тачпад.

piano

Музыкальный инструмент, например, электронная клавиатура.

test

Устройство, используемое расширением XTEST для сообщения о вводе.