赞!我想你的 ignore-case
应该是写反了
太感谢了!我这周末的时候试试,暂时先用着懒猫大神的方法。我也看到后面有很多其他方式,我到时候也学习下~
没注意, 修改了
我知道了,原因是 lsp 即使不能给你补全符号,它的 backend 函数也会返回一大堆乱糟糟的结果而不是 nil
。我再研究下。
@Youmu @songpeng 试一下这个。我在自己这测试通过了:
;; If you keep this as non-nil, `citre-mode' will override the combined backend
;; with its own (Citre only) capf backend.
(setq-default citre-enable-capf-intergration nil)
(defun lsp-citre-capf-function ()
"A capf backend that tries lsp first, then Citre."
(let ((lsp-result (lsp-completion-at-point)))
(if (try-completion
(buffer-substring (nth 0 lsp-result)
(nth 1 lsp-result))
(nth 2 lsp-result))
lsp-result
(citre-completion-at-point))))
(defun enable-lsp-citre-capf-backend ()
"Enable the lsp + Citre capf backend in current buffer."
(add-hook 'completion-at-point-functions #'lsp-citre-capf-function nil t))
现在没想好应该加在哪个 hook 里。即使加在 lsp-mode-hook
里,call lsp
之后 capf 后端还是会被盖掉。暂时需要启用 lsp 之后在当前 buffer 手动 call 一下 enable-lsp-citre-capf-backend
。
Edit: 暂时用 advice 解决了:
(define-advice lsp (:around (fn &rest args) lsp-citre-capf)
(apply fn args)
(enable-lsp-citre-capf-backend))
熟悉 lsp 的高手们有没有稍微普通一点的办法?
More edit: 话说我这个实现是先尝试 lsp,没有结果再用 Citre。大家究竟是想要这样的功能,还是想要把 lsp 和 Citre 的结果揉在一起呢?
其实 citre-ace-peek
之后敲一下回车就是抓当前符号
我在python 里面,开启了lsp后
completion-at-point-functions is a variable defined in ‘minibuffer.el’. Its value is (lsp-citre-capf-function lsp-completion-at-point)
, 这是否意味着其实lsp的completation 操作了两次?
lsp的使用中,我没有配置过completation的事情,所以可能后面那个lsp-completion-at-point是lsp自动加入的?
另外手动call enable
那个函数,是不是得加入interactive
? 不过,后面有advice的使用,应该也就不需要这里手动了,多谢。
不会。除非后端有特别的设置,这个列表里的函数只会执行第一个。
你也许会问那为什么需要一个列表?实际上按 Emacs 的设计,后端可以告诉 Emacs:当我找不到定义,你就试试下一个函数。但是 Emacs 实现上有 bug,导致实际上不太可用。看这里
多谢。我在python中,如果写注释 ## filter blabla
,在写的过程中, 会出现Company: backend company-capf error "Wrong type argument: integer-or-marker-p, nil" with args (prefix)
。 在其他位置补全则没有这个错误,请问你知道这个可能是什么原因么?
不知道,下班帮你看看。
我更想了解一下这个问题:
嗯嗯,多谢。我想对于你感兴趣的问题,不同人可能倾向不同。对我来说,
- 我充分喜欢lsp,它目前的速度,补全能力,代码调转,代码refactor等都非常好用 (我主要利用lsp for python and R)。
- 我使用citre 主要是为了
- jump 某些corner case (lsp work 不好的时候,如同一文件夹下,python调用另一个文件的成员,有时候lsp就不知所措,甚至还说我用的那个同文件夹下的module找不到)。这时候ctags 工作得很好。
- citre peek,这个确实对于读代码很舒服。
- 所以回到补全上,我肯定是优先lsp,其次是citre。
我刚想到一个技巧,应该可以把「lsp 失败了再用 Citre 补」和「两个都用,结果放一起」 各自都实现了。
我今天在公司的代码库上试了一下,感觉ctags的索引速度有点慢。如果不选择语言的话,运行了太久我没耐心Ctrl-C了。选择只索引C++语言的话依然运行了好几分钟。我看了下CPU占用量,并没有用满所有的核心。我找了一下手册也没发现有什么选项可以启用多线程。不知将来是不是有可能加入多线程索引功能?
如果在windows上用 Universal Ctags,生成项目的TAGS传的参数是不是一样。记得以前在linux上生成了TAGS,但是相同方法在windows下没成功。
目前没有多线程,不好说将来有没有。我之前见过一个这个:GitHub - dalance/ptags: A parallel universal-ctags wrapper for git repository ,应该是 ctags 的一个多进程 wrapper,你要不试一下?
你在 Windows 上是用 cmd、PowerShell 还是 bash?
我对 Windows 没啥经验。我在给 Citre 添加一个生成 tags 的向导,是直接用进程来调 ctags 的,不需要经过命令行。如果不急的话可以等这个完成再用。
我是用windows下原生的emacs,用cmd来调Universal Ctags生成TAGS。那应该是我记错了,之前将emacs的bin目录下加到了环境变量。命令行生成的时候,用了bin目录的ctag来生成。后来我写了个函数,不过只会简单的调命令。灵活的我就不会了。
(setq path-to-ctags "d:/DevTools/ctags/ctags.exe")
(defun my-create-tags ()
"Create tags file."
(interactive)
(let ((select-dir (read-directory-name "Select root directory: "))
(select-language (read-string "Input language: ")))
(shell-command (format "%s -f TAGS --languages=%s -e -R %s" path-to-ctags select-language (directory-file-name select-dir))))
)
能做个生成ctags就很好,因为我觉得哪些参数好多,蛮灵活的。
Windows 系统上生成的tags文件得改名为.tags ,不然 Emacs 会认为是TAGS,因为Windows 平台不区分大小写的。
开着 peek 但是光标一直移动到最下面的时候好像有些问题, 但是我不知道怎么描述好