Thursday, September 2, 2010

Vim, PHP, TagList, and Ctags

I spent a good bit of time figuring out how to get vim to play nice with the spectacular TagList plugin, Ctags and PHP, so I've decided to sum up everything I did to get it working perfectly for the next person who comes along.

Installing TagList itself is simple---just follow the instructions, standard to installing any vim plugin. However, getting Exuberant Ctags, which is TagList's workhorse, to work properly with PHP is another matter. Ctags doesn't understand PHP very well. It picks up on variables (which is sorta useless in PHP, anyway) but not functions whose definitions specify access ("public", "protected", etc.), interfaces or abstract classes. How useless!

Creating a useful Ctags file for PHP is not difficult, thanks to the info at these two resources. Just use these flags:

ctags -R --exclude=.svn --tag-relative=yes --PHP-kinds=+cf-v --regex-PHP='/abstract\s+class\s+([^ ]+)/\1/c/' --regex-PHP='/interface\s+([^ ]+)/\1/c/' --regex-PHP='/(public\s+|static\s+|abstract\s+|protected\s+|private\s+)function\s+\&?\s*([^ (]+)/\2/f/' lib/

Notice that I exclude variables via the --PHP-kinds option. This isn't C, tyvm.

What I didn't understand, at first, is that TagList calls Ctags every single time it's opened so that it generates an up-to-date temporary tags file. This makes perfect sense, but when Ctags is called by TagList, it doesn't have all of our required command-line options. Enter the Ctags config file. Put the following in your ~/.ctags file:

--regex-PHP=/abstract\s+class\s+([^ ]+)/\1/c/
--regex-PHP=/interface\s+([^ ]+)/\1/c/
--regex-PHP=/(public\s+|static\s+|abstract\s+|protected\s+|private\s+)function\s+\&?\s*([^ (]+)/\2/f/

And, amazingly, TagList becomes useful for PHP development. The last step is to tweak TagList to work in a way that's most convenient for you. Personally, I like these options:

" set the names of flags
let tlist_php_settings = 'php;c:class;f:function;d:constant'
" close all folds except for current file
let Tlist_File_Fold_Auto_Close = 1
" make tlist pane active when opened
let Tlist_GainFocus_On_ToggleOpen = 1
" width of window
let Tlist_WinWidth = 40
" close tlist when a selection is made
let Tlist_Close_On_Select = 1

TagList has a ton of options, so check them out. You may also be interested in my most up-to-date .ctags and .vimrc.