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 tf
和 tn
始终显示第一个定义在文件中。
我也可以用 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 SomeMethod
和 tn
,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:
我有一个像这样的简单 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 tf
和 tn
始终显示第一个定义在文件中。
我也可以用 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 SomeMethod
和 tn
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: