6

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

 1 year ago
source link: https://www.cnblogs.com/alps2006/p/17138347.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

2023-02-20 17:42  alps2006  阅读(24)  评论(0)  编辑  收藏  举报

在 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 definitions
C                    L      label                 no      no      0      C      goto labels
C                    d      macro                 yes     no      1      C      macro definitions
C                    e      enumerator            yes     no      0      C      enumerators (values inside an enumeration)
C                    f      function              yes     no      0      C      function definitions
C                    g      enum                  yes     no      0      C      enumeration names
C                    h      header                yes     yes     2      C      included header files
C                    l      local                 no      no      0      C      local variables
C                    m      member                yes     no      0      C      struct, and union members
C                    p      prototype             no      no      0      C      function prototypes
C                    s      struct                yes     no      0      C      structure names
C                    t      typedef               yes     no      0      C      typedefs
C                    u      union                 yes     no      0      C      union names
C                    v      variable              yes     no      0      C      variable definitions
C                    x      externvar             no      no      0      C      external and forward variable declarations
C                    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 类型的标签, 可能是因为一个文件中如果有声明和定义, 可能会有两个相同的标签影响查看. 我这边是做了标签选择预览的, 所以不存在这个问题.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK