返回 cdr

问题描述

我需要一些帮助来理解完成点。

我有这个最小的例子,我想:

  1. 当我输入“@”时激活
  2. 搜索/完成候选汽车...
  3. ...但返回 cdr,所以此时的结果是,例如“@doe”(尽管我可能需要稍后扩展它以在某些情况下删除“@”,例如 LaTeX)。

actual use case 是在文档中插入引用键,但搜索作者、标题等。目的是将此用于 corfucompany-capf解决方案.

在该代码中,它是 bibtex-completion 的前端,如 helm-bibtexivy-bibtex我有一个基于 bibtex-actions-read 的核心 completing-read-multiple 函数,用于小缓冲区完成。

有了这个 capf,我想使用相同的缓存数据来完成点完成。

通过这个测试示例,我得到了 1 和 2,这是我在 UI 端想要的。

(defun test-capf ()
  "My capf."
  (when (looking-back "@[a-zA-Z]*")
    (list
     (save-excursion
       (backward-word)
       (point))
     (point)
     (lambda (str pred action)
       (let ((candidates '(("a title doe" . "doe")
                           ("different title jones" . "jones")
                           ("nothing smith" . "smith"))))
       (complete-with-action action candidates str pred))))))

但是我如何适应它以添加 3?也就是说,如果我输入“@not”,corfucompany 应该显示nothing smith”,如果我选择那个项目,它应该在点返回“@smith”。

注意:我的包非常依赖于像 orderless 这样的完成样式,所以顺序当然不重要。

我需要在这里使用 :exit-function 吗?

为了完整起见,这是当前的实际功能,当我尝试使用它时,现在显示“不匹配”。

(defun bibtex-actions-complete-key-at-point ()
    "Complete citation key at point.

When inserting '@' in a buffer the capf UI will present user with
a list of entries,from which they can narrow against a string
which includes title,author,etc.,and then select one. This
function will then return the key 'key',resulting in '@key' at
point."
    ;; FIX current function only returns "no match"
    ;; Todo this regex needs to adapt for mode/citation Syntax
  (when (looking-back "@[a-zA-Z]+" 5)
    (let* ((candidates (bibtex-actions--get-candidates))
           (begin (save-excursion (backward-word) (point)))
           (end (point)))
      (list begin end candidates :exclusive 'no
            ;; I believe I need an exit-function so I can insert the key instead
            ;; of the candidate string.
            :exit-function
            (lambda (chosen status)
              (when (eq status 'finished)
                (cdr (assoc chosen candidates))))))))

还有其他提示或建议吗?

This Q&A 是相关的,但我不知道如何调整它。

解决方法

为什么不只在完成表中保留完成候选,而不是 conses?

minibuffer.el 中围绕完成表有一些有用的包装器。在这种情况下,您可以使用 completion-table-dynamic 作为包装器,将函数用作 complete-with-action 的 COLLECTION 参数。

认为更有效的方法是收集当前候选人的 cdrs 并允许 all-completions 的 C 实现找到匹配项

(complete-with-action action (mapcar #'cdr candidates) str pred)

或者,调用函数返回当前候选

(completion-table-dynamic
 (lambda (_str)
   (mapcar #'cdr (my-current-candidates))))

或者,在 elisp 中过滤

(let ((candidates '((...)))
      (beg '...)
      (end '...))
  ;; ...
  (list beg end
        (completion-table-dynamic
         (lambda (str)
           (cl-loop for (a . b) in candidates
                    if (string-prefix-p str a)
                    collect b)))))
,

解决方案是退出函数,其主体如下:

(delete-char (- (length str)))
(insert (cdr (assoc str candidates)))))