@legoscia 提供了一个很好的答案:completing-read 确实不 让您访问与它用于完成的键关联的值。例如,对于 alist COLLECTION 参数,它不会让您访问所选 alist 键的 cdr。
对于 alist,您可以使用 assoc 来获取 first 匹配 alist 元素,对于哈希表,您可以使用 maphash 或执行 get。
但是这些方法排除了获取与特定选择的键出现相关联的特定值当有 重复 key的,即当多个候选人有相同的key时,或者名字。
您无法获得第 2 个匹配元素或第 13 个。事实上,vanilla Emacs completing-read 消除了具有相同键(名称)的完成候选者的重复。对于普通 Emacs,alist 条目的 cdr 中的任何信息都被浪费了。为方便起见,您可以使用 alist,如果您已经有一个,但如果没有,那么您最好只使用名称列表(字符串或符号),而不是 conses。
如果您使用Icicles,则不会浪费 alist 条目。检索 cdr 值没有问题。在completing-read 完成后,您可以轻松获得所选候选人的完整信息。
Icicles 通过使用属性化字符串作为候选,并通过增强completing-read 来实现这一点,以便它可以返回用户选择的完整字符串、属性和所有内容。您可以从返回的属性化字符串中恢复完整的 alist 条目。
什么时候重要 能够拥有和使用具有不同关联值的重复键?如果它们是重复的,用户如何区分它们(例如,*Completions*)?
例子:
具有相同名称但用于不同目标的书签 - 例如,用于不同目录中具有相同相对名称的不同文件。
缓冲区中与模式匹配或包含标记的行或其他文本。这包括Icicles search 中的匹配项,您可以在其中以任何您喜欢的方式定义搜索上下文(不仅仅是行)。它还包括缓冲区(包括限制,也就是狭窄)和缓冲区位置(标记)。
具有相同文本但注释不同的候选人。 (用户输入与*Completions* 中显示的注释不匹配。)
具有相同名称的 Imenu 项,例如,具有相同名称的对象(例如函数)的多个定义。
具有相同名称的标记项(例如函数)。
可以具有相同名称的其他 Lisp 对象(例如框架)的候选对象。
在Icicles中,用户如何从多个同名的补全候选中选择一个?
用户可以控制候选人的顺序(排序),包括动态更改顺序。 *Completions* 按特定顺序向您显示它们。您可以在候选人之间循环或直接选择其中任何一个。你不限于匹配、选择。 (对于重复的候选人,匹配可能不足以让您只找到其中一个。)
*Completions* 还可以向您显示有关候选人的其他信息,即使他们具有相同的姓名/文本,也可以区分他们。此类信息可能是周围的文本(如果候选匹配缓冲区文本)或候选元数据(例如文件或书签属性)。
您还可以在模式行中查看有关当前候选者(例如在骑行期间)的重要附加信息。
您可以按一个键按需获取有关当前候选人的更多信息(完整的*Help*)。
你需要做什么,才能在你自己的代码中利用这个 Icicles 功能 ?
请参阅Defining Tripping Commands,了解如何定义您自己的命令,让用户在(探索)可能具有相关位置或其他导航信息的候选者之间穿行。 (有关预定义的 Icicles 触发命令,请参阅 Tripping。)
简要概述在您的命令中执行的操作:
将变量icicle-whole-candidate-as-text-prop-p绑定到非nil。
将变量 icicle-candidates-alist 设置为您传递给 completing-read 的 alist。这具有将整个对应的原始 alist 条目编码为候选显示字符串上的文本属性的效果。
在调用completing-read 后使用icicle-get-alist-candidate,恢复用户选择的候选者的完整信息,即完整的alist 元素,包括cdr。
(另见:Note to programmers using Icicles。)