写点什么

修改 ctags 让 fzf.vim 插件显示 C,C++ 方法声明的标签

作者:alps2006
  • 2023-02-20
    上海
  • 本文字数:2258 字

    阅读完需:约 7 分钟

修改ctags让fzf.vim插件显示C,C++方法声明的标签

背景

在 vim 中使用 fzf.vim 插件可以进行方便的搜索文件, 源码 TAG, GIT 记录等, 最近抽空看了下 BTags 命令在 c, c++ 文件中, 无法显示头文件中的函数声明 标签问题.


比如在头文件中有如下一个函数声明, 使用 BTags 命令是无法显示出这个函数原型的.



/*=========================================================================函 数 名: IMGVideoAlgOpen功 能: 算法初始化算法实现: 无参 数: pvHandle 算法句柄[in]emIMGAlgType 算法类型[in]pvOpen 初始化结构体指针[in]返 回 值: 返回函数调用信息===========================================================================*/int IMGVideoAlgOpen(void** pvHandle, EMIMGAlgType emIMGAlgType, void* pvOpen);
复制代码

分析

通过代码定位, 在 ~/.vim/bundle/fzf.vim/autoload/fzf/vim.vim 文件中, 可以看到 BTags 是通过 ctags 生成的标签.


" query, [tag commands], [spec (dict)], [fullscreen (bool)]function! fzf#vim#buffer_tags(query, ...)  ...  let sort = has('unix') && !has('win32unix') && executable('sort') ? '| sort -s -k 5' : ''  let tag_cmds = (len(args) > 1 && type(args[0]) != type({})) ? remove(args, 0) : [    \ printf('ctags -f - --sort=yes --excmd=number --language-force=%s %s 2> %s %s', get({ 'cpp': 'c++' }, &filetype, &filetype), escaped, null, sort),    \ printf('ctags -f - --sort=yes --excmd=number %s 2> %s %s', escaped, null, sort)]  ...endfunction
复制代码


通过在命令行执行 ctags 命令, 确实是没有生成函数声明的标签.


$ ctags -f - --sort=yes --excmd=number --language-force=c  include/VideoAlg.h | grep IMGVideoAlgInit
# output nothing
复制代码


通过查询 ctags 文档了解到, 每个语言生成标签时, 都有默认的标签类型列表.


可以通过 --kinds-(<LANG>|all)=[+|-](<kinds>|*) 参数去控制, 比如我需要控制 c 语言的生成标签类型, 可以写成这样: --kinds-C=+类型.


具体的标签类型可以通过 ctags --list-kinds-full 进行查看, 如下.


$ ctags --list-kinds-full
# output#LANGUAGE LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION...C D macroparam no no 0 C parameters inside macro definitionsC L label no no 0 C goto labelsC d macro yes no 1 C macro definitionsC e enumerator yes no 0 C enumerators (values inside an enumeration)C f function yes no 0 C function definitionsC g enum yes no 0 C enumeration namesC h header yes yes 2 C included header filesC l local no no 0 C local variablesC m member yes no 0 C struct, and union membersC p prototype no no 0 C function prototypesC s struct yes no 0 C structure namesC t typedef yes no 0 C typedefsC u union yes no 0 C union namesC v variable yes no 0 C variable definitionsC x externvar no no 0 C external and forward variable declarationsC z parameter no no 0 C function parameters inside function definitions...
复制代码


由上 ENABLED 列可知, 默认 ctags 为 c 语言生成的 tags 是不包含 prototype 的, 如果需要支持生成 prototype, 需要使用参数加上.

解决

修改 ~/.vim/bundle/fzf.vim/autoload/fzf/vim.vim 文件, 增加 ctags --kinds-C=+p 参数来支持 prototype 方法签名.



\ printf('ctags -f - --sort=yes --kinds-C=+p --excmd=number --language-force=%s %s 2> %s %s', get({ 'cpp': 'c++' }, &filetype, &filetype), escaped, null, sort), \ printf('ctags -f - --sort=yes --kinds-C=+p --excmd=number %s 2> %s %s', escaped, null, sort)]
复制代码


搞定收工, 同时也提交了 PR 到 github , 不知道是否会采纳.

总结

如果需要其它语言额外的标签类型, 可以基于类似的方法添加.回想了一下 ctag 之所以默认不提供 prototype 类型的标签, 可能是因为一个文件中如果有声明和定义, 可能会有两个相同的标签影响查看. 我这边是做了标签选择预览的, 所以不存在这个问题.

参考

用户头像

alps2006

关注

从事音视频即时通信领域开发, 喜欢瞎折腾. 2018-09-18 加入

从事音视频即时通信领域开发, 喜欢瞎折腾.

评论

发布
暂无评论
修改ctags让fzf.vim插件显示C,C++方法声明的标签_ctags_alps2006_InfoQ写作社区