22.3 Интерактивный вызов

После того как цикл команд преобразует последовательность клавиш в команду, он вызывает эту команду с помощью функции command-execute. Если команда является функцией, command-execute вызывает call-interactively, которая считывает аргументы и вызывает команду. Вы также можете вызывать эти функции самостоятельно.

Обратите внимание, что термин «команда» в данном контексте относится к функции (или объекту, подобному функции), вызываемой интерактивно, или к клавиатурному макросу. Он не относится к последовательности клавиш, используемой для вызова команды (см. Клавишные карты).

Функция: commandp object &optional for-call-interactively

Эта функция возвращает t, если object является командой. В противном случае она возвращает nil.

Команды включают строки и векторы (которые рассматриваются как клавиатурные макросы), лямбда-выражения, содержащие форму interactive верхнего уровня (см. Использование interactive), объекты байт-кода функций, созданные из таких лямбда-выражений, объекты автозагрузки, объявленные как интерактивные (не nil четвёртый аргумент для autoload), и некоторые примитивные функции. Кроме того, символ считается командой, если он имеет свойство interactive-form со значением, не равным nil, или если его определение функции удовлетворяет условию commandp.

Если for-call-interactively не равен nil, то commandp возвращает t только для объектов, которые может вызвать call-interactively, — то есть не для клавиатурных макросов.

См. documentation в Доступ к строкам документации для реалистичного примера использования commandp.

Функция: call-interactively command &optional record-flag keys

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

Например, если у вас есть функция со следующей сигнатурой:

(defun foo (begin end)
  (interactive "r")
  ...)

то вызов

(call-interactively 'foo)

вызовет foo с областью выделения (point и mark) в качестве аргументов.

Сигнализируется ошибка, если command не является функцией или если её нельзя вызвать интерактивно (т.е. она не является командой). Обратите внимание, что клавиатурные макросы (строки и векторы) не принимаются, даже несмотря на то, что они считаются командами, потому что они не являются функциями. Если command является символом, то call-interactively использует его определение функции.

Если record-flag не равен nil, то эта команда и её аргументы безусловно добавляются в список command-history. В противном случае команда добавляется, только если она использует минибуфер для чтения аргумента. См. История команд.

Аргумент keys, если задан, должен быть вектором, который определяет последовательность событий для передачи, если команда запрашивает, какие события использовались для её вызова. Если keys опущен или равен nil, по умолчанию используется возвращаемое значение this-command-keys-vector. См. Определение this-command-keys-vector.

Функция: funcall-interactively function &rest arguments

Эта функция работает подобно funcall (см. Вызов функций), но делает вызов похожим на интерактивное обращение: вызов called-interactively-p внутри function вернёт t. Если function не является командой, она вызывается без сигнализации ошибки.

Функция: command-execute command &optional record-flag keys special

Эта функция выполняет command. Аргумент command должен удовлетворять предикату commandp; т.е. он должен быть интерактивно вызываемой функцией или клавиатурным макросом.

Строка или вектор в качестве command выполняются с помощью execute-kbd-macro. Функция передаётся в call-interactively (см. выше) вместе с аргументами record-flag и keys.

Если command является символом, вместо него используется его определение функции. Символ с определением autoload считается командой, если он был объявлен как представляющий интерактивно вызываемую функцию. Такое определение обрабатывается путём загрузки указанной библиотеки и последующей повторной проверки определения символа.

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

Команда: execute-extended-command prefix-argument

Эта функция считывает имя команды из минибуфера с использованием completing-read (см. Дополнение). Затем она использует command-execute для вызова указанной команды. Всё, что возвращает эта команда, становится значением execute-extended-command.

Если команда запрашивает префиксный аргумент, она получает значение prefix-argument. Если execute-extended-command вызывается интерактивно, для prefix-argument используется текущий сырой префиксный аргумент, который таким образом передаётся выполняемой команде.

execute-extended-command является обычным определением для M-x, поэтому в качестве приглашения используется строка ‘M-x ’. (Было бы лучше брать приглашение из событий, использованных для вызова execute-extended-command, но это сложно реализовать.) Описание значения префиксного аргумента, если он есть, также становится частью приглашения.

(execute-extended-command 3)
---------- Буфер: Минибуфер ----------
3 M-x forward-word RET
---------- Буфер: Минибуфер ----------
     ⇒ t

Эта команда учитывает переменную read-extended-command-predicate, которая может отфильтровывать команды, неприменимые в текущем основном режиме (или включённых второстепенных режимах). По умолчанию значение этой переменной равно nil, и никакие команды не отфильтровываются. Однако настройка на вызов функции command-completion-default-include-p будет выполнять фильтрацию, зависящую от режима. read-extended-command-predicate может быть любой функцией-предикатом; она будет вызвана с двумя параметрами: символом команды и текущим буфером. Она должна возвращать не nil, если команда должна включаться при дополнении в этом буфере.

Команда: execute-extended-command-for-buffer prefix-argument

Эта команда подобна execute-extended-command, но ограничивает команды, предлагаемые для дополнения, только теми, которые имеют особое отношение к текущему основному режиму (и включённым второстепенным режимам). Это включает команды, помеченные режимами (см. Использование interactive), а также команды, привязанные к локально активным клавишным картам. Эта команда является обычным определением для M-S-x (то есть «мета шифт x»).

Обе эти команды запрашивают имя команды, но с разными правилами дополнения. Вы можете переключаться между этими двумя режимами, используя команду M-S-x во время запроса.