导航api的区别

xref-find-definitions

evil-goto-definition

counsel-etags-find-tag-at-point

这三个API都能查找定义

  1. 哪一个目前最好?
  2. 具体实现都有什么区别呢?
  3. 这个tag 和 definition 有什么区别呢?

另外 查找所有引用 用哪个好呢?

我用第一个

evil 我没有,所以不用

etags没折腾过也不用

查找引用使用 xref-find-references

这三个函数其实是做不同事情的, 比较难相互比较.

xref 是 Emacs 自带的 cross reference api. 它类似于一个 “中间件”. 向上可以对接到各种 “前端”, 让前端展示候选项. 向下对接到补全的后端, 依靠后端提供候选项. 好用程度基本取决于前后端了.

evil-goto-definition 是 evil-mode 提供的, 它自己其实没实现查找功能, 而是调用了其他的查找 api. 可以 C-h f evil-goto-definition 看下它的定义, 会发现它用了下面这些, 里面就有 xref.

(defcustom evil-goto-definition-functions
  '(evil-goto-definition-imenu
    evil-goto-definition-semantic
    evil-goto-definition-xref
    evil-goto-definition-search)
  "List of functions run until success by `evil-goto-definition'."
  :type 'hook
  :group 'evil)

counsel-etags-find-tag-at-pointcounsel-etags package 提供的, 个人没用过, 应该主要是通过 ctags 查找候选, 然后用 ivy 做展示. 我猜用 xref 可以实现类似的效果 (后端用 etags, 前端用 ivy), 不过很可能没这个专门的 package 方便快速.

1 个赞

我自己现在用的是 lsp-mode, 它其实就是提供了一个 xref 的后端, 可以用 xref-find-definitions 找定义, xref-find-references 找引用. lsp-mode 应该还有些其他的查找功能, 可以找找它的文档看看.

解释的很到位了 感谢

lsp用过一段时间 因为有卡顿感 暂时没用了 ctags可以覆盖工作流

counsel-etags-find-tag-at-point 很不错的一直都在用,快速、稳定、节能、跨平台,使用 https://github.com/universal-ctags/ctags 在文件保存时(或者编译时)触发在项目根目录生成(或更新)tags文件就可以用了。可以用大佬的办法往生成的 tags文件里加入自定义内容 , 生成的tags还可以用company来解决自动补全的问题。

counsel-etags-find-tag-at-point 的问题就是跳转到函数定义时不够精确,特别是对于我这种函数命名乱来的很糟糕。有心想研究counsel-etags的代码解决函数定义跳转不精确的问题,但elisp水平不行只好作罢。

结果是counsel-etags用久了,发现我在函数命名上不在乱来了,意外收获 :joy: