22.1 Обзор цикла команд

Первое, что должен сделать цикл команд — это прочитать ключевую последовательность, которая представляет собой последовательность событий ввода, преобразуемую в команду. Он делает это, вызывая функцию read-key-sequence. Lisp-программы также могут вызывать эту функцию (см. Ввод ключевой последовательности). Они также могут читать ввод на более низком уровне с помощью read-key или read-event (см. Чтение одного события) или отбрасывать ожидающий ввод с помощью discard-input (см. Разные возможности ввода событий).

Ключевая последовательность преобразуется в команду через текущие активные карты клавиш. См. Поиск по клавишам для получения информации о том, как это делается. Результатом должна быть клавиатурная макрокоманда или интерактивно вызываемая функция. Если клавиша — M-x, то она читает имя другой команды, которую затем вызывает. Это выполняется командой execute-extended-command (см. Интерактивный вызов).

Перед выполнением команды Emacs запускает undo-boundary для создания границы отмены. См. Поддержка списков отмены.

Чтобы выполнить команду, Emacs сначала читает её аргументы, вызывая command-execute (см. Интерактивный вызов). Для команд, написанных на Lisp, спецификация interactive определяет, как читать аргументы. При этом может использоваться префиксный аргумент (см. Аргументы префиксных команд) или чтение с подсказкой в минибуфере (см. Минибуферы). Например, команда find-file имеет спецификацию interactive, которая предписывает читать имя файла с использованием минибуфера. Тело функции find-file не использует минибуфер, поэтому если вы вызываете find-file как функцию из Lisp-кода, вы должны передать строку с именем файла как обычный аргумент Lisp-функции.

Если команда является клавиатурной макрокомандой (т.е. строкой или вектором), Emacs выполняет её с помощью execute-kbd-macro (см. Клавиатурные макрокоманды).

Переменная: pre-command-hook

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

Переменная: post-command-hook

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

Этот хук также запускается, когда Emacs впервые входит в цикл команд (в этот момент this-command и last-command равны nil).

Выход подавляется во время выполнения pre-command-hook и post-command-hook. Если во время выполнения одного из этих хуков происходит ошибка, она не завершает выполнение хука; вместо этого ошибка игнорируется, а функция, в которой произошла ошибка, удаляется из хука.

Запрос, поступающий в сервер Emacs (см. Сервер Emacs в Руководство GNU Emacs), запускает эти два хука так же, как и команда клавиатуры.

Обратите внимание, что когда текст буфера содержит очень длинные строки, эти два хука вызываются так, как если бы они находились в форме with-restriction (см. Ограничение) с меткой long-line-optimizations-in-command-hooks и с буфером, ограниченным областью вокруг точки.