Citre: 先进的 Ctags 前端

我觉得大多数人只关心在当前工程建立索引,这是他们用这个软件的心智模型。

至于索引外部项目的功能,放到高级用法文档中,关心的人自然会折腾。

这个概念对大多数用户都不要问,问了也是一脸懵逼的不知道怎么做,这个问题超出他们的常识和认知,怎么问都不对。

梳理了一下treesitter的函数

  • 比较有用的应该是tsnode:sexpr().

treesitter

谢谢你的回复。我想了半天,觉得你说的是对的。

实际上

这两句说的都是生成 tags 文件的问题。而我们讨论的那个 prompt 问的是使用 tags 文件的问题。因此你说的其实和我问的根本不是一件事。但实际上这也从侧面体现了你生成 tags 文件时想的事情和我完全不一样。或许大多数用户都和你一样,觉得我建完索引能用就完了,至于「扫描哪些文件、给哪些文件用」,尽管事实上是必须指定的,却不是用户想要关心的。

这让我想起 VC 的 fileset 概念。尽管事实上是简单和必需的,但我每次看到还是要想一下。

我打算在手册一开始建议设置一些变量,让用户能简单地生成 tags 文件,后面再讲高级用法。但我感觉还是不太想改它们的默认值,可能是因为 Emacs 插件中像这种「动了以后会完全屏蔽掉插件的一部分能力」的选项并不多,或者是实际上我们估计不出来「高级用户」的比例,或者还是我自己习惯「高级用法」,觉得那种才是对的 :rofl:

1 个赞

给你的想法开了个 issue:Accurate inspection on C struct members · Issue #83 · universal-ctags/citre · GitHub

我现在认为这个功能比较重要,而且要做的话需要扩展一些 Citre 核心的功能,这个在我打算做的「交互式过滤 tag」工具里也是有用的。因此现在打算优先做这个。

今天下午专门跟了一些产生重复buffer的问题,感觉还是citre这个包的问题;我用emacs -q单独加载lsp没问题,感觉是因为当时吵了citre-jump+的命令,误解了; 尝试跟踪了citre的函数,发现问题可能出现在(defun citre-goto-tag (tag &optional window)这个函数的 (let* ((buf (find-file-noselect path))这个语句;到这一句后,会产生后面带<2>这样的buf名; 在buffer-list中比较两个buffer,发现可能问题还是出现在windows系统的问题;两个buffer的名字分别是:E:/hello/ctags-p5.9.20210704.0/main/main.c 和 e:/hello/ctags-p5.9.20210704.0/main/main.c; 尝试用find-file-no-select检查两个文件名,返回的buffer确实不一样; 看起来就是find-file-no-select检查windows文件名,是大小写敏感的;而citre-core-get-field 返回的文件名,和buffer-list中存储的文件名,盘符大小写不一致;

没想好咋解决这个问题啊,难道要强行改盘符的大小写?

谢谢! 这是 Citre 目前收到质量最高的 bug 报告!

我已经注意到 ctags 在 Windows 上生成的路径,盘符总是大写的,而 Emacs 是大小写都行。

现在我也没有特别好的想法,需要调查一下,但肯定是能修的。下下策无非就是拿到路径以后转小写,然后和现有所有 buffer 的文件路径转小写对比,有一样的就用那个 buffer。

directory-file-namedostounix_filenamemsdos_downcase_filename

directory-file-name会把大写的盘符改成小写的,expand-file-name不会。可能还有其他函数也会把大写盘符改小写。

emacs -Q F:/somefile.txt后,M-;执行(buffer-file-name),输出的盘符都是小写。

谢谢,但我没看出来这个怎么用。。。

可能大概把tags文件里读出的文件名,调用下directory-file-name吧。 不过最简单还是windows都直接downcase。。。

问题是这样只会把盘符变小写,而我们从 bug 报告中已经知道 Emacs 可以打开大写或小写盘符的文件,并认为它们是不同的。那么要这么做的话,就要假设已经打开的文件盘符都是小写的。

@haoisli9 可否回忆一下,在不是由 Citre 创建的 buffer 中,跳转到一个在当前文件的定义,是不是都会打开一个新 buffer?如果是的话我觉得直接把盘符转小写是可以接受的。

Edit: 我才想起我在 citre-peek 里用过 find-buffer-visiting 这个函数。这样的话就简单了,我们拿大写和小写两个版本都试一下,如果没有已有的 buffer 访问它们的话再创建新的。

我觉得就是个 key 啊,也就是如何找到 tags 文件的索引,不论是 global cache, project cache, 还是直接目录,作用是一样的,都是以这个目录作为 key,根据 citre-default-create-tags-file-location 的不同值去相应的地方去找。

简单来说,理论上讲,这个 key 和相应的目录对应,对于人来说,好记也好用,然后从 key 找到相应的目录作为真正的 path,再根据设置去相应的地方找 tags 文件。只不过现在正好是以目录为 key。

通过前面emacs -Q打开文件的测试,盲猜emacs会在创建buffer时,对filename做些处理,导致buffer-file-name的值是小写盘符。

find-buffer-xxx系列函数,应该也是以buffer-file-name有关联的东西为key来查找存在的buffer的。

M-;运行(find-file-noselect F:/Abc)创建出来没有实际文件对应的的buffer,也是buffer-file-name的盘符是小写。

1 个赞

我不同意你所说的。

看你的解释,确实很有道理,我能理解。问题是我作为插件的作者,还需要你解释一下什么是 key,那我想大部分用户看到这个词都是懵的。

问题是「key」是一个抽象并且带有比喻性质的概念,和 peek、jump、甚至 Emacs 社区常用的 ace/avy 一样,懂了的人觉得很好用,而且他还会变得不能理解不懂的人。这里我们想要的东西并不复杂,应该想办法直接跟用户描述,而不是发明概念。

建议新开一贴哈

谢谢你的建议

  • 我喜欢凑热闹。

  • 目的是为了得到数据结构的信息。

  • 我趟条路,如果走得通,你跟着走就行。

  • 走不通,就立个牌子,写上此路不通。

管理员可以拆分主题,可以请管理员拆分一下

我对 tree sitter 没有兴趣。

好像不止是citre 创建的buffer,我预先打开的文件,通过citre 查找本文件定义,也是会产生新buffer的。find-file-xxx系列函数查找时不知道是用哪个buffer属性来比较的,在当前buffer展示文件名,盘符好像也小写,但就是认为匹配不上。很奇怪啊。

这个是肯定的。你报的 bug 不就是这个意思嘛。我是想问:

  • 你在 Citre 打开的文件里再跳转,是不是就不会出现这个问题。
  • 你在自己打开的文件里用 Citre 跳转,是不是就总是会有这个问题。

我过几天在 Windows 上测试一下再修 :rofl: 你不用太担心,肯定能修好的。

  • 你在 Citre 打开的文件里再跳转,是不是就不会出现这个问题。
  • 不是的,在Citre打开的文件中跳转,还是会创建新buffer,但是这个时候在原先的buffer中跳转,就不会产生新buffer了;
  • 你在自己打开的文件里用 Citre 跳转,是不是就总是会有这个问题。
  • 在自己打开的文件中用Citre跳转,第一次会产生新buffer,然后就不会了;但是如果在新的buffer中再用Citre跳转,就会再次产生新buffer;看起来就是在新产生的带数字的buffer中再次用Citre跳转,会不停产生新buffer,但这个时候在老的buffer中再跳转,就不会有新buffer产生了;