Skip to content
This repository

Support for additional filetypes

Ada

Needs excuberant-ctags with Ada support: rtyler/ctags.

let g:tagbar_type_ada = {
    \ 'ctagstype': 'ada',
    \ 'kinds' : [
        \'P:package specs',
        \'p:packages',
        \'t:type',
        \'u:subtypes',
        \'c:record type components',
        \'l:enum type literals',
        \'v:variables',
        \'f:formal parameters',
        \'n:constants',
        \'x:exceptions',
        \'R:subprogram specs',
        \'r:subprograms',
        \'K:task specs',
        \'k:tasks',
        \'O:protected data specs',
        \'o:protected data',
        \'e:entries',
        \'b:labels',
        \'i:identifiers'
    \]
    \}

ArmAsm

If you installed alisdair/vim-armasm for syntax coloring of ARM assembly, add the following to you .vimrc:

let g:tagbar_type_armasm = {
    \ 'ctagsbin'  : 'ctags',
    \ 'ctagsargs' : '-f- --format=2 --excmd=pattern --fields=nksSa --extra= --sort=no --language-force=asm',
    \ 'kinds' : [
        \ 'm:macros:0:1',
        \ 't:types:0:1',
        \ 'd:defines:0:1',
        \ 'l:labels:0:1'
    \ ]
\}

AsciiDoc

Single-line section titles only. Hierarchy is produced synthetically since regex matching does not support scopes.

Add the following to your ~/.ctags:

--langdef=asciidoc
--langmap=asciidoc:.ad.adoc.asciidoc
--regex-asciidoc=/^=[ \t]+(.*)/# \1/s,Section_L0/
--regex-asciidoc=/^==[ \t]+(.*)/. \1/s,Section_L1/
--regex-asciidoc=/^===[ \t]+(.*)/. . \1/s,Section_L2/
--regex-asciidoc=/^====[ \t]+(.*)/. . . \1/s,Section_L3/
--regex-asciidoc=/^=====[ \t]+(.*)/. . . . \1/s,Section_L4/

... and the following in vimrc:

let g:tagbar_type_asciidoc = {
    \ 'ctagstype' : 'asciidoc',
    \ 'kinds' : [
        \ 's:Table of Contents'
    \ ]
\ }

Appears as:

Table of Contents
# Document Title
. Chapter A
. . Section A
. . Section B
. . . Subsection
. . Section C
. Chapter B

Clojure

See (http://clojurewise.blogspot.cz/2010/03/using-ctags-with-clojure.html).

CoffeeScript

CoffeeScript support is provided by CoffeeTags. That page explains everything about how to set up CoffeeTags with Tagbar.

As an alternative, if you dont want to depend on ruby(which is needed by coffeetags) you can add this to your vimrc:

let g:tagbar_type_coffee = {
    \ 'ctagstype' : 'coffee',
    \ 'kinds'     : [
        \ 'c:classes',
        \ 'm:methods',
        \ 'f:functions',
        \ 'v:variables',
        \ 'f:fields',
    \ ]
\ }

" Posix regular expressions for matching interesting items. Since this will 
" be passed as an environment variable, no whitespace can exist in the options
" so [:space:] is used instead of normal whitespaces.
" Adapted from: https://gist.github.com/2901844
let s:ctags_opts = '
  \ --langdef=coffee
  \ --langmap=coffee:.coffee
  \ --regex-coffee=/(^|=[ \t])*class ([A-Za-z_][A-Za-z0-9_]+\.)*([A-Za-z_][A-Za-z0-9_]+)( extends ([A-Za-z][A-Za-z0-9_.]*)+)?$/\3/c,class/
  \ --regex-coffee=/^[ \t]*(module\.)?(exports\.)?@?(([A-Za-z][A-Za-z0-9_.]*)+):.*[-=]>.*$/\3/m,method/
  \ --regex-coffee=/^[ \t]*(module\.)?(exports\.)?(([A-Za-z][A-Za-z0-9_.]*)+)[ \t]*=.*[-=]>.*$/\3/f,function/
  \ --regex-coffee=/^[ \t]*(([A-Za-z][A-Za-z0-9_.]*)+)[ \t]*=[^->\n]*$/\1/v,variable/
  \ --regex-coffee=/^[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)[ \t]*=[^->\n]*$/\1/f,field/
  \ --regex-coffee=/^[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+):[^->\n]*$/\1/f,static field/
  \ --regex-coffee=/^[ \t]*(([A-Za-z][A-Za-z0-9_.]*)+):[^->\n]*$/\1/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?/\3/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){0}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){1}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){2}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){3}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){4}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){5}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){6}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){7}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){8}/\8/f,field/
  \ --regex-coffee=/((constructor|initialize):[ \t]*\()@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?(,[ \t]*@(([A-Za-z][A-Za-z0-9_.]*)+)([ \t]*=[ \t]*[^,)]+)?){9}/\8/f,field/'

