Effortless ctags with git and submodules

Using Tim Popes Effortless ctags with Git I had the problem that tags for definitions in submodules where missing.

As I usually don’t make changes in submodules and these submodules are quite big I don’t want to run ctags on them every time I commit, I choose a manually approach to get tags inside submodules.

UPDATE Tim Pope removed the feature to add .git to the tags path in recent versions of vim-fugitive. We need to set it manually.


set tags^=.git/sub.tags
set tags^=.git/tags

to your vimrc. Then use

ctags --tag-relative -f .git/sub.tags -R $submodule-dirs

where $submodule-dirs are your directories containing submodules to create a separate tags file.

If you want to run ctags every time on the submodules use the following approach:

After digging a little bit I saw that he is using git ls-files to find files to pass to ctags. A quick study of man git-ls-files showed that you need to pass --recurse-submodules to git ls-files in order to get all files included in the submodules.

Change the ctags-script to be

set -e
dir="`git rev-parse --git-dir`"
trap 'rm -f "$dir/$$.tags"' EXIT
git ls-files --recurse-submodules | \
  ctags --extra=+f --tag-relative -L - -f"$dir/$$.tags" --languages=-javascript,sql
mv "$dir/$$.tags" "$dir/tags"

Note the extra --recurse-submodules behind git ls-files.

This will give you all definitions from submodules in your tags file. Note though, that this will take very long in large projects with many/big submodules. Especially when doing quick commits. A ctags process will be spawned every time you commit, even if there is already one running. This may result in heavy loads.