【问题标题】:completion-at-point function that returns the cdr返回 cdr 的点完成函数
【发布时间】:2021-06-03 15:39:40
【问题描述】:

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

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

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

actual use case 用于在文档中插入引文关键字,但搜索作者、标题等。其目的是与corfucompany-capf 等解决方案一起使用。

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

有了这个 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 是相关的,但我不知道如何适应它。

【问题讨论】:

    标签: emacs tab-completion


    【解决方案1】:

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

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

    认为更有效的方法是收集您当前候选人的 cdr 并允许 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)))))
    

    【讨论】:

    • 总的来说,这个项目对我来说是一个“边做项目边学习 elisp”的项目,而且我不是一个训练有素的程序员。我试图在这里从概念上简化它。在实际代码和 PR 中,我有一个基于完成读取多次的主读取函数,其中完成表候选的形式是 car 是搜索字符串,cdr 是我需要的键。该数据缓存在bibtex-actions--candidates-cache defvar 中,然后由bibtex-actions--get-candidates 函数访问。所以我也想为 capf 重用它。
    • 所以,例如,我有这样一行(let ((candidates (bibtex-actions--get-candidates))),对于完成读取功能和这个是一样的。
    • 好的,所以在这种情况下,您可以添加(let ((candidates (mapcar #'cdr (bibtex-actions...)))) IIUC。如果候选人没有动态变化(听起来像他们这样做,虽然),然后将它们存储在一个变量中。对于更复杂的动态更新,我觉得elisp-completion-at-point是个不错的参考
    • 但是我只是在搜索/完成密钥。最后,我希望弹出窗口向用户显示作者、标题等列表,他们可以缩小范围,然后一旦选择了一个,他们就会取回它的密钥(因为如果你有成千上万的参考文献,您可能不记得足够的细节来缩小键范围)。那可能吗?如果不是,我想一个不太理想的替代方法是使用注释或附加功能。
    • 我想我应该明确说明这一点:我的目标是 corfucompany-capf
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多