Ctags for Crystal

Crystal is what I spend most of my spare time doing right now. I'm also a fan of Ctags, but unfortunately it doesn't have a parser for Crystal by default. I did a quick search on the Internet but came up short. The only Ctags Regex rules I could find was for Exuberant Ctags, which isn't compatible with my version of Universal Ctags.

Fortunately, there is great documentation on how to add your own Regex parser. So down the rabbit whole I went, and came up with the following parser:

--langdef=crystal

--map-crystal=.cr

--kinddef-crystal=a,macro,macros
--kinddef-crystal=c,class,classes
--kinddef-crystal=m,method,methods
--kinddef-crystal=M,module,modules
--kinddef-crystal=s,struct,structs

--regex-crystal=/^[ \t]*(private[ \t]+)?(abstract[ \t]+)?class[ \t]+([A-Z][A-Za-z0-9_]*::)*([A-Z][A-Za-z0-9_]*)/\4/c/{scope=push}
--regex-crystal=/^[ \t]*(private[ \t]+)?(abstract[ \t]+)?struct[ \t]+([A-Z][A-Za-z0-9_]*::)*([A-Z][A-Za-z0-9_]*)/\4/s/{scope=push}
--regex-crystal=/^[ \t]*(private[ \t]+)?macro[ \t]+([a-z_][a-zA-Z0-9_?!]+)/\2/a/{scope=push}
--regex-crystal=/^[ \t]*(private[ \t]+)?module[ \t]+([A-Z][A-Za-z0-9_]*::)*([A-Z][A-Za-z0-9_]*)/\3/M/{scope=push}
--regex-crystal=/^[ \t]*(private[ \t]+|protected[ \t]+)?(abstract[ \t]+)?def[ \t]+([a-z_][a-zA-Z0-9_?!]+)/\3/m/{scope=push}
--regex-crystal=/^[ \t]*end///{scope=pop}{placeholder}

It supports class, def, macro, module and struct definitions.

Put the above in $HOME/.config/ctags/crystal.ctags or any of the other locations CTags looks in by default.

VoilĂ !