vim 和 ctags,未找到具有相同签名的多个定义

vim and ctags, multiple definitions with same signature not found

我有一个像这样的简单 C++ 文件:

class SomeClass
{
    void SomeMethod() {};
};

class AnotherClass
{
    void SomeMethod() {};
};

如果我用 ctags -R * 生成一个 ctags 文件,我得到:

AnotherClass    main.cpp    /^    class AnotherClass$/;"    c   file:
SomeClass   main.cpp    /^    class SomeClass$/;"   c   file:
SomeMethod  main.cpp    /^        void SomeMethod() {};$/;" f   class:AnotherClass  typeref:typename:void   file:
SomeMethod  main.cpp    /^        void SomeMethod() {};$/;" f   class:SomeClass typeref:typename:void   file:

如您所见,SomeMethod 的定义条目没有区别,因为 vim tftn 始终显示第一个定义在文件中。

我也可以用 ctags --fields=+n * 添加行号 结果是:

...
AnotherClass    main.cpp    /^    class AnotherClass$/;"    c   line:6  file:
SomeClass   main.cpp    /^    class SomeClass$/;"   c   line:1  file:
SomeMethod  main.cpp    /^        void SomeMethod() {};$/;" f   line:3  class:SomeClass typeref:typename:void   file:
SomeMethod  main.cpp    /^        void SomeMethod() {};$/;" f   line:8  class:AnotherClass  typeref:typename:void   file:

但是如果我使用 ta SomeMethodtn

,vim 也总是跳转到 SomeMethod 的第一个定义

我在这个版本中使用 ctags:

Universal Ctags 0.0.0(2614dbe1), Copyright (C) 2015 Universal Ctags Team Universal Ctags is derived from Exuberant Ctags. Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert Compiled: Sep 5 2019, 13:10:38 URL: https://ctags.io/ Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +yaml, +packcc

和vim是:

VIM - Vi IMproved 8.1 Patch 1-1713

您需要:

  • 将正确的数字传递给 :tag & co,
  • 或使用:tselect
  • 或使用有助于 distinguish/select 您感兴趣的过载的插件(例如我的旧 lh-tags 插件)
  • 或更现代的解决方案,如 LSP 服务器:最近我发现 coc+ccls 非常好,因为它会从上下文中知道光标下的确切过载,这对于基于标签的情况是不可能的解决方案。

我自己找到了一个简单的解决方案:

ctags --excmd=number *

完成任务。

在标签文件的第三列中,我们找到 vim 用来在文件中查找位置的 excmd。

SomeMethod  main.cpp    /^        void SomeMethod() {};$/;" f   line:8  class:AnotherClass  typeref:typename:void   file:

变成

SomeMethod  main.cpp    8;" f   line:8  class:AnotherClass  typeref:typename    :void   file:

现在 vim 没有搜索在标签文件中重复的表达式,而是简单地转到 excmd 中的行。

尝试--excmd=combine。它将行号添加到模式中。

$ cat /tmp/main.cpp 
class SomeClass
{
    void SomeMethod() {};
};

class AnotherClass
{
    void SomeMethod() {};
};
$ ./ctags -o - --excmd=combine /tmp/main.cpp
AnotherClass    /tmp/main.cpp   5;/^class AnotherClass$/;"  c   file:
SomeClass   /tmp/main.cpp   0;/^class SomeClass$/;" c   file:
SomeMethod  /tmp/main.cpp   2;/^    void SomeMethod() {};$/;"   f   class:SomeClass typeref:typename:void   file:
SomeMethod  /tmp/main.cpp   7;/^    void SomeMethod() {};$/;"   f   class:AnotherClass  typeref:typename:void   file:
$ ./ctags -o - --excmd=combine -B /tmp/main.cpp
AnotherClass    /tmp/main.cpp   7;?^class AnotherClass$?;"  c   file:
SomeClass   /tmp/main.cpp   2;?^class SomeClass$?;" c   file:
SomeMethod  /tmp/main.cpp   4;?^    void SomeMethod() {};$?;"   f   class:SomeClass typeref:typename:void   file:
SomeMethod  /tmp/main.cpp   9;?^    void SomeMethod() {};$?;"   f   class:AnotherClass  typeref:typename:void   file: