Citre: 先进的 Ctags 前端

本想试着把icomplete用起来,结果发现和ivy的框架那一套好像还冲突。还是觉得增加一个ivy的后端好一些。(我看citre里面好像做了xref的后端,但是不知道咋能呈现出来。我用jump还是completing-read的UI)。 昨天把ivy的说明看了看,觉得还挺简单,简单写了一个,自己用感觉没问题,可以把所有匹配的tags都显示出来选择了,终于符合自己的习惯了。 代码贴到这里,大家帮忙看看。ivy我不熟悉,也不知道里面的action啥的都咋用,只写了最简单的几条。

(cl-defun citre-jump-ivy-read (definitions symbol)
  "Select an element ivy-read' interface.  See
`citre-jump-select-definition-function' for the use of this function."
  (pcase (length definitions)
    (1 (car definitions))
    (_ (ivy-read (format "%s: " symbol) definitions
                 :caller 'citre-jump-ivy-read))))
(setq citre-jump-select-definition-function  #'citre-jump-ivy-read)

:rofl:

我多年不用 ivy 了,但按我理解,只要打开 ivy-mode,你不用自己写这些东西,citre-jump 会自动用 ivy 的界面。

其实关键就是把 completing-read-function 设为 ivy-completing-readivy-mode 应该会做这个事。

哦,果然是啊,害得我还琢磨了半天ivy该咋用; 不过这样一来,所有的completing都会使用ivy的模型了,不知道会不会和其他的插件有冲突。我再试试。

歪个楼,楼主是做Linux内核开发的吗? :rofl:

不是 :rofl:

好消息。用了一些 workaround,现在 citre-jumpcitre-peek 找不到定义的时候,都可以升级 tags 文件然后自动重找一遍。逻辑是这样:

  • 找不到定义时,看 tags 文件是否包含升级用的 recipe,若否,直接提示用户找不到定义。
  • 询问用户要不要更新 tags 文件,更新之后再找一遍,如果还找不到,再提示用户找不到定义。

Edit: 给 xref 也实现了这个功能。

1 个赞
let*: Wrong type argument: stringp, nil

如果一个目录没有创建 tags 文件,citre-jump 会报错,我用 citre 目录本身测试的, 感觉这个需要稍微优化优化

谢谢,我回去看下。

如何customize readtag cmd argument?貌似没找到对应的Citre variable啊。

你是指自定义 ctags 命令?

已经修好啦 :wink:

ctags命令好像已经可以自定义了。我是指自定义readtags 命令。因为我想filter out一些tags,因为不想让他们在imenu 或者是 treemacs tag mode中显示不必要的tags。 我对ctags命令不是很了解,但貌似readtags可以有过滤功能。要是ctags可以直接过滤也可以。我想要是readtag也可以自定义命令那就更好了。

这个不好弄啊,我也没有什么好的想法。目前是 Citre 根据环境推断需要过滤掉哪些 tags。你如果觉得自己可以写更好的规则的话,可以 advice citre-definition-default-filtercitre-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,由于找定义抓的是光标下的符号,所以直接找的话只会帮你找 foobar 的定义,但 Citre 设计你可以先把它整个选中,然后用 jump/peek/xref 之类找到这个 foo.bar 的 tag。

排除之后,你只能从 foo 找到 foo 的定义,bar 找到 bar 的定义。

这样说能理解吗?

1 个赞

明白了!等我试试哈,给你反馈。谢谢啊!

可以了 目的达到!谢谢你啊。 我把问题想复杂了。原来这么简单。。Citre很好哦,祝项目github星标越来越多! :grin:

2 个赞

Centaur Emacs 现在应该可以和lsp/eglot一起工作了,快捷键也进行了更新。

1 个赞