cuqery 补全卡顿的问题,貌似找到原因了,感觉是个方向啊

之前一直诟病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 个赞

忘了说了,我用的win10 msys2 emacs 26

20181013_212002 可以看到,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方法,有興趣可以試試。

你说的也有道理,可是我用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触发补全的延迟时间多少?可以设置空闲几百毫秒后触发,最好别把延迟关掉,那样触发补全频率太高

我现在没有把lsp的后端添加进company-backends,用的是company-semantic, 这个东西只补全当前文件出现过的单词貌似是,这个补全速度很快,因为就是补全本文件的内容,涉及不到lsp.用来补全文件中已经出现过的单词,挺好.然后如果还是获得不到补全的话,我做了个快捷键,然后调用lsp 的补全.这是结果就能拿到了.目前来看体验不错,虽然多了一步手动触发,但是比之前爽多了.以前只想补全个变量名也要等很久.

不知道爲什麼死守cquery…構建方式都給了。幾個cquery completion低效的地方我也指出來了(我確實討厭這個專案,但還是指出了兩個可以改進的地方,仁至義盡)

只要補全的話,irony/clangd/ccls 都行。我相信cquery是最慢的

太繁琐了,没有享受到工具的便利性,最好能定位到问题,然后反馈给开发者,把问题彻底解决。

你可以试试clangd,clangd好像没有语法高亮这些额外功能,可能会快点。还有ccls,方便沟通反馈。

我自己用的irony。

额,不是死守cquery,是我没有编译环境啊.之前好长时间用来搭建这些.主要还是太懒了.有点力不从心了.我非常乐意尝试ccls.之前为了编译,装了vs2017,后来好像没编过去,老早之前的事了.

昨天编译了一个ccls,补全速度差不多,不过cpu确实是降低了,默认使用ccls补全也不高。我用eglot和lsp-mode都试过了。lsp-mode无法补全snippet,只能补全到左括号,难道是我配置有问题,鼓捣了半天也不行,求指教啊

使用时发现一个问题,指定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它)

之前论坛上就有人发现,卡顿不是cquery或ccls的问题,而是emacs的lsp客户端的问题。

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不支持呀

謝謝。加了,你可以幫我改的~

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.

今天刚更新了一下ccls.使用的时候,有指定compile_commands.json文件.头文件跳转没问题,但是无法补全头文件里的函数.我是windows环境.

其中stdafx.h里面又包含着别的头文件,我也能跳转过去.stdafx.h里面包含的头文件也能跳转,但是就是无法补全头文件里的函数,类名.

然哈后查看错误说找不到标识.但是这个CWaveMixerSession类我能跳转过去,可是不能补全.不知道为什么.请求指导一下

我想用 cquery 是因为它最成熟,安装配置最方便。ccls 做了很多有意思的改进,能否把安装配置也改善下?每个平台都要自己去编译确实麻烦了些。个人建议吧。