基于 Company 编写了一个带中文注释的英文补全助手

Orderless 我映像中 company 也可以用的吧?我早期切换过去又切换回来主要还是不习惯他的空格过滤搜索的设计,以及不支持分组。后面主要是有这样一个需求:

举个例子: 我有 citre, lsp 两个补全的后端,我可以把他们都加入到 completion-at-point-functions 中,citre 的优先级更高,capf 在这两个当中获取了数据之后。可以跟 company 的其他后端组合:

我还是来点代码说明吧:

(add-hook 'completion-at-point-functions #'lsp-completion-at-point nil t)
(add-hook 'completion-at-point-functions #'citre-completion-at-point -100 t)
;;; completion-at-point-functions 变量的值是这样的
(citre-completion-at-point lsp-completion-at-point t)
;;; 然后,我再来设置 company
(setq-local company-backends
              '((company-yasnippet company-capf
                                   company-dabbrev-code)
                company-files company-keywords
                company-dabbrev))

相当于有了一个两层结构,第一层是 capf 层面的,第二层是 company 层面的。

citre 那边有数据的话直接获取那边的数据,没有的话在获取 lsp 的数据,最终获取的结果就是 company-capf,而在 company 层面我可以对其进行组合或者其他操作,都是可以的,可能性多出许多。

1 个赞

在后端支持方面肯定是成熟的 Company 更加强大的。

我之前 company + orderless 的话,顺序会乱,所以就只在 vertico 中启用 orderless。这个情况我在 oderless 的 issue 列表中看到过好几次,不知道是否已经修复。

PS:如果用 consult 的话,有个包叫 consult-yasnippet,很好用,支持直接对搜索到的 snippet 在buffer 中进行实时预览。

1 个赞

功能是少了不少,Corfu 定位就是轻量化,组合更加灵活。需要的话,还可以适配 company 的后端。

lsp server 自己有增量的 cache。

1 个赞

在lsp server中过滤比在emacs中快吧,,什么lsp server能比emacs还慢,,,

不清楚,只是作者这么说,我具体没遇到过那么慢的 lsp。

其它的不是很清楚,比如 rust. lsp 补全的速度在我这里大概在 20-50ms,但是增量可以快到大概只需要 0.1ms。但这个增量是公共前缀的

请问下增量cache 是怎么打开的?我这 clangd 也差不多是20-50 ms

默认就是打开的,不需要设置。不过这个应该看 lsp server 的具体实现,也许有的是没有的。

1 个赞

使用 lsp-bridge 的时候都在玩 corfu , 最近基于 corfu 写了一个 corf-english-helper GitHub - manateelazycat/corfu-english-helper: English helper for Emacs, base on corfu-mode

感谢 @theFool32 大佬的帮助。

因为 corfu 是基于 child frame 的, 所以 corfu-english-helper 没有做对齐点处理,看起来更加清爽一些。

@Lewisliu 你可以换过来了。

2 个赞
(provide 'capf-english-helper)

应该是

(provide 'corfu-english-helper)

修复了,感谢提醒

capf 和 company 单词还没替换干净。

修复了,感谢反馈

哇,我赶紧更新试试,太赞了

有啥问题欢迎反馈提交 PR, 哈哈哈哈。

我前面也试着把这个插件移植到 corfu 上,这是我写的对齐翻译的代码。

(defvar last-showing-candidate-max-index nil)
(defvar cape--dict-ec-current-input nil)
(defvar cape--dict-ec-max-candidate-translation-width nil)
(defun cape--dict-ec-max-candidate-translation-width ()
  (let ((showing-candidate-max-index (min (+ corfu-count corfu--scroll) corfu--total))
        (showing-candidate-min-index corfu--scroll))
    (if (and (eq cape--dict-ec-current-input corfu--input) (eql showing-candidate-max-index last-showing-candidate-max-index))
        cape--dict-ec-max-candidate-translation-width
      (progn
        (setq last-showing-candidate-max-index showing-candidate-max-index)
        (setq cape--dict-ec-current-input corfu--input)
        (setq showing-candidates (butlast (nthcdr showing-candidate-min-index corfu--candidates) (- corfu--total showing-candidate-max-index)))
        (setq cape--dict-ec-max-candidate-translation-width (apply 'max (mapcar (lambda (w) (string-width (get-text-property 0 :initials (assoc-string (downcase w) corfu-english-helper-completions))))
                                                                                showing-candidates)))))))

(defun cape--dict-ec-annotation (candidate)
  (let* ((translation (get-text-property 0 :initials candidate))
         (translation-width (string-width translation))
         (corfu--candidates-length (length corfu--candidates))
         (max-translation-width (cape--dict-ec-max-candidate-translation-width))
         (blank-width (- max-translation-width translation-width)))
    (format "    %s" (concat translation (make-string (max 0  (- max-translation-width translation-width)) ?\s)))))

简单的改了一下,变量名都还没有改。可以把 :annotation-function 改成 cape–dict-ec-annotation 试一试。

wow, 很不错, 我集成一下,感谢大佬。

很好用,我来集成到 corfu-english-helper 里面吧

4 个赞

看代码中 toggle-corfu-english-helper 应该是只作用于当前 buffer 的吧。

那 corfu-english-helper-active-p 应该用 defvar-local 声明。不然的话,在多个 buffer 中启动 toggle-corfu-english-helper 会报错 “progn: Symbol’s value as variable is void: corfu-english-helper–corfu-auto”。