yicao
2018 年10 月 13 日 09:44
1
之前一直诟病cquery补全卡顿,特别特别慢.我发现补全时cpu会飙升.今天用eglot试了一下,cpu也是非常高(%40).不过我各种尝试,找到了降低的办法,cpu能占到大概%3一下.其实就是就是手动补全.
方法:
先将company-capf (complation-at-point-function)从company-banckends移除,.
eglot的补全用的时company-capf.如果将这个加入company-backends,那么就会用这个进行补全.就会导致cpu飙升.因为当我们键入字符的时候,大部分情景下,敲入的字符都是buffer里已经有的单词.其实这个可以先用 M-x company-semanitic进行补全,这样不触发cquery能能补全.当按下"."后,在M-x company-semanitic进行补全.此时cpu极低极低.如果是补全buffer里没有的单词或函数,可以先敲入函数的前几个单词,比如 conn, 然后M-x company-capf,这样就会调用cquery进行补全.这些补全请求都是精准请求,不会频繁的drop request,浪费cpu.
现在我的疑问是,这些操作能否自动化呢,就是默认从buffer补全,如果补全不到,就调用company-capf,从而触发lsp补全.
回头我补一张动图,cpu非常低
1 个赞
yicao
2018 年10 月 13 日 09:44
2
忘了说了,我用的win10 msys2 emacs 26
yicao
2018 年10 月 13 日 13:26
3
可以看到,cquery的cpu非常低,补全速度也还不错.
我是打算把这个company-capf做成快捷键,这样先用buffer内补全,如果有需求,就调用company-capf补全.可是鄙人elisp很菜,发现M-x可以运行那个命令,做成快捷键就不行了.company-capf需要参数,我不知道传什么参数:disappointed_relieved:,有哪位大哥知道的话,求分享.当然如果能智能的选择补全后端最好了.手动也不错,起码卡顿的问题能解决了
没怎么折腾cquery,不过倒是提醒我了,company的后端都可以手动运行的,就像之前大神的company-english-helper,可以直接手动运行。如果在elisp里面运行,因为都有参数,需要用(call-interactively 'company-capf)。
cquery用libclang completion,不能用StoreInMemory
,會在/tmp
創建PrecompiledPreamble::TempPCHFile
。clangd (及ccls)用上了這個優化和另外一些Clang C++ API才能用的優化。libclang構建的ASTUnit
也有點重,僅用於補全的場景是浪費的。
另外cquery不應該預設傳遞-fspell-checking
。願意測試的話src/clang_complete.cc
刪掉這個選項看下有沒有改善。
另外它的第一遍parse是浪費了,緊接着reparse,原因是libclang用的ASTUnit第二次才構建preamble(_WIN32
沒用CXTranslationUnit_CreatePreambleOnFirstParse
)。它的comp-preload執行緒if (tu->last_parsed_at && *tu->last_parsed_at > request.request_time)
的處理方式是有點浪費的,ccls是僅didSave時處理,節省了一些parse。
常見補全操作:foo.mem<completion>
。你在後面緊接着輸入幾個字元,foo.memb<completion>
foo.membe<completion>
。cquery/ccls都是有cache的,沒有clangSema,CPU飆升的時間很短。我不太相信elisp的semantic會比他們節省。JSON deserialize是問題。
riatre給 Build · MaskRay/ccls Wiki · GitHub 加了 mingw-w64-x86_64-clang
構建ccls方法,有興趣可以試試。
yicao
2018 年10 月 14 日 00:30
6
你说的也有道理,可是我用nvim就没事,补全嗖嗖的,超级快,都是cquery后端。但是emacs下cquery cpu就非常高。nvim下就没事。如果跟json性能有关系,emacs下json序列化慢,发消息就慢,cquery接收消息就也慢,感觉跟cpu影响不是很大了。nvim下cpu低,我感觉是,它补全时就没有用cquery后端,而是优先使用buffer补全,当buffer补全不到时就用cquery,总之就是,我觉得在触发补全时,emacs激活cquery次数或许频繁导致,nvim 仅仅是在有确切需要时激活cquery.不知道理解的对不对。因为从现象看,nvim下补全,cquery真是速度快,而且cpu低
大部分时间不用lsp后端不是个好办法,甚至不能作为一个办法,这样没有充分使用lsp。
以前使用cquery卡顿的一个原因是cquery的语法高亮功能,发给emacs的数据量太大了,把这个关了之后好很多。
你看下你的company触发补全的延迟时间多少?可以设置空闲几百毫秒后触发,最好别把延迟关掉,那样触发补全频率太高
yicao
2018 年10 月 14 日 06:01
9
我现在没有把lsp的后端添加进company-backends,用的是company-semantic, 这个东西只补全当前文件出现过的单词貌似是,这个补全速度很快,因为就是补全本文件的内容,涉及不到lsp.用来补全文件中已经出现过的单词,挺好.然后如果还是获得不到补全的话,我做了个快捷键,然后调用lsp 的补全.这是结果就能拿到了.目前来看体验不错,虽然多了一步手动触发,但是比之前爽多了.以前只想补全个变量名也要等很久.
不知道爲什麼死守cquery…構建方式都給了。幾個cquery completion低效的地方我也指出來了(我確實討厭這個專案,但還是指出了兩個可以改進的地方,仁至義盡)
只要補全的話,irony/clangd/ccls 都行。我相信cquery是最慢的
太繁琐了,没有享受到工具的便利性,最好能定位到问题,然后反馈给开发者,把问题彻底解决。
你可以试试clangd,clangd好像没有语法高亮这些额外功能,可能会快点。还有ccls,方便沟通反馈。
我自己用的irony。
yicao
2018 年10 月 14 日 09:07
12
额,不是死守cquery,是我没有编译环境啊.之前好长时间用来搭建这些.主要还是太懒了.有点力不从心了.我非常乐意尝试ccls.之前为了编译,装了vs2017,后来好像没编过去,老早之前的事了.
yicao
2018 年10 月 15 日 00:22
13
昨天编译了一个ccls,补全速度差不多,不过cpu确实是降低了,默认使用ccls补全也不高。我用eglot和lsp-mode都试过了。lsp-mode无法补全snippet,只能补全到左括号,难道是我配置有问题,鼓捣了半天也不行,求指教啊
yicao
2018 年10 月 15 日 01:19
14
使用时发现一个问题,指定compile_commands.json后,还是有文件没有索引。比如ffmpeg的include目录。不知道是不是放到内存里了。cquery是有的。
請說明用的是不是 Build · MaskRay/ccls Wiki · GitHub msys2,如果你弄成功了,但覺得有什麼坑處幫忙改進下wiki
LSP snippet需要company-lsp提供,
;; company-lsp.el
(defun company-lsp--client-capabilities ()
"Return the extra client capabilities supported by company-lsp."
(when company-lsp-enable-snippet
'(:textDocument (:completion (:completionItem (:snippetSupport t))))))
詳見 bogus autocomplete and index · Issue #15 · emacs-lsp/emacs-ccls · GitHub
还是有文件没有索引。比如ffmpeg的include目录
不詳細。請貼完整檔案名。如果include
裏都是.h
,要確保它們被某些.c
#include
了,否則其自身不會在project loading時檢索(但didOpen後會檢索,即使沒有.c
#include
它)
shaka
2018 年10 月 15 日 07:42
16
之前论坛上就有人发现,卡顿不是cquery或ccls的问题,而是emacs的lsp客户端的问题。
yicao
2018 年10 月 17 日 05:00
17
msys2下编译很顺利,不过有个问题.最好加上这一行
$ pacman -S mingw-w64-x86_64-cmake
因为我的系统上有装windows版本的cmake,并且也在PATH环境变量里面.这就导致了msys默认用的我windows的cmake,导致ninja出现了问题.最后安装这个msys2版本的cmake,就非常顺利了.
另外我测试了一下,就一个单纯的main.cpp.写了一个class.如果这个class 是一个abstract class type,那么只有变量定义成指针会有补全,否则不行,不知道是不是clang不支持呀
yicao:
mingw-w64-x86_64-cmake
謝謝。加了,你可以幫我改的~
The class has incomplete type because is is declared but not defined. Accessing its hypothetical members is ill-formed and you should not expect any completion items from clang.
yicao
2018 年11 月 1 日 04:00
19
今天刚更新了一下ccls.使用的时候,有指定compile_commands.json文件.头文件跳转没问题,但是无法补全头文件里的函数.我是windows环境.
其中stdafx.h 里面又包含着别的头文件,我也能跳转过去.stdafx.h 里面包含的头文件也能跳转,但是就是无法补全头文件里的函数,类名.
然哈后查看错误说找不到标识.但是这个CWaveMixerSession 类我能跳转过去,可是不能补全.不知道为什么.请求指导一下
我想用 cquery 是因为它最成熟,安装配置最方便。ccls 做了很多有意思的改进,能否把安装配置也改善下?每个平台都要自己去编译确实麻烦了些。个人建议吧。