22.3 交互式调用

命令循环将按键序列转换为命令后,会使用函数 command-execute 调用该命令。 如果命令是一个函数,command-execute 会调用 call-interactively, 由它读取参数并执行命令。你也可以自行调用这些函数。

注意,在此上下文中,术语“命令”指可交互式调用的函数(或类函数对象)或键盘宏。 它并不指代用于调用命令的按键序列(see 按键映射)。

Function: commandp object &optional for-call-interactively

如果 object 是命令,此函数返回 t,否则返回 nil

命令包括字符串和向量(被当作键盘宏)、 包含顶层 interactive 形式的 lambda 表达式(see 使用 interactive)、 由这类 lambda 表达式生成的字节码函数对象、 声明为交互式的自动加载对象(autoload 的第四个参数为非 nil), 以及一些原语函数。 此外,如果一个符号拥有非 nilinteractive-form 属性, 或者其函数定义满足 commandp,则该符号也被视为命令。

如果 for-call-interactively 为非 nil, 则 commandp 仅对 call-interactively 能够调用的对象返回 t—— 因此不包括键盘宏。

关于使用 commandp 的实际示例,参见 访问文档字符串 中的 documentation

Function: call-interactively command &optional record-flag keys

此函数调用可交互式函数 command,并根据其交互式调用规范提供参数。 它返回 command 的返回值。

例如,如果你有一个如下签名的函数:

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

那么执行:

(call-interactively 'foo)

会以区域(pointmark)作为参数调用 foo

如果 command 不是函数或无法被交互式调用(即不是命令),则会发出错误信号。 注意,键盘宏(字符串和向量)虽然被视为命令,但不被接受,因为它们不是函数。 如果 command 是符号,call-interactively 会使用其函数定义。

如果 record-flag 为非 nil, 则此命令及其参数会被无条件加入 command-history 列表。 否则,仅当命令使用小缓冲读取参数时才会被加入。see 命令历史

参数 keys 如果给出,应为一个向量, 用于指定当命令询问调用它的事件序列时所返回的事件。 如果 keys 被省略或为 nil, 默认使用 this-command-keys-vector 的返回值。 See Definition of this-command-keys-vector

Function: funcall-interactively function &rest arguments

此函数的工作方式类似 funcall(see 调用函数), 但会让调用看起来像是交互式调用: 在 function 内部调用 called-interactively-p 会返回 t。 如果 function 不是命令,也会直接调用而不报错。

Function: command-execute command &optional record-flag keys special

此函数执行 command。参数 command 必须满足 commandp 谓词; 即必须是可交互式调用的函数或键盘宏。

如果 command 是字符串或向量,则用 execute-kbd-macro 执行。 如果是函数,则连同 record-flagkeys 参数一起传给 call-interactively(见上文)。

如果 command 是符号,则使用其函数定义。 带有 autoload 定义的符号,如果被声明代表可交互式函数,则算作命令。 这类定义会通过加载指定库并重新检查符号定义来处理。

参数 special 如果给出,表示忽略前缀参数且不清除它。 这用于执行特殊事件(see 特殊事件)。

Command: execute-extended-command prefix-argument

此函数使用 completing-read(see 补全)从小缓冲读取命令名, 然后使用 command-execute 调用指定命令。 该命令的返回值即为 execute-extended-command 的返回值。

如果命令需要前缀参数,它会接收到 prefix-argument 的值。 如果 execute-extended-command 被交互式调用, 则当前原始前缀参数会被用作 prefix-argument, 并传递给所运行的任何命令。

execute-extended-command is the normal definition of M-x, 因此它使用字符串 ‘M-x  作为提示。 (更好的方式是从调用 execute-extended-command 的事件中获取提示, 但实现起来较为麻烦。) 前缀参数的值(如果有)的描述也会成为提示的一部分。

(execute-extended-command 3)
---------- Buffer: Minibuffer ----------
3 M-x forward-word RET
---------- Buffer: Minibuffer ----------
     ⇒ t

此命令遵守 read-extended-command-predicate 变量, 该变量可过滤掉不适用于当前主模式(或已启用的次要模式)的命令。 默认情况下,该变量的值为 nil,不会过滤任何命令。 但是,将其自定义为调用函数 command-completion-default-include-p 将会执行依赖于模式的过滤。 read-extended-command-predicate 可以是任意谓词函数; 它会被传入两个参数:命令的符号和当前缓冲区。 如果该命令应在该缓冲区的补全中出现,则应返回非 nil

Command: execute-extended-command-for-buffer prefix-argument

此命令类似 execute-extended-command, 但会将补全提供的命令限制为与当前主模式(及已启用的次要模式)特别相关的命令。 这包括被标记为对应模式的命令(see 使用 interactive), 以及绑定到本地活跃按键映射的命令。 此命令是 M-S-x(即 “meta+shift+x”)的默认绑定。

这两个命令都会提示输入命令名,但使用不同的补全规则。 你可以在提示时使用 M-S-x 命令在这两种模式之间切换。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike