环境是macOS Catalina + emacs 27.1 + 最新的develop
yasnippet是可以正常使用的,但不想费心去记keyword,希望company自动展示可选项
按照auto-completion layer的文档,
我在init.el里配置dotspacemacs/layers加上
(auto-completion :variables
spacemacs-default-company-backends '(company-files company-capf)
auto-completion-enable-snippets-in-popup t)
并且在user-config
打开了(global-company-mode)
,
理论上任何mode下C-h v company-backends
的结果都应该是下面吧?
((company-files . #1=(:with company-yasnippet))
(company-capf . #1#))
然而在go-mode下结果却是
(company-capf
(company-go . #1=(:with company-yasnippet))
(company-files . #1#)
(company-capf . #1#))
看了下 go layer的代码,直接有对company进行配置,另外发现lsp-mode也会影响company,甚至一度产生bug(我的lsp是lsp-mode-20210307.1909,应该不是这个bug)。
似乎推荐直接用(global-company-mode)
?所以正确的使用姿势是什么?给每个mode加上hook (push '(company-capf :with company-yasnippet) company-backends)
吗?
求鱼之外还想求渔技,有什么办法追踪有哪些函数影响了某个变量吗?比如这里的company-backends
另外发现在py mode 下是
(company-bbdb company-semantic company-cmake company-capf company-clang company-files
(company-dabbrev-code company-gtags company-etags company-keywords)
company-oddmuse company-dabbrev)
这个貌似是 lsp 加上去的,我这样强行去掉的:
(add-hook 'lsp-completion-mode-hook
(lambda ()
(when (eq (car company-backends) 'company-capf)
(setq company-backends (cdr company-backends)))))
spacemacs 有一套自己设定 backends 的机制,在我转成自己配置前也没弄懂😂,不确定下面像 centaur 这样行不行:
(with-no-warnings
(with-eval-after-load 'yasnippet
(defun company-backend-with-yas (backend)
"Add `yasnippet' to company backend."
(if (and (listp backend) (member 'company-yasnippet backend))
backend
(append (if (consp backend) backend (list backend))
'(:with company-yasnippet))))
(defun company-enable-yas (&rest _)
"Enable `yasnippet' in `company'."
(setq company-backends
(mapcar #'company-backend-with-yas company-backends)))
(company-enable-yas)
(defun my-company-yasnippet-disable-inline (fun command &optional arg &rest _ignore)
"Enable yasnippet but disable it inline."
(if (eq command 'prefix)
(when-let ((prefix (funcall fun 'prefix)))
(unless (memq (char-before (- (point) (length prefix))) '(?. ?> ?\())
prefix))
(funcall fun command arg)))
(advice-add #'company-yasnippet :around #'my-company-yasnippet-disable-inline)))
有道理,我试试加个lsp-completion-mode的hook
是的,就是这点让我十分脑壳疼
查了下lsp-mode的代码,(setq lsp-completion-provider :none)
能让lsp不去改company的配置,当然这就必须搭配global-company食用了。
然后python-mode似乎是因为python layer里没有company相关配置
But it is not recommended to do so, you should instead open an issue to ask for auto-completion support for the major-modes where it is missing.
1 个赞
wsw
7
(setq lsp-completion-provider :none)
(add-hook 'go-mode-hook 'lsp-deferred)
(add-hook 'go-mode-hook (lambda ()
(setq-local company-backends '((company-yasnippet :separate company-capf)))
(company-mode +1)))
希望yasnippet放在前面不会太影响,不满意自己调整顺序。
(setq lsp-completion-enable nil)
可以更彻底地让lsp不捣鼓company设置。
试了一下发现确实是这样,看了下代码,lsp会跑一句(add-hook 'completion-at-point-functions #'lsp-completion-at-point nil t)
我是主要用tabnine所以让lsp别帮我改backends。