Vim: 设置 ctag 很困难。子目录中的源代码在项目根目录中看不到标签文件

今天我试着在 Vim 上安装(热情洋溢的) ctag,但是很难让它正常工作。我使用以下命令行生成 ctag 文件:

cd myproj
ctags -R

这将标记文件放在 myproj 根目录中。但是,当我在处理驻留在 root 中的源代码时,Vim 似乎只读取这个标记文件。当我导航到更深的目录时,如果我尝试使用 <C-]>跳转到一个标记,我会得到:

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

我已经验证了 MyClassName 在标记文件中确实有一个标记,只是 Vim 没有看到它。有人能解释一下如何将 Vim 配置为引用 root 的标记文件吗?

谢谢。

37412 次浏览

有一个选项可以告诉 Vim 在哪里查找标记文件。

我使用以下配置:

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

从帮助中摘录:

当标记文件名以“ ./”开头时,’.’将替换为 这使得在目录中使用标记文件成为可能 当前文件的位置(不管工作目录是什么) 之所以使用“ ./”,是因为您可以定义首先搜索哪个标记文件: 在 工作目录(“标记,./标记”)或当前文件的目录中 (“ ./标签,标签”)。

例如: Set tag = ./tag,tag,/home/user/common tag

我将当前的工作目录保存在生成 tags文件的 top project 目录中。

使用 :pwd:cd myproj(在 Vim 中)转到包含标记文件的目录。

有关标记路径的更多信息,请参见 :help tags-option

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

将其添加到 .vimrc文件 set tags=tags;/

这将检查当前文件夹的标记文件,并继续沿着一个目录向上一直到根文件夹。

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

如果您为每个项目生成一个标记文件,您可能会喜欢这种模式,特别是如果您跨不同的机器共享您的 .vimrc:

let repohome=substitute($REPO_HOME, "\/", "\\\\/", "g")
let &tags=substitute(expand("%:p:h"), "\\(".repohome."/.\\{-}\/\\).*", "\\1tags", "")

然后,你需要将环境变量 $REPO _ HOME 设置为主回购目录 没有的尾部空间(例如 /home/<yourusername>/repos) ,它会自动在 $REPO _ HOME 的每个子目录中查找一个深度为1的标记文件,例如 /home/<yourusername>/repos/myproj/tags

#!/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 文件并运行... 这将生成您的标记。

用下面的代码创建一个.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 -