• 修改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-(|all)=[+|-](|*) 参数去控制, 比如我需要控制 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 类型的标签, 可能是因为一个文件中如果有声明和定义, 可能会有两个相同的标签影响查看. 我这边是做了标签选择预览的, 所以不存在这个问题.

    参考

  • 相关阅读:
    python字典、列表排序,从简单到复杂
    java开发手册-05MySQL 数据库
    使用vscode编辑markdown文件(可粘贴截图)
    ITSS云能力评估是什么?
    Java 面试题一
    【深度学习】可交互讲解图神经网络GNN
    c语言-操作符详解(含优先级与结合性)
    Python 爬虫如何配置代理 IP (Py 采集)
    远程拷贝Windows上的文件到Linux指定的文件夹
    上传本地包到私有maven仓库
  • 原文地址:https://www.cnblogs.com/alps2006/p/17138347.html