Vim和Ctags技巧与诀窍

485

我刚刚安装了Ctags(用于辅助C++开发),并希望了解您最喜欢的命令、宏、快捷键、技巧等...

分享您的最佳武器。您还建议为Vim上的C++开发使用哪些其他插件?

编辑 您会与Ctags一起使用哪些其他插件?

编辑2 您使用的gVim版本有何不同?是否有影响?

编辑3 您如何增强大型和小型项目的编程体验?


15
请确保使用充满活力的 ctags(现代实现)以获得最佳结果:http://ctags.sourceforge.net/ - idbrii
17
"也许这个 kev 不够有建设性?" - Floyd
27
尽管两年前被判定为“不具建设性”,但对我而言,它非常有建设性。 - sazary
15
我认为关闭这个问题的真正原因应该是:“尽管这个问题非常有帮助,但它不符合 StackOverflow 的问答政策。让这个问题和回答转到 Quora 上去发展,而我们则固执地继续关闭有用的问题和回答。” - Diego Pino
2
我理解为什么这个问题按照 SO 的规则被关闭了。但是标记一个有 400 多个赞的问题和一个有 300 多个赞的答案进行 删除,这不太好吧? - DevSolar
显示剩余4条评论
15个回答

394

Ctrl+] - 跳转到定义
Ctrl+T - 从定义处返回
Ctrl+W Ctrl+] - 在水平分割窗口中打开定义

在vimrc文件中添加以下几行代码:
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+\ - 在新标签页中打开定义
Alt+] - 在垂直分割窗口中打开定义

当标签被生成后,你可以使用以下快捷键来跳转到和跳出函数:

Ctrl+左键单击 - 跳转到定义
Ctrl+右键单击 - 从定义处返回


8
C - ] => (Ctrl键)和]键C - T =>(Ctrl键)和T键这是给ctags新手的提示。感谢提供新建选项卡技巧。 - kumar
6
同样地,在使用 Ctrl-w C-] 命令分割窗口后,你可以使用 C-w T(即 Shift-t)将该窗口变成一个新的标签页。 - dash-tom-bang
1
@Will 如果你是在终端使用vim,那么你需要更改终端首选项以使选项键行为alt键。如果你使用的是MacVim,则将以下行添加到vimrc中:'set macmeta'。有关macmeta的文档,请参阅:h macmeta。 - Amjith
17
"g C-]" 非常有用。它打开一个快速对话框,让您在多个定义之间进行选择。 - Vincenzo Pii
3
g]也很有用。你可以将光标放在标签名称上,然后按下g]键以获取匹配标签的列表。 - zeekvfu
显示剩余7条评论

176

我 .vimrc 中必须要有的一行:

set tags=./tags;/

这将在当前目录中查找“tags”,并向上遍历树,直到找到一个为止。换句话说,您可以在源代码树的任何地方,而不仅仅是在其根目录中。


37
上溯至根目录有些过度了。我建议仅上溯至主目录:tags+=tags;$HOME - gotgenes
37
我所处理的源代码树并不总在我的主目录中,而由于$HOME目录通常距离根目录两级...我还可以再多查找两级目录 :) - uzi
6
我同意uzi的观点。如果我的当前工作目录是/home/me/programming/foo/bar/baz/bang/bam,那么只需要查找8个目录。我想这取决于你对速度的容忍度,但在我的机器上查找一个目录与查找8个目录的时间几乎没有明显的差别。 - Nate Murray
1
有没有类似于 cscope 的东西? - szx
1
如果您直接到根目录,甚至不需要 /。只需使用 ; 即可。 - danadam
显示剩余2条评论

45

另一个有用的C开发插件是cscope,就像Ctags可以跳转到定义,Cscope可以跳转到调用函数。

如果你的~/bin/目录中有cscope,将以下内容添加到你的.vimrc文件中,并使用g^]命令转到调用函数(参见::help cscope)。

if has("cscope")
    set csprg=~/bin/cscope
    set csto=0
    set cst
    set nocsverb
    " add any database in current directory
    if filereadable("cscope.out")
        cs add cscope.out
        " else add database pointed to by environment
    elseif $CSCOPE_DB != ""
        cs add $CSCOPE_DB
    endif
