启用了 c++, semantic 以及 ggtags layers 后,编辑 elisp 文件时经常 parsing

最近启用了几个 layers:c++, semantic 以及 ggtags layers,然后编辑 elisp 时,尤其是编辑字符串的时候,总是在 parsing,造成拖慢。这个是什么功能?怎样在 elisp mode 下禁用 parsing?

image

1 个赞

这个问题是 semantic 导致的, 把下面三个函数去掉就可以了

(semantic-mode 1)
(remove-hook 'completion-at-point-functions
             'semantic-analyze-completion-at-point-function)
(remove-hook 'completion-at-point-functions
             'semantic-analyze-notc-completion-at-point-function)
(remove-hook 'completion-at-point-functions
             'semantic-analyze-nolongprefix-completion-at-point-function)
1 个赞

能不能帮我看一下你的 completion-at-point-functions 的值,我照做之后仍然会 parse 并造成卡顿。

我的

completion-at-point-functions’s value is (elisp-completion-at-point t ggtags-completion-at-point)

Local in buffer org-noter.el; global value is 
(semantic-analyze-completion-at-point-function semantic-analyze-notc-completion-at-point-function semantic-analyze-nolongprefix-completion-at-point-function tags-completion-at-point-function)

解决了我多年的“宿疾”啊,多谢!(后来一直关着semantic-mode,只有想用helm-semantic-or-imenu时才临时开)

为什么 completion-at-point-functions 里面还有 ggtags-completion-at-point?按理说只要设置为 local variable 就能避免干扰。

不过看起来这是个历史悠久的问题,2015 年至今不断有人被困扰:

底下回帖有各种解决方案。

1 个赞

说是已经在 develop 修复了,但是没有啊,我依然受其困扰。

@zilongshanren 最后怎么解决的?所有各位的方法我都试了,但是没有用。

@twlz0ne 多谢!我找到了更好的解决方案。我用semantic-mode,主要为了以下两个功能:

  • stickyfunc-mode
  • helm-semantic-or-imenu or counsel-semantic-or-imenu

经我测试,以下解决了我的问题(我用的是自己配置,所以能肯定别的地儿没有偷偷加载semantic-mode的别的东东)

  (semantic-mode 1)
  (semantic-default-elisp-setup)
  ;; enable /semantic/ with minimal features for /stickyfunc/ and /*-semantic-or-imenu/
  ;; stop semantic parsing (huge,slow) elisp sys libraries
  (setq-mode-local emacs-lisp-mode
                   semanticdb-find-default-throttle
                   (default-value 'semanticdb-find-default-throttle))

这个semantic-default-elisp-setup还是需要的(更好的可能是详细了解这个干了什么,选择要用的,我懒得查了),不然*-semantic-or-imenu 没办法parse和列出.el的symbol tables。

原来一直困扰我们的,就是进elisp mode,它会偷偷修改semanticdb-find-default-throttle,加上omniscience,这个东东会parse系统的el库。你可以C-h v 看下这个list的文档。

1 个赞

感谢!这个问题貌似解决了

但是 elisp-mode 下我的 company 还是有些小问题,有时候会

Company: backend company-capf error "Nothing to complete" with args (prefix)

我的 completion-at-point-functions 的值

completion-at-point-functions is a variable defined in ‘minibuffer.el’.
Its value is (elisp-completion-at-point t)
Local in buffer init.el; global value is 
(tags-completion-at-point-function)

看起来你的 global value 里还是有那三个 semantic-analyze-* 函数

给个例子?让我们重复下这个error?

应该是的,我用了 @oracleyue 的办法解决了,但是有时候 company 还是会报 nothing to complete 的错,不过那也许是另外的问题了。

随便补全就会偶尔出现,你看你的 Message buffer 没有这样的出错信息吗?

我的 company-backends 的值

Value: (company-capf
 (company-dabbrev-code company-gtags company-etags company-keywords)
 company-files company-dabbrev)

Original value was 
(company-bbdb company-nxml company-css company-eclim company-semantic company-clang company-xcode company-cmake company-capf company-files
              (company-dabbrev-code company-gtags company-etags company-keywords)
              company-oddmuse company-dabbrev)

Local in buffer org-noter.el; global value is nil

从来没有过,所以我才想让你给个具体的补全例子(那些字母开头的el函数,company会给出你错误信息)。

同时,我用completion-at-point补全也从来没出过问题(现在借用ivy提供补全列表,挺方便),所以我一直都不知道哪个库函数支持这个补全(company-mode知道)。

在 elisp 中输入括号,然后什么也不输入,就会出现这个错误。这时候还没有输入任何前缀。

如果输入(),cursor 位于中间,运行company-complete,没有任何错误信息,补全列表如图 (哪个右括号有点怪,应该是smartparens的锅);如果只输入单括号(,确实没有补全信息,因为company应该默认不考虑这种情形下的补全,但也不过报错误(我的是这样的)。
看来你得好好自己找找了,应该不是company-mode的问题。

38

你的 company 补全是用 tab 吗?还是根据 idle 时间自动弹出?

具体的出错信息:

Debugger entered--Lisp error: (error "Nothing to complete")
  signal(error ("Nothing to complete"))
  error("Nothing to complete")
  semantic-analyze-possible-completions(nil)
  semantic-analyze-completion-at-point-function()
  completion--capf-wrapper(semantic-analyze-completion-at-point-function optimist)
  run-hook-wrapped(completion--capf-wrapper semantic-analyze-completion-at-point-function optimist)
  company--capf-data-real()
  company--capf-data()
  company-capf(prefix)
  apply(company-capf prefix)
  company-call-backend-raw(prefix)
  apply(company-call-backend-raw prefix)
  company--force-sync(company-call-backend-raw (prefix) company-capf)
  company-call-backend(prefix)
  company--begin-new()
  company--perform()
  company-auto-begin()
  company-idle-begin(#<buffer org-noter.el> #<window 3 on org-noter.el> 11919 30593)
  apply(company-idle-begin (#<buffer org-noter.el> #<window 3 on org-noter.el> 11919 30593))
  timer-event-handler([t 23292 18243 122623 nil company-idle-begin (#<buffer org-noter.el> #<window 3 on org-noter.el> 11919 30593) nil 806000])

看来还是 semantic 的锅

你禁了semantic-mode就没这个错误了? 你各种试试查查
我们也许也有版本的问题,我的company-mode相当的老。。。。

是的,禁用 semantic-mode 就没有这个问题了,你的 company-mode 是在等待时间补全(不用按 tab)吗?

不是,我不是自动弹出补全。我之前是都整合到tab上的,现在重新绑了个新快捷键。

我建议你再试一下,把company-mode的其他设置(包括tab键整合)注释掉,用最简单的设置,看看有没有这个问题。反正当初整合tab引来挺多bug的。首先测试下,裸.emacs,enable compnay-mode, 试试调用company-complete这个命令。

对了,我把company-semantic这个支持补全源从默认的company-backends里删掉了,会不会是它引起的?它应该是调用semantic-mode的。你用company-diag看看这东东有没有,优先级是不是比company-capf还高。

为毛有人用sp这种复杂的一笔的“emacs”?自己配下ggtag、semantic、irony页很简单呀