你是指自定义 ctags 命令?
已经修好啦
ctags命令好像已经可以自定义了。我是指自定义readtags 命令。因为我想filter out一些tags,因为不想让他们在imenu 或者是 treemacs tag mode中显示不必要的tags。 我对ctags命令不是很了解,但貌似readtags可以有过滤功能。要是ctags可以直接过滤也可以。我想要是readtag也可以自定义命令那就更好了。
这个不好弄啊,我也没有什么好的想法。目前是 Citre 根据环境推断需要过滤掉哪些 tags。你如果觉得自己可以写更好的规则的话,可以 advice citre-definition-default-filter
和 citre-completion-default-filter
。
Edit: 不如说说你不想要哪些 tag?
我的项目用systemverilog,用ctags后生成tags, 在imenu里同时显示<类名>.<成员名> 和 <成员名>, 两者指向是一样的所以重复,我想干掉其中一个,这样看上去就会简洁点。我对ctags和readtags都不是很熟悉。可能两个都有过滤功能。对我来说都可以,达到目的就行。写elisp对我来说目前能力和时间都有限所以暂时不考虑哇。ctags有没有相应的option可以在生成tags时直接过滤掉?要是imenu能过滤也行。
首先我假设你是用 Citre 生成 tags 文件。你只需要把 qualified tags 排除掉。编辑那个 tags 文件的 recipe,然后把命令修改一下:
...
--extras=*
--extras=-{qualified}
...
哦, 那就是修改ctags 命令就可以实现啦?那这qualified tags是指的哪个? 带类名的还是不带类名的?过滤掉后会不会影响跳转?
指的是带类名的。据我所知不可能做到排除不带的,留下带的。
假如你原来有一个 foo.bar
的 tag,如果你代码里也有 foo.bar
,由于找定义抓的是光标下的符号,所以直接找的话只会帮你找 foo
或 bar
的定义,但 Citre 设计你可以先把它整个选中,然后用 jump/peek/xref 之类找到这个 foo.bar
的 tag。
排除之后,你只能从 foo
找到 foo
的定义,bar
找到 bar
的定义。
这样说能理解吗?
明白了!等我试试哈,给你反馈。谢谢啊!
可以了 目的达到!谢谢你啊。 我把问题想复杂了。原来这么简单。。Citre很好哦,祝项目github星标越来越多!
我看了一下,有一点问题。
你的 company 配置同时启用了 capf 和 citre 后端,同时这个 capf 后端又是一个 citre + lsp 的联合后端。这两个只要用一个就行了。
另外就是文件里还是把 tags 叫做 TAGS。Citre 并不支持 TAGS 格式。我倒建议直接把这个模块叫 init-ctags
,消除一切可能的误解。
另外建议给 citre-update-this-tags-file
一个快捷键。
有道理,我重构了下。
好问题,我也想寻找这个方案来着…… BTW,宏定义跳转怎么弄的,有方案吗?目前我用了下面的配置,感觉有点硬核
(defun my-config/init-citre()
(use-package citre
:init
(require 'citre)
(require 'citre-config)
:defer t
:config
(defun my-verilog-get-symbol-atpt ()
(let* ((sym (symbol-at-point))
(char (substring (symbol-name sym) 0 1))
)
(if (string= "`" char)
(substring (symbol-name sym) 1)
(symbol-name sym))
)
)
(defvar citre-lang-verilog-plist
`(:get-symbol
my-verilog-get-symbol-atpt
)
"Verilog language support for Citre.")
(setf (alist-get 'verilog-mode citre-language-support-alist)
citre-lang-verilog-plist)
))
我不懂 verilog 啊,但我看你这个应该是正解。要不要给 Citre 写个 PR?
Edit: 建议考虑下有选区的情况,Citre 在有选区时就会抓选区里的符号。参考 citre-get-marked-symbol
和 citre-get-symbol-at-point
。
在 Rust 项目上试了一下,感觉基本没法用呀,是我姿势不对吗?
在 133 行的 range 上执行的 citre-jump,出来一堆没用的,但是 range 就是在上面几行定义的呀$ ctags --version
Universal Ctags 5.9.0(p5.9.20210725.0), Copyright (C) 2015 Universal Ctags Team
citre commit: 2bcdddb
你的姿势是对的。
基于 Ctags 的方案无法像 lsp 那样理解程序的语法结构,所以大部分 ctags 前端都是单纯地查找同名的 tag,也就是会给你所有叫做 range 的符号的定义。
Citre 做得稍微好一点,会尽量帮你排除肯定不需要的那些,这里面的大头是「不在当前文件,但具有文件内作用域的符号」。此外也可以根据具体情况,猜测用户想要的结果然后把它们排到前面去,我们对 C 做了一些这样的规则。但终究是不会像 lsp 那么准确的。
就我以往用 Citre 的经验,其实你要找 range
这种一看就到处都是的名字的话,25 个结果真的不算多
解决的方法是允许用户二次过滤。Citre 显示的结果是 种类/类型@作用域 文件(行号): 行内容
这样的格式,既然你用 citre-jump
,这个时候可以再输入文件名、种类等信息过滤一下。我也想给 citre-peek
做个这样的东西,但目前没想好怎么弄。
对 Citre 和 lsp 的长短有兴趣的话,可看这个文档。
多谢,明白了,等回来写其他语言我再试试吧,目前看还是要依赖 lsp 。
那段关于 my-verilog-get-symbol-atpt的函数,你看看怎么改合适更新到你的仓库里吧(我自己弄感觉肯定会把你代码搞乱)
分类是影响menu tool的菜单排布么?我习惯用 counsel-imenu,无分类,似乎对我没啥影响