看到有人推荐 cquery 我就试了一下, 编译成功了,也安装成功了(应该吧 )。
不过有个小问题,就是在进行补全的时候会这样
我按下 tab 键之后就变成了下面这个样子
我想问的是这里是不是什么地方设置出了问题,个人猜测他的原意应该是我按下 tab 或者其他什么按键之后光标在 $0, $1 上依次跳转?或者说有没有可能设置成这样子
emacs 版本:
cquery 相关设置:
(setq cquery-executable "/home/zmqc/backups/src/cquery/cquery/build/release/bin/cquery")
(add-hook 'c-mode-hook
'(lambda ()
(require 'cquery)
(lsp-cquery-enable)
(setq cquery-sem-highlight-method 'overlay)
(setq cquery-sem-highlight-method 'font-lock)))
(require 'lsp-imenu)
(add-hook 'lsp-after-open-hook 'lsp-enable-imenu)
多半和 cquery 无关,可能是 snippet 写的不规范,检查修改一下。
不然不太好解释 $1 $0 这俩东东。
看起来是 snippet-function 出了问题,但是我搜了一下 emacs-cquery 又没发现 snippet 相关代码,那么参数展开是怎么实现的?@MaskRay
还是说楼主举例的这个补全,根本不是 cquery 在起作用,而是纯粹的 snippet 模版?
@ashfinal @twlz0ne
应该不是模板吧, 我看了下它对于自己定义的函数也是可以进行补全的,不过结果一样
相对的 yasnippet 却没有什么问题,比如 for 循环
你安装了 company-lsp 吗?
因为 printf 是最基本的函数,我才会有疑问。
从后面的截图看,参数列表的 snippet 模版已经生成,但是在补全的时候没有执行(展开)
company-lsp 是通过 emacs 自带的包管理安装的
yyjjl
2018 年2 月 26 日 07:12
8
你可以尝试在 lsp-enable-cquery
之前 require company-lsp
你看看 company-lsp--snippet-functions
有什么
比如我这里是:
company-lsp--snippet-functions is a variable defined in ‘company-lsp.el’.
Its value is
(("java" . company-lsp--java-completion-snippet)
("python" . company-lsp--python-completion-snippet)
("rust" . company-lsp--rust-completion-snippet))
This variable may be risky if used as a file-local variable.
Documentation:
Alist of functions to insert our snippets for each language.
[back]
可能是利用 GitHub - abo-abo/auto-yasnippet: quickly create disposable yasnippets 这个包来实现参数补全的?
可以检查下 auto-yasnippet 这个包安装了没。emacs 体系里我想不到还有其它简单方法实现参数补全的方案了。
company-lsp--snippet-functions is a variable defined in ‘company-lsp.el’.
Its value is
(("rust" . company-lsp--rust-completion-snippet))
This variable may be risky if used as a file-local variable.
Documentation:
Alist of functions to insert our snippets for each language.
emacs-cquery 没有hook completion
cquery以及其他基于libclang的工具补全的原理就像这个c-index-test
命令
% c-index-test -code-completion-at=a.cc:5:8 a.cc -resource-dir ~/Dev/Util/cquery/build/debug/lib/clang+llvm-5.0.1-x86_64-linux-gnu-ubuntu-14.04/lib/clang/5.0.1
FunctionDecl:{ResultType int}{TypedText vprintf}{LeftParen (}{Placeholder const char *__restrict __format}{Comma , }{Placeholder __va_list_tag *__arg}{RightParen )} (50)
FunctionDecl:{ResultType int}{TypedText vscanf}{LeftParen (}{Placeholder const char *__restrict __format}{Comma , }{Placeholder __va_list_tag *__arg}{RightParen )} (50)
FunctionDecl:{ResultType int}{TypedText vsnprintf}{LeftParen (}{Placeholder char *__restrict __s}{Comma , }{Placeholder size_t __maxlen}{Comma , }{Placeholder const char *__restrict
__format}{Comma , }{Placeholder __va_list_tag *__arg}{RightParen )} (50)
FunctionDecl:{ResultType int}{TypedText vsprintf}{LeftParen (}{Placeholder char *__restrict __s}{Comma , }{Placeholder const char *__restrict __format}{Comma , }{Placeholder __va_list_tag *__arg}{RightParen )} (50)
FunctionDecl:{ResultType int}{TypedText vsscanf}{LeftParen (}{Placeholder const char *__restrict __s}{Comma , }{Placeholder const char *__restrict __format}{Comma , }{Placeholder __va_list_tag *__arg}{RightParen )} (50)
里面 CXCompletionChunk_Placeholder
会被替换成LSP的 ${1:foo}
这样的snippet,由company-lsp解释
ELISP> company-lsp--snippet-functions
(("rust" . company-lsp--rust-completion-snippet))
所以 cquery 不需要 snippet-function 了?
楼主可能没有配置 company-lsp?
(require 'company-lsp)
(push 'company-lsp company-backends)
我之前用 setq company-backends 加的 company-lsp, 现在换成你这种形式好像没有问题了。
非常感谢大家的帮忙
不懂 snippet-function 這些……
@zmqclee 另外可以試試 :detailedLabel t
, Sarcasm加的
(setq cquery-extra-init-params
'(:cacheFormat "msgpack" :completion (:detailedLabel t) :xref (:container t)))
這裏 :xref (:container t)
是期待有一天有人把引用的lexical container在客戶端顯示出來
MaskRay:
不懂 snippet-function 這些……
就是用来把参数列表转换成 snippet 的函数,company-lsp 自带了一个例子:company-lsp–rust-completion-snippe
既然 cquery 输出的参数列表已经是 snippet,就不需要实现这个函数了。
其实很多语言的 company backend 都不需要这个 snippet-function,因为 company-mode 有另外一种实现 company-template-c-like-templatify
。
具体到某个语言比如 company-go
是这样的(不依赖 snippet):
(defun company-go--insert-arguments (meta)
"Insert arguments when META is a function or a method."
(when (string-match "^func\\s *[^(]+\\(.*\\)" meta)
(let ((args (company-go--extract-arguments (match-string 1 meta))))
(insert args)
(company-template-c-like-templatify args))))
可以运行这句看看效果:
(company-go--insert-arguments
"func Errorf(format string, a ...interface{}) error")
所以这个 snippet-function 的使用场合是:当你使用了 lsp-FOO
并且刚好没有配套的 company-FOO
,这时候就需要写一个 company-lsp--FOO-completion-snippe
来处理参数列表。
2 个赞
大概明白snippet是什么了。
DaanDeMeyer给cquery加了cmake https://github.com/cquery-project/cquery/pull/526
有望取代waf
改进了#include补全。company-lsp可以用
#i"
补全 #include "user_header"
#<
补全#include <system_header>
补全都用上了从clangd抄+改的fuzzy_match.cc
遇到同样的问题了,使用本题解决方案还是没有解决。依然是snippet没有生效。