I use git, and a big part of my workflow is jumping around between branches. A major issue with switching branches frequently is code completion - each time I switch, my tag file is suddenly out of date. There are plugins out there that try to ease this process, but I never found anything that quite fit what I wanted to do.

So, I decided to roll my own little function. Essentially, my goal was to regenerate my tag file any time I hit a key press - and that generation needed to happen in the background, so I don’t have to sit around twiddling my thumbs while ctags crawls my filesystem.

Throw this in your .vimrc, and you should be good to go:

" Regenerates ctags with ctagsgen.sh in a background process. " If a directory is not supplied, then pwd will be used. If suppressOutput is " true, then AsyncCommand will be used instead of AsyncShell (so no output " comes back to the user) function Tagrefresh( dir , suppressOutput) if empty(a: dir ) let gendir = substitute(system( 'pwd' ), "

", '', '') else let gendir = a: dir endif if a:suppressOutput execute "AsyncCommand(~/.vim/ctagsgen.sh " . gendir . ")" else execute "AsyncShell(~/.vim/ctagsgen.sh " . gendir . ")" endif endfunction

Note that there are a couple of requirements:

#!/bin/bash cd $1 exec ctags -f ~/.vimtags \ -h "\.php" -R \ --exclude = \"\.svn\" \ --exclude = \"\.git\" \ --totals = yes \ --tag-relative = yes \ --PHP-kinds = +cf \ --regex-PHP = '/abstract class ([^ ]*)/\1/c/' \ --regex-PHP = '/interface ([^ ]*)/\1/c/' \ --regex-PHP = '/(public |static |abstract |protected |private )+function ([^ (]*)/\2/f/'

AsyncCommand by David Briscoe must be installed. The script expects a basic ctags script to generate tags. Here’s a simple one for PHP:

[Update] fjonk over at reddit suggested using a git post-checkout hook to generate tags. This is another good solution if you want to generate tags every time you switch branches.

Additionally, shawncplus has a nice plugin that will parse tags in the active file. Good complement to Tagrefresh.