Citre: 先进的 Ctags 前端

你有安装 ivy 的话,另外安装一个ivy-xref 插件就可以了,如果有安装 use-package这样就好

(use-package ivy-xref
      :ensure
      :init
      (setq xref-show-definitions-function #'ivy-xref-show-defs
            xref-show-xrefs-function #'ivy-xref-show-xrefs))

如果用的是 vertico 或者 selectrum 或者内置的 icomplete 的话,是需要跟consult 搭配的,安装完 consult 后记得 (require 'consult-xref) 以及相应的 consult-verticoconsult-selectrum 或者内置的 consult-icomplete 同时配置下 xref 的两个变量即可:

(setq xref-show-xrefs-function #'consult-xref
      xref-show-definitions-function #'consult-xref)

对了, icomplete 的话,可能还需要手动开启一些东西比如下面这样才会舒服点,当然,这东西主要还是看个人喜好

(icomplete-mode)
(icomplete-vertical-mode)
(setq icomplete-scroll t)
1 个赞

这个选项也可以试试

(setq icomplete-show-matches-on-no-input t)
1 个赞

用ivy-xref好像不行,citre-jump似乎不是用xref的调用来搜索tags内容的。可能还是需要单独给citre做一个ivy的后端。

直接用 xref-find-definitions

PS:我试了一下,发现 citre-jump 也没有问题啊,是不是 xref 起得作用我就不清楚了,反正按我上面那个配置完,是可以直接使用的。配色上跟 xref-find-definitions 略有不同,然后提示符那里显示的是查询的函数(变量)截图中是 help,而 xref 就直接显示 xref

2021-07-21 18-46-53屏幕截图

2021-07-21 18-46-33屏幕截图

这个可以显示出来一个匹配,但是不能列举出来所有的匹配,感觉还是没有ivy的模式好用;我想着最好能列出所有的匹配然后可以直接选择跳转。而且打开icomplete后,所有命令都有匹配显示,感觉比较乱。

他的意思是没有输入时,下面也自动弹出,跟 ivy 或者其他的框架类似,默认是不会弹的,你如果用 icomplete 的话,是需要你把我给你的那几句也一起加上的:

(icomplete-mode)
(icomplete-vertical-mode)
(setq icomplete-scroll t)
(setq icomplete-show-matches-on-no-input t)
(require 'consult)
(require 'consult-xref)
(require 'consult-icomplete)
(setq xref-show-xrefs-function #'consult-xref
      xref-show-definitions-function #'consult-xref)

效果图(icomplete consult)如下:

2021-07-21 16-17-48屏幕截图

效果图(ivy ivy-xref)如下:

2021-07-21 16-16-38屏幕截图

@kinono 功能需求:Can’t find definition for … 时,能否加个提示yes-or-no 更新 tags file?经常拉取别人的代码,感觉这样流畅一点,当然也可以加个设置把这个询问关闭

好想法!我回去考虑一下。

大佬加油,等你更新代码 :grinning:,先自己改了一下,感觉要是能更新完后再自动 citre-jump 就更妙了

;; (user-error "Can't find definition for %s" symbol)
        (and (yes-or-no-p (format "Can't find definition for %s, update tags file?" symbol))
             (citre-update-this-tags-file))

必须的,紫薯布丁

已经加了你说的这个功能。很遗憾没有实现更新以后继续 jump,因为某些疑似 race condition 的原因,生成完 tags 文件立即查询的话 readtags 进程会卡死。

我个人怀疑 Emacs 的 write-region 会在没写完或者没关闭文件的时候就返回。Universal Ctags 有计划做一个 edittags 命令,到时候我们用这个替换现在让 Emacs 写的方案,应该就能修好这个 bug。当然我周末也会再看看能不能修好。

2 个赞

本想试着把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啊。