如何通过完成读取 return 值而不是键

How to return the value instead of key by completing-read

(completing-read
 "Complete a foo: "
 '(("foobar1" "~/foobar1/") ("barfoo" "/usr/barfoo/") ("foobaz" "/hello/")))

如上所示,我想提示输入"foobar1""barfoo""foobaz",但得到的是return中的配对目录。

此外,如果我有这样的散列-table

(cl-defstruct person ID name)
(setq person-object (make-person :ID 123 :name "foo"))
(setq person-table (make-hash-table))
(pushash (person-ID person-object) person-object person-table)

如何提示输入人名但在 return 中获取人 ID?

无法从 completing-read 到 return 值而不是键,因此您必须自己进行查找:

(let ((completions '(("foobar1" "~/foobar1/") ("barfoo" "/usr/barfoo/") ("foobaz" "/hello/"))))
  (cadr (assoc (completing-read "Complete a foo: " completions) completions)))

至于散列table,由于名称不是键,您需要遍历散列table中的每个对象来找到它,使用maphash。由于在找到所需内容后继续迭代会很浪费,因此可以使用 catchthrow,如下所示:

(catch 'found-it
  (maphash
   (lambda (key value)
     (when (equal (person-name value) desired-name)
       (throw 'found-it key)))
   person-table))

这将 return 人 ID,或者 nil 如果没有人的名字等于 desired-name

@legoscia 提供了一个很好的答案:completing-read 确实 而不是 允许您访问与用于完成的键关联的值。例如,对于 alist COLLECTION 参数,它不会让您访问所选 alist 键的 cdr。

对于列表,您可以使用 assoc 获取 第一个 匹配的列表元素,对于散列 table,您可以 maphash或做一个得到。

但是这些方法排除了获取与特定选择的键出现相关联的特定值的可能性当存在 duplicates key,即当多个候选者有相同的key,或者名字.

您无法获取第 2 个或第 13 个匹配元素。事实上,vanilla Emacs completing-read 消除了具有相同键(名称)的完成候选的重复。对于香草 Emacs,列表条目的 cdr 中的任何信息都被浪费了。如果你已经有一个列表,为了方便起见,你可以使用一个列表,但如果没有,那么你也可以只使用一个名称列表(字符串或符号),而不是 conses。

如果您使用 Icicles,则不会浪费列表条目。检索 cdr 值没有问题。 completing-read完成后,您可以轻松获取所选候选人的完整信息。

Icicles 通过使用属性化字符串作为候选对象,并通过增强 completing-read 使其可以 return 完整的字符串、属性和所有内容,用户选择的。您可以从 returned.

的属性化字符串中恢复完整的列表条目

何时重要 能够拥有和使用具有不同关联值的重复键?如果它们是重复的,用户如何区分它们(例如,在 *Completions* 中)?

示例:

  • 具有相同名称但用于不同目标的书签 - 例如,用于不同目录中具有相同相对名称的不同文件。

  • 缓冲区中匹配模式或包含标记的行或其他文本。这包括 Icicles search 中的匹配项,您可以在其中以任何您喜欢的方式定义搜索上下文(不仅仅是行)。它还包括缓冲区(包括限制,又名缩小)和缓冲区位置(标记)。

  • 文本相同但注释不同的考生。 (用户输入与 *Completions* 中显示的注释不匹配。)

  • 具有相同名称的菜单项,例如具有相同名称的对象(例如函数)的多个定义。

  • 具有相同名称的标记项(例如函数)。

  • 候选为其他 Lisp 对象,例如可以具有相同名称的框架。

Icicles中,用户如何在多个具有相同名称的补全候选中选择一个?

  • 用户可以控制候选人的顺序(排序),包括动态更改顺序。 *Completions* 按特定顺序向您展示它们。您可以在候选人之间循环或直接选择其中任何一个。您不限于搭配,任您选择。 (对于重复的候选人,匹配可能不足以让您只找到其中​​一个。)

  • *Completions* 还可以向您显示有关候选人的其他信息,即使他们具有相同的 name/text,这也能区分他们。此类信息可以是周围的文本(如果候选匹配缓冲区文本),或候选元数据(例如文件或书签属性)。

  • 您还可以在模式行中查看有关当前候选人的重要附加信息(例如在骑自行车时)。

  • 您可以按需按需获取有关当前候选人的其他信息(完整*Help*)。

您需要做什么才能利用此 Icicles 功能 在你自己的代码中?

有关预定义的 Icicles 跳闸命令,请参见 Defining Tripping Commands for how to define your own commands that let users trip among (explore) candidates might have associated positional or other navigational information. (See Tripping。)

关于在命令中执行的操作的简要概述:

  1. 绑定变量icicle-whole-candidate-as-text-prop-p到非nil.

  2. 将变量 icicle-candidates-alist 设置为您传递给 completing-read 的列表。这具有编码的效果,作为候选显示字符串上的文本 属性,整个对应的原始列表条目。

  3. 调用completing-read后使用icicle-get-alist-candidate恢复用户选择的候选人的完整信息,即完整的列表元素,包括cdr。

(另见:Note to programmers using Icicles。)