有时无法或不方便预先创建包含所有预期补全项的 alist 或 obarray。 在这种情况下,你可以提供自己的函数来计算给定字符串的补全。 这被称为 可编程补全。 Emacs 在补全文件名(see 文件名补全)等许多场景中都会使用可编程补全。
要使用此功能,需将一个函数作为 collection 参数传递给 completing-read。
completing-read 会将你的补全函数传递给 try-completion、
all-completions 以及其他基础补全函数,由你的函数完成全部工作。
补全函数应当接受三个参数:
nil。
该函数应当对每个可能的匹配项调用谓词,
若谓词返回 nil 则忽略该匹配项。
nil指定执行 try-completion 操作。
若无匹配项,函数应返回 nil;
若指定字符串是唯一且精确的匹配,返回 t;
否则返回所有匹配项的最长公共前缀子串。
t指定执行 all-completions 操作。
函数应返回指定字符串的所有可能补全项列表。
lambda指定执行 test-completion 操作。
若指定字符串是某个补全候选项的精确匹配,函数应返回 t,否则返回 nil。
(boundaries . suffix)指定执行 completion-boundaries 操作。
函数应返回 (boundaries start . end),
其中 start 是指定字符串中起始边界的位置,
end 是 suffix 中结束边界的位置。
如果 Lisp 程序返回了非平凡边界,
必须确保 all-completions 操作与其保持一致。
all-completions 返回的补全项应只对应补全边界所覆盖的前缀与后缀部分。
补全边界的确切预期语义参见 See 基础补全函数。
metadata ¶请求获取当前补全状态的相关信息。
返回值应具有形式 (metadata . alist),
其中 alist 是一个关联列表,其元素在下面说明。
如果标志是其他值,补全函数应返回 nil。
下面是补全函数在响应 metadata 标志时可以返回的元数据条目列表:
category ¶值应为一个符号,描述补全函数试图补全的文本类型。
如果该符号与 completion-category-overrides 中的某个键匹配,
则覆盖常规补全行为。See 补全相关变量。
annotation-function ¶值应为一个用于对补全项进行 注释(annotating) 的函数。
该函数接受一个参数 string,即一个可能的补全项,
并返回一个字符串,显示在 *Completions* 缓冲区中补全字符串的后面。
除非该函数自行对注释后缀字符串设置 face,
否则默认会为该字符串应用 completions-annotations face。
affixation-function ¶值应为一个用于为补全项添加前缀和后缀的函数。
该函数接受一个参数 completions,即补全项列表,
并返回同样格式的补全项列表,其中每个元素是一个三元素列表:
补全项、在 *Completions* 缓冲区中显示在补全字符串前的前缀、
以及显示在补全字符串后的后缀。
该函数优先级高于 annotation-function。
group-function ¶值应为一个用于对补全候选项分组的函数。
该函数必须接受两个参数:completion(补全候选项)
和 transform(布尔标志)。
若 transform 为 nil,函数必须返回该候选项所属分组的标题,
返回的标题也可以是 nil。
否则函数必须返回转换后的候选项。
转换操作可以例如去掉冗余前缀,该前缀会显示在分组标题中。
display-sort-function ¶值应为一个用于对补全项排序的函数。 该函数接受一个参数(补全字符串列表),并返回排序后的补全字符串列表。 允许破坏性地修改输入列表。
cycle-sort-function ¶当 completion-cycle-threshold 非 nil
且用户正在循环切换补全候选项时,用于对补全项排序的函数。
See Completion Options in The GNU Emacs Manual。
其参数列表与返回值和 display-sort-function 相同。
该函数是编写可编程补全函数的便捷方式。
参数 function 应是一个单参数函数,参数为字符串,
返回包含所有可能补全项的补全表(see 基础补全函数)。
function 返回的表中也可以包含与参数字符串不匹配的元素,
它们会被 completion-table-dynamic 自动过滤掉。
特别地,function 可以忽略其参数并返回所有可能补全项的完整列表。
你可以将 completion-table-dynamic 看作
function 与可编程补全函数接口之间的转换器。
如果可选参数 switch-buffer 非 nil,
且补全在小缓冲区中执行,
调用 function 时会将当前缓冲区设为进入小缓冲区的源缓冲区。
completion-table-dynamic 的返回值是一个函数,
可用作 try-completion 和 all-completions 的第二个参数。
注意,该函数总是返回空元数据和平凡边界。
这是 completion-table-dynamic 的包装器,
会保存上一次的参数与结果对。
这意味着使用相同参数的多次查找只需调用一次 function。
当涉及较慢操作(如调用外部进程)时,这会很有用。