Skip to content
David Hegland edited this page Sep 21, 2023 · 165 revisions

Note: Tagbar is documented using VIM's inline help system, run :help tagbar after installation for setup and usage instructions.


Support for additional filetypes

Table of Contents generated with DocToc

overview

tagbar refered tag file. universal-ctags has more support languages than excuberant-ctags. Many of this wiki's entry mentioned excuberant-ctags. if you can install universal-ctags, please do ctags --list-languages. you can see 118 languages such as asciidoc. (2020-09-06T19:26:10)

$ ctags --version
Universal Ctags 0.0.0, Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Aug 24 2020, 09:57:20
  URL: https://ctags.io/
  Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +json, +interactive, +sandbox, +yaml, +packcc

$ ctags --list-languages|wc
    118     121     831

$ ctags --list-languages
Ada
AnsiblePlaybook
Ant
Asciidoc
Asm
Asp
Autoconf
AutoIt
Automake
Awk
Basic
BETA
BibTeX
C
C#
C++
Clojure
CMake
Cobol
CPreProcessor
CSS
Ctags
CUDA
D
DBusIntrospect
Diff
DosBatch
DTD
DTS
Eiffel
Elixir
Elm
EmacsLisp
Erlang
Falcon
Flex
Fortran
Fypp
Gdbinit
Glade
Go
HTML
Iniconf
Inko
ITcl
Java
JavaProperties
JavaScript
JSON
Jsonnet
Kconfig
LdScript
Lisp
Lua
M4
Make
Man
Markdown
MatLab
Maven2
Moose
Myrddin
NSIS
ObjectiveC
OCaml
OldC [disabled]
OldC++ [disabled]
Pascal
Passwd
Perl
Perl6
PHP
PlistXML
Pod
PowerShell
Protobuf
PuppetManifest
Python
PythonLoggingConfig
QemuHX
QtMoc
R
RelaxNG
ReStructuredText
REXX
Robot
RpmSpec
RSpec
Ruby
Rust
Scheme
SCSS
Sh
SLang
SML
SQL
SVG
SystemdUnit
SystemTap
SystemVerilog
Tcl
TclOO
Tex
TeXBeamer
TTCN
TypeScript
Unknown [disabled]
Varlink
Vera
Verilog
VHDL
Vim
WindRes
XML
XSLT
YACC
Yaml
YumRepo
Zephir

language support

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'
    \]
    \}

Ansible

Put this into ~/.ctags

--langdef=ansible
--langmap=ansible:.yml
--regex-ansible=/^\s*- name:(.*)/\1/t,task/

And this into your .vimrc

let g:tagbar_type_ansible = {
	\ 'ctagstype' : 'ansible',
	\ 'kinds' : [
		\ 't:tasks'
	\ ],
	\ 'sort' : 0
\ }

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

