Vim 维姆跳到了错误的标签上
标题说明了问题所在,下面是上下文。我有一个微小的C++文件Vim 维姆跳到了错误的标签上,vim,ctags,Vim,Ctags,标题说明了问题所在,下面是上下文。我有一个微小的C++文件 void f( int x ) { } void f( ) { } 我在上面运行CTAG ctags --recurse --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f tags f.C 检查标记文件时,会按预期显示f的两个条目,并带有正确的签名 当我尝试在Vim中使用它时,Vim使用ctrl-
void f(
int x
) { }
void f(
) { }
我在上面运行CTAG
ctags --recurse --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f tags f.C
检查标记文件时,会按预期显示f的两个条目,并带有正确的签名
当我尝试在Vim中使用它时,Vim使用ctrl-]定位函数,但当我使用:tnext和:tprev时,消息会显示标记1/2
或标记2/2
,但光标不会在它们之间移动。如果您查看,Vim使用第三列(名为{tagaddress}
)作为(搜索)命令()。在生成的标记文件中,它如下所示:
f foo.cpp /^void f($/;" f signature:( )
f foo.cpp /^void f($/;" f signature:( int x )
<> >强>两个重载的搜索模式(b bar.cpp /^void b()$/;" f signature:()
b bar.cpp /^void b(int x)$/;" f signature:(int x)
解决这一问题的一个更正确(但也是更复杂的)途径是扩展<代码> CTAGS < /Case>程序来识别这些歧义,然后用正的前瞻来扩充模式,也考虑下面行中的内容。
f foo.cpp /^void f(\%(\n\s*int x\)\@=/;" f signature:( )
f foo.cpp /^void f(\n\s*)/;" f signature:( int x )
不幸的是,Vim似乎不理解这种语法(无论有无前瞻);我只是得到了
E435:找不到标记,只是猜测!
根据Ingo Karkat的回答,这里有一个可能适合您的解决方案。如果您运行ctags
(至少是旺盛的ctags)使用--excmd=number
,它将输出行号,而不是针对标记位置的搜索命令,这将解决歧义
ctags --recurse --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f tags --excmd=number f.C
这样做的缺点是,一旦开始编辑文件,标签将无效,直到您再次运行CTAG。搜索模式比行号更容易受到影响
还有其他一些答案(只有一个)这涵盖了根据更改自动运行CTAG;这两种方法的某些组合可能适合您。使用更传统的编码风格的原因。回答不错!是的,感谢确认,这就是我担心的!对于如此短的函数,编码风格看起来有点奇怪,但我的实际用例有五个参数,其中两个是模板参数实例化,将它们以列格式分别写在单独的行上是完全合理的。它仍然会造成签名的模糊性。你刚刚击败了我!这对我来说是一个非常有效的解决方案。此外,如果我创建两个标记文件,在行号和regexp的基础上,我可以在它们之间切换,只需按一下键,就可以获得最好的both worlds.By kine number对于我的大多数(相当大的)代码库来说都是好的,当我有了方向时就切换到regexp。