endif

差点忘了......就像ctags一样 - 你需要生成(并定期更新)数据库。我使用以下脚本

select_files > cscope.files
ctags -L cscope.files
ctags -e -L cscope.files
cscope -ub -i cscope.files

‘select_files’是另一个脚本,它从Makefile中提取C和头文件列表。这样我只索引项目实际使用的文件。


4
它们互相补充。Ctags 可以找到符号或函数的定义。Cscope 可以找到调用函数的所有位置。同时使用它们可以使在大型源代码树中导航变得非常容易。 - nimrodm
1
然而,据我所知,cscope对C++的理解能力有限。 - Luc Hermitte
你能展示一下 select_files 脚本的例子吗? - vehomzzz
2
@Whaledawg 是的,当我按下CTRL+]时,我的声卡会发送“clap.wav”作为输出 :) - Patrizio Rullo
@vehomzzz:nimrodm在他的makefile中使用了一些高级技巧,但你可以直接使用find命令:find . -type f \( -iname "*.cpp" -o -iname "*.h" \) - idbrii
显示剩余3条评论

27

您可以将目录添加到ctags搜索中。例如,我已经为Qt4构建了一个ctags索引,并将其添加到我的.vimrc文件中:

set tags+=/usr/local/share/ctags/qt4

23

5
我认为添加这个标签列表(taglist.vim)是最受欢迎的 Vim 插件会很好。 - amit kumar

16

我使用 ALT-左箭头 和 ALT-右箭头 来从标签堆栈中弹出/推入。

" Alt-right/left to navigate forward/backward in the tags stack
map <M-Left> <C-T>
map <M-Right> <C-]>

如果你使用 hjkl 进行光标移动,你可以将其映射为 <M-h><M-l>


不同于ctrl-]和ctrl-t--我猜你的建议更加简洁。 - Sasha
@ Sasha,抱歉?不知道你在说什么。=X 请注意,这也适用于:help。 - strager
2
我认为这比默认更直观和清晰。 - Ayman
1
@Ayman 但同时也违反了不需要将手移开主键区的原则,就像使用 hjkl 而非箭头键一样。 - TankorSmash
@TankorSmash,什么原则? - strager

10

同名定义有多个

<C-w>g<C-]> 打开分区中的定义,并执行 :tjump 命令,如果只有一个定义,则直接跳转到该定义;如果有多个定义,则会显示可供选择的定义列表。


2
与第一个命令类似,vim 有一个 :ptag 命令,可以在预览窗口中打开定义。 - idbrii
1
预览窗口很好用,因为你可以从任何其他窗口使用 :pc 关闭它,而不必先将光标移动到预览窗口。 - Heikki Naski
还有一个很棒的自动命令技巧,使用:h CursorHold-exampleptag,在可配置的超时时间后,在预览窗口中显示光标下项目的标签。 - dash-tom-bang
+1 for :tjump 我现在绑定了 :tjump <C-r><C-w><CR> 在我看来比<C-]>效果更好希望能将此行为与:ptag结合起来 - Andreas Fliesberg
有时候,:help 真的很棒... 请查看 :help CTRL-W_g}:ptjump - Andreas Fliesberg

8

我最常使用的命令是C-],它可以跳转到光标下函数的定义。你可以更频繁地使用它来跟踪更多的调用。之后,C-o将带您返回上一层,C-i再次深入。


16
C-t 在 C-] 栈中返回上一级,而 C-o 在移动后返回先前的光标位置。因此,如果你使用 C-] 跳转到一个函数,然后向下翻页,C-t 将立即返回上一级,而 C-o 将返回函数的开头,然后返回调用处。 - Greg Hewgill

6

我发现taglist插件是必备的。它会在一个单独的窗口中列出所有已知的标签(您打开的文件),使得浏览大型文件变得非常容易。

我主要用它来进行Python开发,但对于C/C++来说也会更好用。


5

我已经将标签操作封装在我的实验性插件中。

关于在vim中进行C++开发,我已经在这里回答过:我使用自己的套件和其他几个插件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接