if you use universal-ctags, you don't need to changes below. And Tagbar has already done. You can check https://github.com/majutsushi/tagbar/blob/master/autoload/tagbar/types/uctags.vim.

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/h/
--regex-asciidoc=/^==[ \t]+(.*)/. \1/h/
--regex-asciidoc=/^===[ \t]+(.*)/. . \1/h/
--regex-asciidoc=/^====[ \t]+(.*)/. . . \1/h/
--regex-asciidoc=/^=====[ \t]+(.*)/. . . . \1/h/
--regex-asciidoc=/^======[ \t]+(.*)/. . . . \1/h/
--regex-asciidoc=/^=======[ \t]+(.*)/. . . . \1/h/
--regex-asciidoc=/\[\[([^]]+)\]\]/\1/a/
--regex-asciidoc=/^\.([^ \t].+)/\1/t/
--regex-asciidoc=/image::([^\[]+)/\1/i/
--regex-asciidoc=/image:([^:][^\[]+)/\1/I/
--regex-asciidoc=/include::([^\[]+)/\1/n/

... and the following in vimrc:

let g:tagbar_type_asciidoc = {
    \ 'ctagstype' : 'asciidoc',
    \ 'kinds' : [
        \ 'h:table of contents',
        \ 'a:anchors:1',
        \ 't:titles:1',
        \ 'n:includes:1',
        \ 'i:images:1',
        \ 'I:inline images:1'
    \ ],
    \ 'sort' : 0
\ }

Appears as:

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

Bib

ℹ️ Native BibTeX support has been added, so no need for a custom configuration anymore. The below is kept as an example or for older setups. This only includes the kinds supported by universal-ctags 6.0.2.

~/.ctags

--langdef=bib
--langmap=bib:.bib
--regex-bib=/^@article\{([^,]*)/\1/a,article/i
--regex-bib=/^@book\{([^,]*)/\1/b,book/i
--regex-bib=/^@booklet\{([^,]*)/\1/L,booklet/i
--regex-bib=/^@conference\{([^,]*)/\1/c,conference/i
--regex-bib=/^@inbook\{([^,]*)/\1/B,inbook/i
--regex-bib=/^@incollection\{([^,]*)/\1/C,incollection/i
--regex-bib=/^@inproceedings\{([^,]*)/\1/P,inproceedings/i
--regex-bib=/^@manual\{([^,]*)/\1/m,manual/i
--regex-bib=/^@mastersthesis\{([^,]*)/\1/T,mastersthesis/i
--regex-bib=/^@misc\{([^,]*)/\1/M,misc/i
--regex-bib=/^@phdthesis\{([^,]*)/\1/t,phdthesis/i
--regex-bib=/^@proceedings\{([^,]*)/\1/p,proceedings/i
--regex-bib=/^@techreport\{([^,]*)/\1/r,techreport/i
--regex-bib=/^@unpublished\{([^,]*)/\1/u,unpublished/i

$MYVIMRC:

let g:tagbar_type_bib = {
    \ 'ctagstype' : 'bib',
    \ 'kinds'     : [
        \ 'a:Articles',
        \ 'b:Books',
        \ 'L:Booklets',
        \ 'c:Conferences',
        \ 'B:Inbook',
        \ 'C:Incollection',
        \ 'P:Inproceedings',
        \ 'm:Manuals',
        \ 'T:Masterstheses',
        \ 'M:Misc',
        \ 't:Phdtheses',
        \ 'p:Proceedings',
        \ 'r:Techreports',
        \ 'u:Unpublished',
    \ ]
\ }

Document types taken from https://en.wikipedia.org/wiki/BibTeX#Bibliographic_information_file.

BibLaTeX

The documentation of the newer biblatex package contains a different list: article, book, booklet, collection, manual, misc, online, patent, periodical, proceedings, reference, report, set, thesis, unpublished, xdata. Additionally following variants are given

  • multi-volume: mvbook, mvcollection, mvproceedings, mvreference
  • within: inbook, bookinbook, incollection, inproceedings, inreference
  • supplements: suppbook, suppcollection, suppperiodical

VIM does not have a known filetype extension to differentiate a .bib file as BibTeX separate from BibLaTeX. However ctags supports both BibTeX and BibLaTeX, so there are two definitions in tagbar (one for each). So to get VIM to recognize BibLaTeX files, it is necessary to define a custom filetype recognition in your vim configuration. This can be done by adding the following definition in your .vim/filetype.vim file.

augroup filetypedetect
    au! BufRead,BufNewFile *.biblatex setfiletype biblatex
augroup END

Clojure

Add this to your ~/.ctags:

--langdef=clojure
--langmap=clojure:.clj
--langmap=clojure:+.cljs
--langmap=clojure:+.cljc
--regex-clojure=/\(def ([^ ]+)/\1/d,def/
--regex-clojure=/\(defonce ([^ ]+)/\1/d,def/
--regex-clojure=/\(defn-? ([^ ]+)/\1/f,function/
--regex-clojure=/\(defmacro ([^ ]+)/\1/m,macro/
--regex-clojure=/\(defmulti ([^ ]+)/\1/u,multimethod/
--regex-clojure=/\(defmethod ([^ ]+ [^ ]+)/\1/u,multimethod/
--regex-clojure=/\(defstruct ([^ ]+)/\1/s,struct/
--regex-clojure=/\(deftype ([^ ]+)/\1/t,type/
--regex-clojure=/\(defprotocol ([^ ]+)/\1/p,protocol/

Add this to your ~/.vimrc:

let g:tagbar_type_clojure = {
    \ 'ctagstype' : 'clojure',
    \ 'kinds' : [
        \ 'd:defs',
        \ 'f:functions',
        \ 'm:macros',
        \ 'u:multimethods',
        \ 's:structs',
        \ 'r:records',
        \ 't:types',
        \ 'p:protocols',
    \ ]
\ }

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',
    \ ]
\ }

And put this into your ~/.ctags:

" Posix regular expressions for matching interesting items.
" Adapted from: https://gist.github.com/2901844
--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_.]*)+)[ \t]*:.*[-=]>.*$/\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/'

Crystal

Add this to your ~/.ctags:

--langdef=Crystal
--langmap=Crystal:.cr
--regex-Crystal=/^\s*def\s+([a-z_][a-zA-Z0-9_?!]*)/\1/d,def,defs/
--regex-Crystal=/^\s*(abstract|private|protected)\s+def\s+([a-z_][a-zA-Z0-9_?!]*)/\2/d,def,defs/
--regex-Crystal=/^\s*fun\s+([a-z_][a-zA-Z0-9_?!]*)/\1/f,function,functions/
--regex-Crystal=/^\s*macro\s+([a-z_][a-zA-Z0-9_?!]*)/\1/m,macro,macros/
--regex-Crystal=/^\s*class\s+([A-Z][a-zA-Z0-9_:]*)/\1/c,class,classes/
--regex-Crystal=/^\s*(abstract|private)\s+class\s+([A-Z][a-zA-Z0-9_:]*)/\1/c,class,classes/
--regex-Crystal=/^\s*module\s+([A-Z][a-zA-Z0-9_:]*)/\1/m,module,modules/
--regex-Crystal=/^\s*lib\s+([A-Z][a-zA-Z0-9_:]*)/\1/l,lib,libs/
--regex-Crystal=/^\s*struct\s+([A-Z][a-zA-Z0-9_:]*)/\1/s,struct,structs/
--regex-Crystal=/^\s*(abstract|private)\s+struct\s+([A-Z][a-zA-Z0-9_:]*)/\2/s,struct,structs/

And add this to your .vimrc:

let g:tagbar_type_crystal = {
    \ 'ctagstype': 'crystal',
    \ 'kinds' : [
        \'d:defs',
        \'f:functions',
        \'c:classes',
        \'m:modules',
        \'l:libs',
        \'s:structs'
    \]
    \}

Cucumber

Aka Gherkin. Add this to your ~/.ctags or $HOME/.ctags.d/cucumber.ctags:

--langdef=cucumber
--langmap=cucumber:.feature
--regex-cucumber=/^\s*Background: (.*)$/\1/b,background/
--regex-cucumber=/^\s*Rule: (.*)$/\1/r,rule/
--regex-cucumber=/^\s*Scenario: (.*)$/\1/s,scenario/
--regex-cucumber=/^\s*Exemple: (.*)$/\1/s,scenario/
--regex-cucumber=/^\s*Example: (.*)$/\1/s,scenario/
--regex-cucumber=/^\s*Scenario Outline: (.*)$/\1/o,scenariooutline/
--regex-cucumber=/^\s*Scenario Template: (.*)$/\1/o,scenariooutline/

And add this to your .vimrc:

let g:tagbar_type_cucumber = {
    \ 'ctagstype' : 'cucumber',
    \ 'kinds' : [
        \ 'b:background',
        \ 'r:rule',
        \ 's:scenario',
        \ 'o:scenariooutline',
    \ ],
    \ 'sort' : 0
    \ }

CSS

CSS support requires the use of Universal Ctags, a more up-to-date and maintained ctags, and the following vimrc configuration:

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

D

Proper D support is provided by the Dscanner project. Note that the version of Dscanner must be 0.2.0-beta2+. Add the following to your .vimrc:

let g:tagbar_type_d = {
            \ 'ctagstype' : 'd',
            \ 'kinds'     : [
            \ 'c:classes:1:1',
            \ 'f:functions:1:1',
            \ 'T:template:1:1',
            \ 'g:enums:1:1',
            \ 'e:enumerators:0:0',
            \ 'u:unions:1:1',
            \ 's:structs:1:1',
            \ 'v:variables:1:0',
            \ 'i:interfaces:1:1',
            \ 'm:members',
            \ 'a:alias'
            \ ],
            \'sro': '.',
            \ 'kind2scope' : {
            \ 'c' : 'class',
            \ 'g' : 'enum',
            \ 's' : 'struct',
            \ 'u' : 'union',
            \ 'T' : 'template'
            \},
            \ 'scope2kind' : {
            \ 'enum'      : 'g',
            \ 'class'     : 'c',
            \ 'struct'    : 's',
            \ 'union'     : 'u',
            \ 'template'  : 'T'
            \ },
            \ 'ctagsbin' : 'dscanner',
            \ 'ctagsargs' : ['--ctags']
            \ }

Alternatively, if you use the D patch for exuberant-ctags add the following to your .vimrc:

let g:tagbar_type_d = {
    \ 'ctagstype' : 'd',
    \ 'kinds'     : [
        \ 'c:classes:0:1',
        \ 'f:functions',
        \ 'g:enums',
        \ 'u:unions',
        \ 's:structs',
        \ 'm:members'
    \ ],
    \'sro': '.',
    \ 'kind2scope' : {
        \ 'c' : 'class',
        \ 'g' : 'enum',
        \ 's' : 'struct',
        \ 'u' : 'union'
    \},
    \ 'scope2kind' : {
        \ 'enum'      : 'g',
        \ 'class'     : 'c',
        \ 'struct'    : 's',
        \ 'union'     : 'u'
    \ }
\ }

Elixir

Elixir is best supported by Universal Ctags, a more up-to-date and maintained ctags, and the following vimrc configuration:

let g:tagbar_type_elixir = {
    \ 'ctagstype' : 'elixir',
    \ 'kinds' : [
        \ 'p:protocols',
        \ 'm:modules',
        \ 'e:exceptions',
        \ 'y:types',
        \ 'd:delegates',
        \ 'f:functions',
        \ 'c:callbacks',
        \ 'a:macros',
        \ 't:tests',
        \ 'i:implementations',
        \ 'o:operators',
        \ 'r:records'
    \ ],
    \ 'sro' : '.',
    \ 'kind2scope' : {
        \ 'p' : 'protocol',
        \ 'm' : 'module'
    \ },
    \ 'scope2kind' : {
        \ 'protocol' : 'p',
        \ 'module' : 'm'
    \ },
    \ 'sort' : 0
\ }

Elm

Based on the vimwiki script, here is a python script for elm tags.

This script creates tags for:

  • imports, indicating their alias and exposed functions/types as a signature
  • types
  • functions with signature

Enable in your .vimrc with:

let g:tagbar_type_elm = {
          \   'ctagstype':'elm'
          \ , 'kinds':['h:header', 'i:import', 't:type', 'f:function', 'e:exposing']
          \ , 'sro':'&&&'
          \ , 'kind2scope':{ 'h':'header', 'i':'import'}
          \ , 'sort':0
          \ , 'ctagsbin':'/path/to/elmtags.py'
          \ , 'ctagsargs': ''
          \ }

Don't forget to edit the ctagsbin parameter to point to the script. More information here.

Fountain

Add this to ~/.ctags:

--langdef=fountain
--langmap=fountain:.fountain
--regex-fountain=/(((INT|E(S|X)T|INT\.?\/EXT|I\.?\/E)\.? .*)|ESTABLISHING|\.[A-Z]+[A-Z ]*)/\1/h,heading/
--regex-fountain=/^#( ?)([^#]+)/\2/s,section/

And add this to ~/.vimrc:

let g:tagbar_type_fountain = {
    \ 'ctagstype': 'fountain',
    \ 'kinds': [
      \ 'h:headings',
      \ 's:sections',
    \ ],
    \ 'sort': 0,
    \}

GAP

Add the following to your vimrc:

let g:tagbar_type_gap = {
    \ 'ctagstype' : 'gap',
    \ 'kinds' : [
        \ 'f:function',
        \ 'v:value',
        \ 'm:method',
        \ 't:truemethod',
        \ 'd:documentation',
        \ 'c:category',
        \ 'r:representation',
        \ 'i:infoclass',
        \ 'a:attribute',
        \ 'p:property',
        \ 's:synonym',
        \ 'g:gfunction',
        \ 'o:operation'
    \ ]
\ }

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'
    \]
\}

Gradle

Gradle support is provided by vim-gradle plugin. No configuration is necessary, just installation of plugin itself.

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]*package[ \t]+([a-zA-Z0-9.-_]+)/\1/p,package/
--regex-groovy=/^[ \t]*(private|public)?[ \t]*(abstract|final|static)?[ \t]*class[ \t]+([A-Za-z0-9_]+)/\3/c,class/
--regex-groovy=/^[ \t]*(private|public)?[ \t]*interface[ \t]+([A-Za-z0-9_]+)/\2/i,interface/
--regex-groovy=/^[ \t]*(private|public)?[ \t]*trait[ \t]+([A-Za-z0-9_]+)/\2/t,trait/
--regex-groovy=/^[ \t]*(private|public)?[ \t]*enum[ \t]+([A-Za-z0-9_]+)/\2/e,enum/
--regex-groovy=/^[ \t]*[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/~\3/m,package method/
--regex-groovy=/^[ \t]*public[ \t]+[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/+\3/m,public method/
--regex-groovy=/^[ \t]*protected[ \t]+[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/#\3/m,protected method/
--regex-groovy=/^[ \t]*private[ \t]+[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/-\3/m,private method/
--regex-groovy=/^[ \t]*[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][A-Za-z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/~\2/f,property/
--regex-groovy=/^[ \t]*public[ \t]+[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/+\2/f,public field/
--regex-groovy=/^[ \t]*protected[ \t]+[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/#\2/f,protected field/
--regex-groovy=/^[ \t]*private[ \t]+[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/-\2/f,private field/

And then add this to your ~/.vimrc:

let g:tagbar_type_groovy = {
    \ 'ctagstype' : 'groovy',
    \ 'kinds'     : [
        \ 'p:package:1',
        \ 'c:classes',
        \ 'i:interfaces',
        \ 't:traits',
        \ 'e:enums',
        \ 'm:methods',
        \ 'f:fields:1'
    \ ]
\ }

Alternatively, you can use vim-gradle plugin, which provides Groovy support for Ctags and Tagbar with no need to configure your ~/.vimrc and ~/.ctags files.

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 an empty tagbar) and has not been properly updated for a while.

A more reliable alternative is hasktags. Add the following to your .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',
        \  'i:instance:0:1',
        \  'o:others:0:1'
    \ ],
    \ 'sro'        : '.',
    \ 'kind2scope' : {
        \ 'm' : 'module',
        \ 'c' : 'class',
        \ 'd' : 'data',
        \ 't' : 'type',
        \ 'i' : 'instance'
    \ },
    \ 'scope2kind' : {
        \ 'module'   : 'm',
        \ 'class'    : 'c',
        \ 'data'     : 'd',
        \ 'type'     : 't',
        \ 'instance' : 'i'
    \ }
\ }

IDL (Interactive Data Language)

IDL seems to ignore indentation, hence the optional white space at the start of a line. Add the following to your ~/.ctags:

--langdef=IDL
--langmap=IDL:.pro
--regex-IDL=/^[ \t]*function[ \t]+([a-zA-Z0-9_:]+)/\1/f,function/i
--regex-IDL=/^[ \t]*pro[ \t]+([a-zA-Z0-9_:]+)/\1/p,procedure/i
--regex-IDL=/^[ \t]*common[ \t]+([a-zA-Z0-9_:]+)/\1/c,common/i

... and the following in vimrc:

let g:tagbar_type_idlang = {
    \ 'ctagstype' : 'IDL',
    \ 'kinds' : [
        \ 'p:Procedures',
        \ 'f:Functions',
        \ 'c:Common Blocks'
        \ ]
    \ }

Jack

Add the following to your $HOME/.ctags.d/jack.ctags:

--langdef=Jack
--langmap=Jack:.jack

--kinddef-Jack=C,Class,class definitions
--kinddef-Jack=s,static,static declarations
--kinddef-Jack=d,field,field declarations
--kinddef-Jack=c,constructor,constructor definitions
--kinddef-Jack=m,method,method definitions
--kinddef-Jack=f,function,function definitions

--regex-Jack=/^[[:blank:]]*\/\///{exclusive}
--regex-Jack=/^class +(\w+) +\{$/\1/C/{scope=push}{exclusive}
--regex-Jack=/^\}//{scope=pop}{exclusive}

--regex-Jack=/^\W+static (\w+) (\w+);/\1 \2/s/{scope=ref}
--regex-Jack=/^\W+field (\w+) (\w+);/\1 \2/d/{scope=ref}
--regex-Jack=/^\W+constructor \w+ (\w+)\(([^)]*)\)/\1(\2)/c/{scope=ref}
--regex-Jack=/^\W+method (\w+) (\w+)\(([^)]*)\)/\1 \2(\3)/m/{scope=ref}
--regex-Jack=/^\W+function (\w+) (\w+)\(([^)]*)\)/\1 \2(\3)/f/{scope=ref}

... and the following in vimrc:

let g:tagbar_type_jack = {
    \ 'ctagstype': 'jack',
    \ 'kinds' : [
        \'C:Class',
        \'s:static',
        \'d:field',
        \'c:constructor',
        \'m:method',
        \'f:function',
    \ ],
    \ 'sro' : '.',
    \ 'kind2scope' : {
        \ 'C' : 'Class',
    \ },
\ }

JavaScript

There are two valid options to generate an Exuberant Ctags file.

jsctags (depends on Tern) ** Recommended **

It works as expected and thanks to Tern, it recognizes the return value of functions and variable types, which comes extremely handy in a loosely-typed language. jsctags, by default, outputs a JSON file, but with the -f flag, the resulting file is ctags-compatible.

  • Install tern_for_vim using the pathogen, neobundle, vundle, etc.
  • Navigate to the tern folder and execute in the shell, the following command: npm install (if it doesn't work, try prepending sudo).
  • Follow the install instruction from ramitos/jsctags.
Ctags Regex

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/
Possibly better Javascript RegExs

https://github.com/winstonwolff/ctags-javascript-coffeescript

RomainL's Javascript RegExs

Copy this to your ~/.ctags : https://raw.githubusercontent.com/romainl/ctags-patterns-for-javascript/master/.ctags

Add this to your vimrc :

let g:tagbar_type_javascript = {
      \ 'ctagstype': 'javascript',
      \ 'kinds': [
      \ 'A:arrays',
      \ 'P:properties',
      \ 'T:tags',
      \ 'O:objects',
      \ 'G:generator functions',
      \ 'F:functions',
      \ 'C:constructors/classes',
      \ 'M:methods',
      \ 'V:variables',
      \ 'I:imports',
      \ 'E:exports',
      \ 'S:styled components'
      \ ]}

JSON

Add the following to vimrc:

let g:tagbar_type_json = {
    \ 'ctagstype' : 'json',
    \ 'kinds' : [
      \ 'o:objects',
      \ 'a:arrays',
      \ 'n:numbers',
      \ 's:strings',
      \ 'b:booleans',
      \ 'z:nulls'
    \ ],
  \ 'sro' : '.',
    \ 'scope2kind': {
    \ 'object': 'o',
      \ 'array': 'a',
      \ 'number': 'n',
      \ 'string': 's',
      \ 'boolean': 'b',
      \ 'null': 'z'
    \ },
    \ 'kind2scope': {
    \ 'o': 'object',
      \ 'a': 'array',
      \ 'n': 'number',
      \ 's': 'string',
      \ 'b': 'boolean',
      \ 'z': 'null'
    \ },
    \ 'sort' : 0
    \ }

Jsonnet

Add the following to your ~/.ctags:

--langdef=Jsonnet
--langmap=Jsonnet:.jsonnet
--langmap=Jsonnet:.libsonnet
--regex-jsonnet=/^[ \t]*local ([A-Za-z0-9_]+)/\1/v,variable/
--regex-jsonnet=/^[ \t]*([A-Za-z0-9_]+):::?/\1/m,member/
--regex-jsonnet=/^[ \t]*([A-Za-z0-9_]+)\([^)]*\):::?/\1/f,function/

... and the following in vimrc:

let g:tagbar_type_jsonnet = {
    \ 'ctagstype' : 'jsonnet',
    \ 'kinds'     : [
        \ 'f:function', 'm:member', 'v:variable'
    \ ],
\ }

Julia

Add the following to your ~/.ctags:

--langdef=julia
--langmap=julia:.jl
--regex-julia=/^[ \t]*(@with_kw[ \t]+)?(abstract type|primitive type|struct|mutable struct|typealias)[ \t]+([^ \t({[]+).*$/\3/t,type/
--regex-julia=/^[ \t]*(macro)[ \t]+([^ \t({[]+).*$/\2/m,macro/
--regex-julia=/^[ \t]*(@inline[ \t]+|@noinline[ \t]+)?(function)[ \t]+([^ \t({[]+)[^(]*\([ \t]*([^ \t;,=)({]+).*$/\3 (\4, …)/f,function/
--regex-julia=/^[ \t]*(@inline[ \t]+|@noinline[ \t]+)?(function)[ \t]+([^ \t({[]+)[^(]*(\([ \t]*\).*|\([ \t]*)$/\3/f,function/
--regex-julia=/^[ \t]*(@inline[ \t]+|@noinline[ \t]+)?(([^@#$ \t({[]+)|\(([^@#$ \t({[]+)\)|\((\$)\))[ \t]*(\{.*\})?[ \t]*\([ \t]*\)[ \t]*=([^=].*$|$)/\3\4\5/f,function/
--regex-julia=/^[ \t]*(@inline[ \t]+|@noinline[ \t]+)?(([^@#$ \t({[]+)|\(([^@#$ \t({[]+)\)|\((\$)\))[ \t]*(\{.*\})?[ \t]*\([ \t]*([^ \t;,=)({]+).*\)[ \t]*=([^=].*$|$)/\3\4\5 (\7, …)/f,function/
--regex-julia=/^(const)[ \t]+([^ \t({[]+).*[ ]*=.*$/\2/c,const/

... and the following in vimrc:

let g:tagbar_type_julia = {
    \ 'ctagstype' : 'julia',
    \ 'kinds'     : [
        \ 't:struct', 'f:function', 'm:macro', 'c:const']
    \ }

kotlin

Add these to your ctags(if you use universal-ctags add it to ~/.ctags.d/kotlin.ctags):

# Regex for Kotlin
--langdef=kotlin
--langmap=kotlin:+.kt
--langmap=kotlin:+.kts
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|inner|open)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*class[[:space:]]+([[:alnum:]_:]+)/\4/c,classes/
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*object[[:space:]]+([[:alnum:]_:]+)/\4/o,objects/
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|open)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*data class[[:space:]]+([[:alnum:]_:]+)/\6/d,data classes/
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*interface[[:space:]]+([[:alnum:]_:]+)/\4/i,interfaces/
--regex-kotlin=/^[[:space:]]*type[[:space:]]+([[:alnum:]_:]+)/\1/T,types/
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|override|open|private[^ ]*(\[[a-z]*\])*|protected)[[:space:]]*)*fun[[:space:]]+([[:alnum:]_:]+)/\4/m,methods/
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[[:space:]]*)*(const[[:space:]])*val[[:space:]]+([[:alnum:]_]+)/\4/C,constants/
--regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[[:space:]]*)*(lateinit[[:space:]]*)*var[[:space:]]+([[:alnum:]_]+)/\4/v,variables/
--regex-kotlin=/^[[:space:]]*package[[:space:]]+([[:alnum:]_.:]+)/\1/p,packages/
--regex-kotlin=/^[[:space:]]*import[[:space:]]+([[:alnum:]_.:]+)/\1/I,imports/

add these to ~/.vimrc

let g:tagbar_type_kotlin = {
    \ 'ctagstype' : 'kotlin',
    \ 'ctagsbin' : 'ctags-universal',
    \ 'kinds'     : [
        \ 'c:classes:0:1',
        \ 'f:functions',
        \ 'g:enums',
        \ 'u:unions',
        \ 's:structs',
        \ 'm:members'
    \ ],
    \'sro': '.',
    \ 'kind2scope' : {
        \ 'c' : 'class',
        \ 'g' : 'enum',
        \ 's' : 'struct',
        \ 'u' : 'union'
    \},
    \ 'scope2kind' : {
        \ 'enum'      : 'g',
        \ 'class'     : 'c',
        \ 'struct'    : 's',
        \ 'union'     : 'u'
    \ }
\ }

Makefile (targets)

To add support for jumping to Makefile targets, add the following to your ~/.ctags:

--regex-make=/^([^# \t:]*):/\1/t,target/

... and the following in vimrc:

let g:tagbar_type_make = {
            \ 'kinds':[
                \ 'm:macros',
                \ 't:targets'
            \ ]
\}

Markdown

Please use Universal Ctags which has support for Markdown built in. To display tags ordered by heading, you can use the following local definition in your .vimrc to override the default markdown language definition for tagbar. This will rename the tag kinds to be more accurate for what ctags outputs, and also provide the scope2kind and kind2scope definitions needed to get the proper scope hierarchy.

let g:tagbar_type_markdown = {
  \ 'ctagstype'	: 'markdown',
  \ 'kinds'		: [
    \ 'c:chapter:0:1',
    \ 's:section:0:1',
    \ 'S:subsection:0:1',
    \ 't:subsubsection:0:1',
    \ 'T:l4subsection:0:1',
    \ 'u:l5subsection:0:1',
  \ ],
  \ 'sro'			: '""',
  \ 'kind2scope'	: {
    \ 'c' : 'chapter',
    \ 's' : 'section',
    \ 'S' : 'subsection',
    \ 't' : 'subsubsection',
    \ 'T' : 'l4subsection',
  \ },
  \ 'scope2kind'	: {
    \ 'chapter' : 'c',
    \ 'section' : 's',
    \ 'subsection' : 'S',
    \ 'subsubsection' : 't',
    \ 'l4subsection' : 'T',
  \ },
\ }

For older exuberant-ctags you can add 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,
\ }

Alternatively, you can use tagbar-markdown to show markdown section title. You can also use the :MDAgenda to generate the markdown agenda and put into current line.

Alternatively, you can use mdctags to generate tags for markdown file.

let g:tagbar_type_markdown = {
            \ 'ctagsbin'  : 'mdctags',
            \ 'ctagsargs' : '',
            \ 'kinds'     : [
            \     'a:h1:0:0',
            \     'b:h2:0:0',
            \     'c:h3:0:0',
            \     'd:h4:0:0',
            \     'e:h5:0:0',
            \     'f:h6:0:0',
            \ ],
            \ 'sro'        : '::',
            \ 'kind2scope' : {
            \     'a' : 'h1',
            \     'b' : 'h2',
            \     'c' : 'h3',
            \     'd' : 'h4',
            \     'e' : 'h5',
            \     'f' : 'h6',
            \ },
            \ 'scope2kind' : {
            \     'h1' : 'a',
            \     'h2' : 'b',
            \     'h3' : 'c',
            \     'h4' : 'd',
            \     'h5' : 'e',
            \     'h6' : 'f',
            \}
            \}

MediaWiki

Put this into ~/.ctags

--langdef=MediaWiki
--langmap=MediaWiki:.mw
--regex-MediaWiki=/^==[ \t]+(.*)[ \t]+==/\1/c,chapters/
--regex-MediaWiki=/^===[ \t]+(.*)[ \t]+===/\1/s,sections/
--regex-MediaWiki=/^====[ \t]+(.*)[ \t]+====/\1/u,subsections/
--regex-MediaWiki=/^=====[ \t]+(.*)[ \t]+=====/\1/b,subsubsections/

And this into your .vimrc

 let g:tagbar_type_mediawiki = {
    \ 'ctagstype' : 'mediawiki',
    \ 'kinds' : [
        \'h:chapters',
        \'s:sections',
        \'u:subsections',
        \'b:subsubsections',
    \]
    \}

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=/^[ \t]*private function[ \t]+([_a-zA-Z][_a-zA-Z0-9]*)/\1/r,private function/
--regex-nasl=/^[ \t]*public function[ \t]+([_a-zA-Z][_a-zA-Z0-9]*)/\1/u,public function/
--regex-nasl=/^(var)? ?([_a-zA-Z][_a-zA-Z0-9]*)[ \t]*=/\1/v,variable/
--regex-nasl=/^[ \t]*global_var ([_a-zA-Z][_a-zA-Z0-9]*)/\1/g,global/
--regex-nasl=/^namespace ([_a-zA-Z][_a-zA-Z0-9]*)/\1/n,namespace/
--regex-nasl=/^[ \t]*object ([_a-zA-Z][_a-zA-Z0-9]*)/\1/o,object/

... and the following in vimrc:

let g:tagbar_type_nasl = {
    \ 'ctagstype' : 'nasl',
    \ 'kinds'     : [
      \ 'f:function',
      \ 'u:public function',
      \ 'r:private function',
      \ 'v:variables',
      \ 'n:namespace',
      \ 'g:globals',
    \ ]
\ }

Nim

Add this to your ~/.ctags:

--langdef=nim
--langmap=nim:.nim
--regex-nim=/(\w+)\*?\s*=\s*object/\1/c,class/
--regex-nim=/(\w+)\*?\s*=\s*enum/\1/e,enum/
--regex-nim=/(\w+)\*?\s*=\s*tuple/\1/t,tuple/
--regex-nim=/(\w+)\*?\s*=\s*range/\1/r,subrange/
--regex-nim=/(\w+)\*?\s*=\s*proc/\1/P,proctype/
--regex-nim=/proc\s+(\w+)/\1/p,procedure/
--regex-nim=/method\s+(\w+)/\1/m,method/
--regex-nim=/proc\s+`([^`]+)`/\1/o,operator/
--regex-nim=/template\s+(\w+)/\1/T,template/
--regex-nim=/macro\s+(\w+)/\1/M,macro/

And this to your .vimrc:

let g:tagbar_type_nim = {
    \ 'ctagstype': 'nim',
    \ 'kinds' : [
        \'c:classes',
        \'e:enums',
        \'t:tuples',
        \'r:subranges',
        \'P:proctypes',
        \'p:procedures',
        \'m:methods',
        \'o:operators',
        \'T:templates',
        \'M:macros'
    \ ]
\}

obj-c

" add a definition for Objective-C to tagbar
let g:tagbar_type_objc = {
    \ 'ctagstype' : 'ObjectiveC',
    \ 'kinds'     : [
        \ 'i:interface',
        \ 'I:implementation',
        \ 'p:Protocol',
        \ 'm:Object_method',
        \ 'c:Class_method',
        \ 'v:Global_variable',
        \ 'F:Object field',
        \ 'f:function',
        \ 'p:property',
        \ 't:type_alias',
        \ 's:type_structure',
        \ 'e:enumeration',
        \ 'M:preprocessor_macro',
    \ ],
    \ 'sro'        : ' ',
    \ 'kind2scope' : {
        \ 'i' : 'interface',
        \ 'I' : 'implementation',
        \ 'p' : 'Protocol',
        \ 's' : 'type_structure',
        \ 'e' : 'enumeration'
    \ },
    \ 'scope2kind' : {
        \ 'interface'      : 'i',
        \ 'implementation' : 'I',
        \ 'Protocol'       : 'p',
        \ 'type_structure' : 's',
        \ 'enumeration'    : 'e'
    \ }
\ }

The above definition requires a build of Exuberant Ctags trunk. The last official ctags release is now very old, and Objective C support landed after that release. Recent Debian-based Linux distros package an up-to-date version directly. Users of OS X or Linux distros without a current ctags can use Homebrew or Linuxbrew as needed to install an up-to-date version with Objective C support:

brew install ctags --HEAD

To check whether your ctags supports Objective C, run the following command:

ctags --list-kinds=ObjectiveC

Perl

To add support for Perl, please follow the instructions in this project and elaborate on it. Extended Rules to support Modern Perl in Exuberant Ctags See also Perl::Tags, "Vim and custom tagging"

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.

PowerShell

Added to ~/ctags.cnf (On Win7):

--langdef=powershell
--langmap=powershell:.ps1.psm1
--regex-powershell=/^[Ff]unction[\t ]*([a-zA-Z0-9_-]+)/\1/f,function/
--regex-powershell=/^[Ff]ilter[\t ]*([a-zA-Z0-9_-]+)/\1/i,filter/
--regex-powershell=/^[sS]et-[Aa]lias[\t ]*([a-zA-Z0-9_-]+)/\1/a,alias/

Add this to _vimrc:

let g:tagbar_type_ps1 = {
    \ 'ctagstype' : 'powershell',
    \ 'kinds'     : [
        \ 'f:function',
        \ 'i:filter',
        \ 'a:alias'
    \ ]
\ }

If you have universal-ctags, ctags will generate PowerShell tags. In this case, setting ctags.cnf is not required.

See the following example.

let g:tagbar_type_ps1 = {
    \ 'ctagstype': 'powershell',
    \ 'kinds': [
        \ 'e:enum',
        \ 'c:class',
        \ 'f:function',
        \ 'i:filter',
        \ 'v:variable'
    \ ]
\ }

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',
    \ ]
\ }

By the way,ctags-universal has support R already, and if you have already install ctags-universal, you can write:

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

RISC-V ASM

If you installed henry-hsieh/riscv-asm-vim for syntax coloring of RISC-V assembly, add the following to you .vimrc:

let g:tagbar_type_riscv_asm = {
    \ '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'
    \ ]
\}

Rmd

Based on the vimwiki script, here is a python script for Rmarkdown tags.

This script creates tags for:

  • Rmarkdown headers, hierarchicaly, indicating the CSS class as signature
  • code chunks, organized inside their respective header, indicating the chunk options as signature
  • functions
  • variables

Enable in your .vimrc with :

let g:tagbar_type_rmd = {
          \   'ctagstype':'rmd'
          \ , 'kinds':['h:header', 'c:chunk', 'f:function', 'v:variable']
          \ , 'sro':'&&&'
          \ , 'kind2scope':{'h':'header', 'c':'chunk'}
          \ , 'sort':0
          \ , 'ctagsbin':'/path/to/rmdtags.py'
          \ , 'ctagsargs': ''
          \ }

Don't forget to edit the ctagsbin parameter to point to the script. More information here.

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,
\ }

Universal ctags just works fine too.

let g:tagbar_type_rst = {
            \ 'ctagstype' : 'ReStructuredText',
            \ 'kinds' : [
            \     'c:chapter',
            \     's:article',
            \     'S:section',
            \ ],
            \ "sort" : 0
            \ }

Robot

Robot support requires the use of Universal Ctags, which is a up-to-date and maintained version of Exuberant Ctags with support for more languages. Add following configuration in your .vimrc:

let g:tagbar_type_robot= {
            \ 'ctagstype' : 'robot',
            \ 'kinds'     : [
            \'t:testcases',
            \'k:keywords',
            \'v:variables'
  \]
\}

Ruby

Using Universal 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'
    \ ]
\ }

Using ripper-tags provides faster and more accurate support for Ruby. A working configuration of tagbar for this is the following. The kinds order follows the one as recommended in the ruby style guide for classes (apart from the aliases). If you want a different order, you will have to change that.

if executable('ripper-tags')
  let g:tagbar_type_ruby = {
      \ 'kinds'      : ['m:modules',
                      \ 'c:classes',
                      \ 'C:constants',
                      \ 'F:singleton methods',
                      \ 'f:methods',
                      \ 'a:aliases'],
      \ 'kind2scope' : { 'c' : 'class',
                       \ 'm' : 'class' },
      \ 'scope2kind' : { 'class' : 'c' },
      \ 'ctagsbin'   : 'ripper-tags',
      \ 'ctagsargs'  : ['-f', '-']
      \ }
endif

Rust

Put this into ~/.ctags

--langdef=Rust
--langmap=Rust:.rs
--regex-Rust=/^[ \t]*(#\[[^\]]\][ \t]*)*(pub[ \t]+)?(async[ \t]+)?(extern[ \t]+)?("[^"]+"[ \t]+)?(unsafe[ \t]+)?fn[ \t]+([a-zA-Z0-9_]+)/\7/f,functions,function definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?type[ \t]+([a-zA-Z0-9_]+)/\2/T,types,type definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?enum[ \t]+([a-zA-Z0-9_]+)/\2/g,enum,enumeration names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?struct[ \t]+([a-zA-Z0-9_]+)/\2/s,structs,structure names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?mod[ \t]+([a-zA-Z0-9_]+)/\2/m,modules,module names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?(static|const)[ \t]+(mut[ \t]+)?([a-zA-Z0-9_]+)/\4/c,consts,static constants/
--regex-Rust=/^[ \t]*(pub[ \t]+)?(unsafe[ \t]+)?trait[ \t]+([a-zA-Z0-9_]+)/\3/t,traits,traits/
--regex-Rust=/^[ \t]*(pub[ \t]+)?(unsafe[ \t]+)?impl([ \t\n]*<[^>]*>)?[ \t]+(([a-zA-Z0-9_:]+)[ \t]*(<[^>]*>)?[ \t]+(for)[ \t]+)?([a-zA-Z0-9_]+)/\5 \7 \8/i,impls,trait implementations/
--regex-Rust=/^[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/d,macros,macro definitions/

And this into your .vimrc

 let g:tagbar_type_rust = {
    \ 'ctagstype' : 'rust',
    \ 'kinds' : [
        \'T:types,type definitions',
        \'f:functions,function definitions',
        \'g:enum,enumeration names',
        \'s:structure names',
        \'m:modules,module names',
        \'c:consts,static constants',
        \'t:traits',
        \'i:impls,trait implementations',
    \]
    \}

universal-ctags variant

universal-ctags has native support for Rust, including nested items, which is much nicer than the above. Install universal-ctags and use the following in your .vimrc.

let g:rust_use_custom_ctags_defs = 1  " if using rust.vim
let g:tagbar_type_rust = {
  \ 'ctagsbin' : '/path/to/your/universal/ctags',
  \ 'ctagstype' : 'rust',
  \ 'kinds' : [
      \ 'n:modules',
      \ 's:structures:1',
      \ 'i:interfaces',
      \ 'c:implementations',
      \ 'f:functions:1',
      \ 'g:enumerations:1',
      \ 't:type aliases:1:0',
      \ 'C:constants:1:0',
      \ 'M:macros:1',
      \ 'm:fields:1:0',
      \ 'e:enum variants:1:0',
      \ 'P:methods:1',
  \ ],
  \ 'sro': '::',
  \ 'kind2scope' : {
      \ 'n': 'module',
      \ 's': 'struct',
      \ 'i': 'interface',
      \ 'c': 'implementation',
      \ 'f': 'function',
      \ 'g': 'enum',
      \ 't': 'typedef',
      \ 'v': 'variable',
      \ 'M': 'macro',
      \ 'm': 'field',
      \ 'e': 'enumerator',
      \ 'P': 'method',
  \ },
\ }

Scala

You may like to use vim-scala, which automatically configures Tagbar and ctags generation with the settings below.

If you don't wish to use vim-scala, however, you can set up the following configuration yourself. Add the ctags language definition to ~/.ctags (hat tip to Leonard Ehrenfried, though this has been enhanced since his post):

--langdef=scala
--langmap=scala:.scala

--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*class[ \t]+([a-zA-Z0-9_]+)/\4/c,classes/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*object[ \t]+([a-zA-Z0-9_]+)/\4/o,objects/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*((abstract|final|sealed|implicit|lazy)[ \t ]*)*case class[ \t ]+([a-zA-Z0-9_]+)/\6/C,case classes/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*case object[ \t]+([a-zA-Z0-9_]+)/\4/O,case objects/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*trait[ \t]+([a-zA-Z0-9_]+)/\4/t,traits/
--regex-scala=/^[ \t]*type[ \t]+([a-zA-Z0-9_]+)/\1/T,types/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*(\[[a-z]*\])*|protected)[ \t]*)*def[ \t]+([a-zA-Z0-9_]+)/\4/m,methods/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[ \t]*)*val[ \t]+([a-zA-Z0-9_]+)/\3/V,values/
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[ \t]*)*var[ \t]+([a-zA-Z0-9_]+)/\3/v,variables/
--regex-scala=/^[ \t]*package[ \t]+([a-zA-Z0-9_.]+)/\1/p,packages/

...and add Tagbar settings to your ~/.vimrc:

let g:tagbar_type_scala = {
    \ 'ctagstype' : 'scala',
    \ 'sro'       : '.',
    \ 'kinds'     : [
      \ 'p:packages',
      \ 'T:types:1',
      \ 't:traits',
      \ 'o:objects',
      \ 'O:case objects',
      \ 'c:classes',
      \ 'C:case classes',
      \ 'm:methods',
      \ 'V:values:1',
      \ 'v:variables:1'
    \ ]
\ }

systemverilog

~/.ctags

--langdef=systemverilog
--langmap=systemverilog:.v.vg.sv.svh.tv.vinc.f
--regex-systemverilog=/^\s*(\b(static|local|virtual|protected)\b)*\s*\bclass\b\s*(\b\w+\b)/\3/c,class/
--regex-systemverilog=/^\s*(\b(static|local|virtual|protected)\b)*\s*\btask\b\s*(\b(static|automatic)\b)?\s*(\w+::)?\s*(\b\w+\b)/\6/t,task/
--regex-systemverilog=/^\s*(\b(static|local|virtual|protected)\b)*\s*\bfunction\b\s*(\b(\w+)\b)?\s*(\w+::)?\s*(\b\w+\b)/\6/f,function/
--regex-systemverilog=/^\s*\bmodule\b\s*(\b\w+\b)/\1/m,module/
--regex-systemverilog=/^\s*\bprogram\b\s*(\b\w+\b)/\1/p,program/
--regex-systemverilog=/^\s*\binterface\b\s*(\b\w+\b)/\1/i,interface/
--regex-systemverilog=/^\s*\btypedef\b\s+.*\s+(\b\w+\b)\s*;/\1/e,typedef/
--regex-systemverilog=/^\s*define\b\s*(\w+)/\1/d,define/ --regex-systemverilog=/}\s*(\b\w+\b)\s*;/\1/e,typedef/
--regex-systemverilog=/^\s*(\b(static|local|private|rand)\b)*\s*(\b(shortint|int|longint)\b)\s*(\bunsigned\b)?(\s*\[.+\])*\s*(\b\w+\b)/\7/v,variable/
--regex-systemverilog=/^\s*(\b(static|local|private|rand)\b)*\s*(\b(byte|bit|logic|reg|integer|time)\b)(\s*\[.+\])*\s*(\b\w+\b)/\6/v,variable/
--regex-systemverilog=/^\s*(\b(static|local|private)\b)*\s*(\b(real|shortreal|chandle|string|event)\b)(\s*\[.+\])*\s*(\b\w+\b)/\6/v,variable/
--regex-systemverilog=/(\b(input|output|inout)\b)\s*(\[.+\])*\s*(\b(wire|reg|logic)\b)\s*(\[.+\])*\s*(#(\(.+\)|\S+)\))?\s*(\b\w+\b)/\9/v,variable/
--regex-systemverilog=/(\b(parameter|localparam)\b).+(\b\w+\b)\s*=/\3/a,parameter/
--systemverilog-kinds=+ctfmpied

~/.vimrc

let g:tagbar_type_systemverilog= {
    \ 'ctagstype' : 'systemverilog',
    \ 'kinds'     : [
        \'c:classes',
        \'t:tasks',
        \'f:functions',
        \'m:modules',
        \'i:interfaces',
        \'v:variables',
        \'d:defines',
        \'e:typedefs',
        \'a:parameters'
  \]
\}

Note: ~/.ctags is referred from https://verificationacademy.com/forums/systemverilog/ctags-systemverilog

If you can use universal-ctags, it has a better parser for SystemVerilog. You can even have a hierarchy in your tags with the following configuration in your .vimrc:

let g:tagbar_type_systemverilog = {
    \ 'ctagstype': 'systemverilog',
    \ 'kinds' : [
         \'A:assertions',
         \'C:classes',
         \'E:enumerators',
         \'I:interfaces',
         \'K:packages',
         \'M:modports',
         \'P:programs',
         \'Q:prototypes',
         \'R:properties',
         \'S:structs and unions',
         \'T:type declarations',
         \'V:covergroups',
         \'b:blocks',
         \'c:constants',
         \'e:events',
         \'f:functions',
         \'m:modules',
         \'n:net data types',
         \'p:ports',
         \'r:register data types',
         \'t:tasks',
     \],
     \ 'sro': '.',
     \ 'kind2scope' : {
        \ 'K' : 'package',
        \ 'C' : 'class',
        \ 'm' : 'module',
        \ 'P' : 'program',
        \ 'I' : 'interface',
        \ 'M' : 'modport',
        \ 'f' : 'function',
        \ 't' : 'task',
     \},
     \ 'scope2kind' : {
        \ 'package'   : 'K',
        \ 'class'     : 'C',
        \ 'module'    : 'm',
        \ 'program'   : 'P',
        \ 'interface' : 'I',
        \ 'modport'   : 'M',
        \ 'function'  : 'f',
        \ 'task'      : 't',
     \ },
     \}

Terraform (HCL)

  1. Add the following to your ctags configuration:
--langdef=tf
--langmap=tf:.tf.tfvars
--regex-tf=/^[[:space:]]*resource[[:space:]]*"([^"]*)"[[:space:]]*"([^"]*)"/\2/r,Resource/
--regex-tf=/^[[:space:]]*data[[:space:]]*"([^"]*)"[[:space:]]*"([^"]*)"/\2/d,Data/
--regex-tf=/^[[:space:]]*variable[[:space:]]*"([^"]*)"/\1/v,Variable/
--regex-tf=/^[[:space:]]*provider[[:space:]]*"([^"]*)"/\1/p,Provider/
--regex-tf=/^[[:space:]]*module[[:space:]]*"([^"]*)"/\1/m,Module/
--regex-tf=/^[[:space:]]*output[[:space:]]*"([^"]*)"/\1/o,Output/
--regex-tf=/^([a-z0-9_]+)[[:space:]]*=/\1/f,TFVar/

For Universal Ctags, this is any file under ~/.ctags.d/*.ctags. Suggest using ~/.ctags.d/terraform.ctags.

For Exuberant Ctags, probably ~/.ctags.

(Credit: ctags configuration and regexes derived from: https://github.com/juliosueiras/vim-terraform-completion/blob/master/ctags/terraform.ctags)

  1. Add the following to ~/.vimrc
let g:tagbar_type_tf = {
  \ 'ctagstype': 'tf',
  \ 'kinds': [
    \ 'r:Resource',
    \ 'R:Resource',
    \ 'd:Data',
    \ 'D:Data',
    \ 'v:Variable',
    \ 'V:Variable',
    \ 'p:Provider',
    \ 'P:Provider',
    \ 'm:Module',
    \ 'M:Module',
    \ 'o:Output',
    \ 'O:Output',
    \ 'f:TFVar',
    \ 'F:TFVar'
  \ ]
\ }

NOTE: a limitation of this, ctags will not generate tags for variables defined in local block because we don't provide a regex for it in step 1. It would require something more complicated because locals are defined inside a block (so a simple prefix-match regex is not enough).

TypeScript

Universal Ctags

No additional configuration necessary; Tagbar supports universal-ctags TS output. (If you're using an old config that relies on the tstags package, you'll find that removing it in favor of the built-in u-ctags support is far more accurate.)

Exuberant Ctags (Vanilla)

~/.ctags

Community maintained .ctags for typescript: https://github.com/jb55/typescript-ctags

~/.vimrc

let g:tagbar_type_typescript = {
  \ 'ctagstype': 'typescript',
  \ 'kinds': [
    \ 'c:classes',
    \ 'n:modules',
    \ 'f:functions',
    \ 'v:variables',
    \ 'v:varlambdas',
    \ 'm:members',
    \ 'i:interfaces',
    \ 'e:enums',
  \ ]
\ }

UltiSnips

Note: this configuration is now included in current versions of UltiSnips, so no setup is necessary. The examples are left for historical reference.

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',
    \ ]
\ }

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'
    \]
\}

Vlang

Copy this ctags config from the Vlang project into your ~/.ctags or ~/.config/ctags/config.ctags.

Put this in your .vimrc:

let g:tagbar_type_vlang = {
  \ 'kinds': [
    \ 'm:imodule',
    \ 'M:module',
    \ 'C:cfunction',
    \ 'f:function',
    \ 'h:method',
    \ 'c:const',
    \ 'v:variable',
    \ 's:struct',
    \ 'e:enum',
    \ 'i:interface',
    \ 'S:sfield',
    \ 'E:efield',
  \ ],
\ }

WSDL

Put this in your ~/.ctags:

--langdef=WSDL
--langmap=WSDL:.wsdl
--regex-WSDL=/^.*xmlns:([a-z]+)=/\1/n,namespace/
--regex-WSDL=/^\s*<.*:message.*name="([A-Za-z0-9_-]+)"/\1/m,message/
--regex-WSDL=/^\s*<.*:portType.*name="([A-Za-z0-9_-]+)"/\1/p,portType/
--regex-WSDL=/^\s*<.*:operation.*name="([A-Za-z0-9_-]+)"/\1/o,operation/
--regex-WSDL=/^\s*<.*:binding.*name="([A-Za-z0-9_-]+)"/\1/b,binding/
--regex-WSDL=/^\s*<.*:service.*name="([A-Za-z0-9_-]+)"/\1/s,service/

Put this in your ~/.vimrc:

let g:tagbar_type_xml = {
    \ 'ctagstype' : 'WSDL',
    \ 'kinds'     : [
        \ 'n:namespaces',
        \ 'm:messages',
        \ 'p:portType',
        \ 'o:operations',
        \ 'b:bindings',
        \ 's:service'
    \ ]
\ }

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',
    \ ]
\ }

XSD

Put this in your ~/.ctags:

--langdef=XSD
--langmap=XSD:.xsd
--regex-XSD=/^\s*<.*element.+name=["']([a-zA-Z0-9_-]+)["']/\1/e,element/
--regex-XSD=/^\s*<.*complexType.+name=["']([a-zA-Z0-9_-]+)["']/\1/c,complexType/
--regex-XSD=/^\s*<.*simpleType.+name=["']([a-zA-Z0-9_-]+)["']/\1/s,simpleType/

Put this in your ~/.vimrc:

let g:tagbar_type_xsd = {
    \ 'ctagstype' : 'XSD',
    \ 'kinds'     : [
        \ 'e:elements',
        \ 'c:complexTypes',
        \ 's:simpleTypes'
    \ ]
\ }

XSLT

Put this in your ~/.ctags:

--langdef=xslt
--langmap=xslt:.xsl
--regex-xslt=/<xsl:variable.*name="(\S+)".*>/\1/v,variable/
--regex-xslt=/<xsl:template.*name="(\S+)".*>/\1/t,template/

Put this in your ~/.vimrc:

let g:tagbar_type_xslt = {
  \ 'ctagstype' : 'xslt',
  \ 'kinds' : [
    \ 'v:variables',
    \ 't:templates'
  \ ]
\}

Yaml

Add the following to your ~/.ctags or ~/.ctags.d/yaml.ctags:

--langmap=yaml:.yml.yaml
--kinddef-yaml=s,section,sections
--kinddef-yaml=e,entry,entries
--regex-yaml=/^([a-zA-Z0-9_\/-]+):/\1/s/{scope=set}
--regex-yaml=/^ *- (name: .*)$/\1/e/{scope=ref}

If Yaml isn't in the output of ctags --list-languages, also add --langdef=yaml

... and the following in vimrc:

let g:tagbar_type_yaml = {
    \ 'ctagstype' : 'yaml',
    \ 'kinds' : [
        \ 'a:anchors',
        \ 's:section',
        \ 'e:entry'
    \ ],
  \ 'sro' : '.',
    \ 'scope2kind': {
      \ 'section': 's',
      \ 'entry': 'e'
    \ },
    \ 'kind2scope': {
      \ 's': 'section',
      \ 'e': 'entry'
    \ },
    \ 'sort' : 0
    \ }

Zig

Add this to your ~/.ctags:

--langdef=Zig
--langmap=Zig:.zig
--regex-Zig=/fn +([a-zA-Z0-9_]+) *\(/\1/f,functions,function definitions/
--regex-Zig=/(var|const) *([a-zA-Z0-9_]+) *= *(extern|packed)? *struct/\2/s,structs,struct definitions/
--regex-Zig=/(var|const) *([a-zA-Z0-9_]+) *= *(extern|packed)? *enum/\2/e,enums,enum definitions/
--regex-Zig=/(var|const) *([a-zA-Z0-9_]+) *= *(extern|packed)? *union/\2/u,unions,union definitions/
--regex-Zig=/(var|const) *([a-zA-Z0-9_]+) *= *error/\2/E,errors,error definitions/

And add this to your .vimrc:

let g:tagbar_type_zig = {
    \ 'ctagstype': 'zig',
    \ 'kinds' : [
        \'f:functions',
        \'s:structs',
        \'e:enums',
        \'u:unions',
        \'E:errors'
    \]
    \}

Alternatively you can use ztags.