let $CTAGS = substitute(s:ctags_opts, '\v\\([nst]\)', '\\\\\1', 'g')

CSS

CSS support requires the use of a patched CTags installation, and the following vimrc configuration:

let g:tagbar_type_css = {
\ 'ctagstype' : 'Css',
    \ 'kinds'     : [
        \ 'c:classes',
        \ 's:selectors',
        \ 'i:identities'
    \ ]
\ }

Google Go

Proper Go support is provided by the gotags project, complete with how to configure Tagbar to make use of it.

Alternatively, if you use the Go patch for exuberant-ctags or the Debian/Ubuntu package (which has it integrated), the following configuration provides simple support without scopes:

let g:tagbar_type_go = {
    \ 'ctagstype': 'go',
    \ 'kinds' : [
        \'p:package',
        \'f:function',
        \'v:variables',
        \'t:type',
        \'c:const'
    \]
\}

Groovy

The following Groovy configuration was provided by Siddhartha Kasivajhula based on this TagList setup.

Put this into your ~/.ctags:

--langdef=groovy
--langmap=groovy:.groovy
--regex-groovy=/^[ \t][(private|public|protected) ( \t)][A-Za-z0-9<>]+[ \t]+([A-Za-z0-9]+)[ \t](.)[ \t]{/\1/f,function,functions/
--regex-groovy=/^[ \t]*def[ \t]+([A-Za-z0-9_]+)[ \t]\=[ \t]{/\1/f,function,functions/
--regex-groovy=/^[ \t]*private def[ \t]+([A-Za-z0-9_]+)[ \t]/\1/v,private,private variables/
--regex-groovy=/^[ \t]def[ \t]+([A-Za-z0-9_]+)[ \t]/\1/u,public,public variables/
--regex-groovy=/^[ \t][abstract ( \t)][(private|public) ( \t)]class[ \t]+([A-Za-z0-9_]+)[ \t]/\1/c,class,classes/
--regex-groovy=/^[ \t][abstract ( \t)][(private|public) ( \t)]enum[ \t]+([A-Za-z0-9_]+)[ \t]/\1/c,class,classes/

And then add this to your ~/.vimrc:

let g:tagbar_type_groovy = {
    \ 'ctagstype' : 'groovy',
    \ 'kinds'     : [
        \ 'p:package',
        \ 'c:class',
        \ 'i:interface',
        \ 'f:function',
        \ 'v:variables',
    \ ]
\ }

Haskell

The easier way to get Haskell support is to use lushtags. However, lushtags does not seem to be able to parse files with do notation (failed parses result in empty an tagbar) and has not been properly updated for a while.

A more reliable alternative is hasktags. Add the following to you .vimrc.

let g:tagbar_type_haskell = {
    \ 'ctagsbin'  : 'hasktags',
    \ 'ctagsargs' : '-x -c -o-',
    \ 'kinds'     : [
        \  'm:modules:0:1',
        \  'd:data: 0:1',
        \  'd_gadt: data gadt:0:1',
        \  't:type names:0:1',
        \  'nt:new types:0:1',
        \  'c:classes:0:1',
        \  'cons:constructors:1:1',
        \  'c_gadt:constructor gadt:1:1',
        \  'c_a:constructor accessors:1:1',
        \  'ft:function types:1:1',
        \  'fi:function implementations:0:1',
        \  'o:others:0:1'
    \ ],
    \ 'sro'        : '.',
    \ 'kind2scope' : {
        \ 'm' : 'module',
        \ 'c' : 'class',
        \ 'd' : 'data',
        \ 't' : 'type'
    \ },
    \ 'scope2kind' : {
        \ 'module' : 'm',
        \ 'class'  : 'c',
        \ 'data'   : 'd',
        \ 'type'   : 't'
    \ }
\ }

JavaScript

There are three options to generate an Exuberant Ctags file, 2 of which are partially working with more or less hacking, the last one is still in early development.

jsctags (doctorjs)

jsctags has much better support for JavaScript than standard Exuberant Ctags and is itself written in JavaScript. Tagbar already includes support for jsctags, so if your jsctags executable is in your $PATH it should just work. If it is not in your $PATH you have to copy this into your ~/.vimrc and adjust the path accordingly:

let g:tagbar_type_javascript = {
    \ 'ctagsbin' : '/path/to/jsctags'
\ }

Note that currently there is a bug in jsctags that will cause all tags to be reported as top-level tags instead of in their proper scopes (see here for progress on the bug: https://github.com/mozilla/doctorjs/issues/5).

In order to get proper support for scopes you can check out an older, working version by doing this in a git clone of jsctags (note: this only works with node 0.4x):

git checkout 1062dd31625cc002261f15e68af77eedd63a56f6
git submodule update --init --recursive
sudo make install

For newer node versions you probably also need to apply this patch, or you can try this fork that already has support for newer nodes. For either one, you must install Narcissus too.

git submodule update --init --recursive
sudo make install
Exuberant Ctags (Vanilla)

The simplest option of all, just append the following code to your ~/.ctags file. Use this method only when viewing older simple JavaScript files, as scopes and the modern way of JavaScript development is not supported.

--langdef=js
--langmap=js:.js
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/o,object/

--regex-JavaScript=/([A-Za-z0-9._$'"()]+)[ \t]*[:][ \t]*function[ \t]*\([^)]*\)/\1/f,function/

--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/a,array/

--regex-JavaScript=/([^= ]+)[ \t]*=[ \t]*'[^']*'/\1/s,string/

--regex-JavaScript=/([^= ]+)[ \t]*=[ \t]*"[^"]*"/\1/s,string/
jsctags (tern-based) ** Experimental WIP **

In addition there is a new project that uses the tern library that tries to provide JavaScript integration support for IDEs. Exuberant ctags output support is currently work in progress.

Markdown

Add the following to your ~/.ctags:

--langdef=markdown
--langmap=markdown:.mkd
--regex-markdown=/^#[ \t]+(.*)/\1/h,Heading_L1/
--regex-markdown=/^##[ \t]+(.*)/\1/i,Heading_L2/
--regex-markdown=/^###[ \t]+(.*)/\1/k,Heading_L3/

... and the following in vimrc:

let g:tagbar_type_markdown = {
    \ 'ctagstype' : 'markdown',
    \ 'kinds' : [
        \ 'h:Heading_L1',
        \ 'i:Heading_L2',
        \ 'k:Heading_L3'
    \ ]
\ }

Alternatively, you can use markdown2ctags to generate the tags. It handles both the ATX-style headings, like the above, and the underline (Settext) style headings. It also understands nesting, so you can see a proper tree in TagBar. Simply put the script somewhere and this to your ~/.vimrc:

let g:tagbar_type_markdown = {
    \ 'ctagstype': 'markdown',
    \ 'ctagsbin' : '/path/to/markdown2ctags.py',
    \ 'ctagsargs' : '-f - --sort=yes',
    \ 'kinds' : [
        \ 's:sections',
        \ 'i:images'
    \ ],
    \ 'sro' : '|',
    \ 'kind2scope' : {
        \ 's' : 'section',
    \ },
    \ 'sort': 0,
\ }

NASL

Add the following to your ~/.ctags:

--langdef=nasl
--langmap=nasl:.inc
--regex-nasl=/^[ \t]*function[ \t]+([_a-zA-Z][_a-zA-Z0-9]*)/\1/f,function/
--regex-nasl=/^([_a-zA-Z][_a-zA-Z0-9]*)[ \t]*=/\1/v,variable/
--regex-nasl=/^global_var ([_a-zA-Z][_a-zA-Z0-9]*)/\1/g,global/

... and the following in vimrc:

let g:tagbar_type_nasl = {
    \ 'ctagstype' : 'nasl',
    \ 'kinds'     : [
        \ 'f:function',
        \ 'v:variables',
        \ 'g:globals',
    \ ]
\ }

PHP

The standard PHP parser provided by ctags is pretty rudimentary and doesn't support scopes. Techlive Zheng has written a plugin that provides better support through a program written in PHP itself.

Puppet

Quick and dirty puppet file support. Based on this mailing list post.

Add this to your ~/.ctags:

--langdef=puppet
--langmap=puppet:.pp
--regex-puppet=/^class[ \t]*([:a-zA-Z0-9_\-]+)[ \t]*/\1/c,class/
--regex-puppet=/^site[ \t]*([a-zA-Z0-9_\-]+)[ \t]*/\1/s,site/
--regex-puppet=/^node[ \t]*([a-zA-Z0-9_\-]+)[ \t]*/\1/n,node/
--regex-puppet=/^define[ \t]*([:a-zA-Z0-9_\-]+)[ \t]*/\1/d,definition/

And add this to your .vimrc:

let g:tagbar_type_puppet = {
    \ 'ctagstype': 'puppet',
    \ 'kinds': [
        \'c:class',
        \'s:site',
        \'n:node',
        \'d:definition'
      \]
    \}

R

Quick-and-dirty R support based on this answer on StackOverflow:

Add this to your ~/.ctags:

--langdef=R
--langmap=r:.R.r
--regex-R=/^[ \t]*"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t]function/\1/f,Functions/
--regex-R=/^"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t][^f][^u][^n][^c][^t][^i][^o][^n]/\1/g,GlobalVars/ 
--regex-R=/[ \t]"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t][^f][^u][^n][^c][^t][^i][^o][^n]/\1/v,FunctionVariables/

And add this to your .vimrc:

let g:tagbar_type_r = {
    \ 'ctagstype' : 'r',
    \ 'kinds'     : [
        \ 'f:Functions',
        \ 'g:GlobalVariables',
        \ 'v:FunctionVariables',
    \ ]
\ }

reStructuredText

You can use rst2ctags to generate a ctags-compatible tags file for the sections of a reStructuredText document. Docutils is notoriously slow, so the script implements into own parsing technique to keep it fast. Put the script somewhere and include this in your ~/.vimrc:

let g:tagbar_type_rst = {
    \ 'ctagstype': 'rst',
    \ 'ctagsbin' : '/path/to/rst2ctags.py',
    \ 'ctagsargs' : '-f - --sort=yes',
    \ 'kinds' : [
        \ 's:sections',
        \ 'i:images'
    \ ],
    \ 'sro' : '|',
    \ 'kind2scope' : {
        \ 's' : 'section',
    \ },
    \ 'sort': 0,
\ }

Ruby

The ctags fork at https://github.com/fishman/ctags provides additional support for RSpec context and describe kinds. Patrik Sundberg has created an updated configuration that makes use of it:

let g:tagbar_type_ruby = {
    \ 'kinds' : [
        \ 'm:modules',
        \ 'c:classes',
        \ 'd:describes',
        \ 'C:contexts',
        \ 'f:methods',
        \ 'F:singleton methods'
    \ ]
\ }

Scala

An example configuration for Scala, which requires adding a ctags regexp configuration, is described here. Note that instead of putting the Tagbar configuration directly into one of Tagbar's files as the post suggests put this into your ~/.vimrc:

let g:tagbar_type_scala = {
    \ 'ctagstype' : 'Scala',
    \ 'kinds'     : [
        \ 'p:packages:1',
        \ 'V:values',
        \ 'v:variables',
        \ 'T:types',
        \ 't:traits',
        \ 'o:objects',
        \ 'a:aclasses',
        \ 'c:classes',
        \ 'r:cclasses',
        \ 'm:methods'
    \ ]
\ }

UltiSnips

To get a simplistic but nice list of snippets while you're editing your UltiSnips files, put this inside your ~/.ctags:

--langdef=snippets
--langmap=snippets:.snippets
--regex-snippets=/^snippet (.*)/\1/s,snippet/

... and the following in your ~/.vimrc:

let g:tagbar_type_snippets = {
    \ 'ctagstype' : 'snippets',
    \ 'kinds' : [
        \ 's:snippets',
    \ ]
\ }

Xquery

Put this in your ~/.ctags: (make sure to copy the source, as the gist rendering will remove some of the code!)

--langdef=xquery
--langmap=xquery:.xq
--regex-xquery=/^(declare|define)[ \t]*(private)?[ \t]*(updating)?[ \t]*(%an:sequential)?[ \t]*(%an:nondeterministic)?[ \t]*function[ \t]*([_a-zA-Z0-9:-]*:)?([_a-zA-Z0-9-]+)/\7/f,function/
--regex-xquery=/^(declare|define)[ \t]*(private)?[ \t]*(%an:automatic)?[ \t]*variable[ \t]*\$([_a-zA-Z0-9:-]*:)?([_a-zA-Z0-9-]+)/\5/v,variable/
--regex-xquery=/^module namespace[ \t]*(\w+)[ \t]*=.*/\1/m,module/

And put this in your ~/.vimrc:

let g:tagbar_type_xquery = {
    \ 'ctagstype' : 'xquery',
    \ 'kinds'     : [
        \ 'f:function',
        \ 'v:variable',
        \ 'm:module',
    \ ]
\ }

VHDL

Put this in your .vimrc:

let g:tagbar_type_vhdl = {
    \ 'ctagstype': 'vhdl',
    \ 'kinds' : [
        \'d:prototypes',
        \'b:package bodies',
        \'e:entities',
        \'a:architectures',
        \'t:types',
        \'p:processes',
        \'f:functions',
        \'r:procedures',
        \'c:constants',
        \'T:subtypes',
        \'r:records',
        \'C:components',
        \'P:packages',
        \'l:locals'
    \]
\}
Something went wrong with that request. Please try again.