Vim:设置ctags困难。子目录中的源代码无法看到项目根目录中的tags文件。

72

今天我在尝试在Vim上设置(exuberant)ctags,但是遇到了无法正常工作的困难。我在命令行上使用以下命令生成我的ctags文件:

cd myproj
ctags -R

这会将tags文件放在myproj根目录下。然而,只有在我处理位于根目录下的源代码时,Vim才似乎从这个tags文件中读取。当我进入更深的目录时,如果我尝试使用<C-]>跳转到标签,我会得到:

E433: No tags file
E426: tag not found: MyClassName

我验证过 MyClassName 在 tags 文件中有标签,只是 Vim 没有看到它。请问如何配置 Vim 引用根目录的 tags 文件?

谢谢。

5个回答

142

将以下内容添加到.vimrc文件中:set tags=tags;/

这将从当前文件夹开始检查标签文件,并一直向上遍历直到根目录。

因此,您可以在项目的任何子文件夹中,并且它将能够找到标签文件。


8
如果您有其他的标签文件,您可能想要执行 set tags+=tags;/ - Henry Hu
45
如果你和我一样对于 tags;/ 这个表示感到困惑,那么 ;/ 后缀会指示 vim 在包含 tags 文件的目录向上搜索,直到停止目录为止(在这个例子中是 /)。如果你想要使用你的 home 目录作为停止目录,可以使用 set tags+=tags;~set tags+=tags;$HOME。或者你也可以使用项目树的顶级目录作为停止目录。(请参考 :help file-searching 以了解分号的用法。)另外,请注意搜索 tags 文件时受 autochdir 的影响。我在我的 .vimrc 文件中使用的设置是 set tags=./tags,./TAGS,tags;~,TAGS;~ - Andrej Panjkov
我有一个tags文件,它在同一目录下被忽略了,需要使用set tags=./tags;/ - xtian
1
@Amjith 我们不断地更改文件,因此ctags也需要更新。我们能自动化吗? - kamal
1
我使用的系统上有一个相当老的 Vim 版本:7.4。set tags=tags;/ 可以正常工作...但是我在 :help 文档中找不到任何关于这个机制的参考。:help tags-option 中也没有任何信息。在 help.txttagsrch.txt 帮助文件中搜索 ;/ 也没有结果。 - Kaz
显示剩余3条评论

15

Vim有一个选项可以告诉它去哪里查找标签文件。

我使用以下配置:

" search first in current directory then file directory for tag file
set tags=tags,./tags

从帮助文件中提取:

如果一个标签文件以 "./" 开头,'.' 将被替换为当前文件的路径。这样可以在当前文件所在的目录中使用标签文件(无论当前目录是什么)。使用 "./" 的想法是可以定义首先搜索哪个标签文件:在当前目录中搜索("tags,./tags"),还是在当前文件所在的目录中搜索("./tags,tags")。

例如: :set tags=./tags,tags,/home/user/commontags

我将我的当前工作目录保留在生成我的tags文件的顶级项目目录中。

使用 :pwd 然后使用 :cd myproj 命令(在 Vim 内部)进入包含你的标签文件的目录。

请参阅 :help tags-option 获取有关标签路径的更多信息。

你可能遇到的问题是你在错误的目录中,或者你的 tags 选项没有正确设置。


这解释了很多问题。谢谢。我之所以只接受了另一个答案作为正确答案,是因为在我的设置中,当前工作目录会随着我编辑的每个缓冲区而改变。因此,更实际的方法是跳转到目录结构的上一级,在根目录中查找标签文件。 - Thomas

2
#!/bin/sh

FREEZE_NAME=/* Give some version number */

mkdir $HOME/ctags/$FREEZE_NAME

V1=/* Software Path */

find $V1 -name "*.h" | xargs /usr/local/bin/ctags -a -f $HOME/ctags/$FREEZE_NAME/h.tags

find $V1 -name "*.c" | xargs /usr/local/bin/ctags -a -f $HOME/ctags/$FREEZE_NAME/c.tags

cd $HOME/ctags/$FREEZE_NAME/

rm -f all.tags

cat c.tags h.tags >> all.tags

sort all.tags > temp.tags

mv temp.tags all.tags

rm -f c.tags h.tags 

将上述代码放入一个.sh文件中并运行...这样肯定会生成您的标签。

1
如果您为每个项目生成一个标签文件,您可能会喜欢这个模式,特别是如果您在不同的机器上共享您的.vimrc
let repohome=substitute($REPO_HOME, "\/", "\\\\/", "g")                         
let &tags=substitute(expand("%:p:h"), "\\(".repohome."/.\\{-}\/\\).*", "\\1tags", "")

您需要在 .bashrc 中设置环境变量 $REPO_HOME,将其设置为您的主存储库目录,不要 保留尾随空格(例如:/home/<yourusername>/repos)。它将自动在 $REPO_HOME 的每个子目录中查找深度为1的标签文件,例如:/home/<yourusername>/repos/myproj/tags


0

创建一个包含以下代码的 .sh 文件。然后在您想要标签的地方运行 .sh 文件。 这肯定会起作用。

#!/bin/sh`enter code here`
filelist=`mktemp`
find . -name \*.h >> ${filelist}
find . -name \*.c >> ${filelist}
find . -name \*.cc >> ${filelist}
find . -name \*.cpp >> ${filelist}
find . -name \*.hpp >> ${filelist}
if [ "$SDKTARGETSYSROOT" != "" ]; then
find $SDKTARGETSYSROOT/usr/include -name \*.h >> ${filelist}
fi
cat ${filelist} | ctags -L -

这很棒,你们可以试试看。 - Ramanand Yadav

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