*tagbar.txt* Display tags of a file in their correct scope Author: Jan Larres Licence: Vim licence, see |license| Homepage: http://majutsushi.github.com/tagbar/ Version: 1.2 ============================================================================== Contents *tagbar* *tagbar-contents* 1. Intro ........................... |tagbar-intro| Pseudo-tags ................... |tagbar-pseudotags| Supported features ............ |tagbar-features| 2. Requirements .................... |tagbar-requirements| 3. Installation .................... |tagbar-installation| 4. Usage ........................... |tagbar-usage| Commands ...................... |tagbar-commands| Key mappings .................. |tagbar-keys| 5. Configuration ................... |tagbar-configuration| 6. Extending Tagbar ................ |tagbar-extend| 7. Bugs and limitations ............ |tagbar-bugs| 8. History ......................... |tagbar-history| 9. Todo ............................ |tagbar-todo| 10. Credits ......................... |tagbar-credits| ============================================================================== 1. Intro *tagbar-intro* Tagbar is a plugin for browsing the tags of source code files. It provides a sidebar that displays the ctags-generated tags of the current file, ordered by their scope. This means that for example methods in C++ are displayed under the class they are defined in. Let's say we have the following code inside of a C++ file: > namespace { char a; class Foo { public: Foo(); ~Foo(); private: int var; }; }; < Then Tagbar would display the tag information like so: > __anon1* : namespace Foo : class +Foo() +~Foo() -var a < This example shows several important points. First, the tags are listed indented below the scope they are defined in. Second, the type of a scope is listed after its name and a colon. Third, tags for which the access/visibility information is known are prefixed with a symbol indicating that. ------------------------------------------------------------------------------ PSEUDO-TAGS *tagbar-pseudotags* The example also introduces the concept of "pseudo-tags". Pseudo-tags are tags that are not explicitly defined in the file but have children in it. In this example the namespace doesn't have a name and thus ctags doesn't generate a tag for it, but since it has children it still needs to be displayed using an auto-generated name. Another case where pseudo-tags appear is in C++ implementation files. Since classes are usually defined in a header file but the member methods and variables in the implementation file the class itself won't generate a tag in that file. Since pseudo-tags don't really exist they cannot be jumped to from the Tagbar window. Pseudo-tags are denoted with an asterisk ('*') at the end of their name. ------------------------------------------------------------------------------ SUPPORTED FEATURES *tagbar-features* The following features are supported by Tagbar: - Display tags under their correct scope. - Automatically update the tags when switching between buffers and editing files. - Display visibility information of tags if available. - Highlight the tag near the cursor while editing files. - Jump to a tag from the Tagbar window. - Display the complete prototype of a tag. - Tags can be sorted either by name or order of appearance in the file. - Scopes can be folded to hide uninteresting information. - Supports all of the languages that ctags does, i.e. Ant, Assembler, ASP, Awk, Basic, BETA, C, C++, C#, COBOL, DosBatch, Eiffel, Erlang, Flex, Fortran, HTML, Java, JavaScript, Lisp, Lua, Make, MatLab, OCaml, Pascal, Perl, PHP, Python, REXX, Ruby, Scheme, Shell script, SLang, SML, SQL, Tcl, Tex, Vera, Verilog, VHDL, Vim and YACC. - Can be extended to support arbitrary new types. ============================================================================== 2. Requirements *tagbar-requirements* The following requirements have to be met in order to be able to use tagbar: - Vim 7.0 or higher. Older versions will not work since Tagbar uses data structures that were only introduced in Vim 7. - Exuberant ctags 5.5 or higher. Ctags is the program that generates the tag information that Tagbar uses. It is shipped with most Linux distributions, otherwise it can be downloaded from the following website: http://ctags.sourceforge.net/ Tagbar will work on any platform that ctags runs on -- this includes UNIX derivatives, Mac OS X and Windows. Note that other versions like GNU ctags will not work. Tagbar generates the tag information by itself and doesn't need already existing tag files. - File type detection must be turned on in vim. This can be done with the following command in your vimrc: > filetype on < See |filetype| for more information. - Tagbar will not work in |restricted-mode|. ============================================================================== 3. Installation *tagbar-installation* Use the normal Vimball install method for installing tagbar.vba: > vim tagbar.vba :so % :q < Alternatively you can clone the git repository and then add the path to 'runtimepath' or use the pathogen plugin. Don't forget to run |:helptags| if you're not using pathogen. If the ctags executable is not installed in one of the directories in your $PATH environment variable you have to set the g:tagbar_ctags_bin variable, see |g:tagbar_ctags_bin|. ============================================================================== 4. Usage *tagbar-usage* There are essentially two ways to use Tagbar: 1. Have it running all the time in a window on the side of the screen. In this case Tagbar will update its contents whenever the source file is changed and highlight the tag the cursor is currently on in the file. If a tag is selected in Tagbar the file window will jump to the tag and the Tagbar window will stay open. |g:tagbar_autoclose| has to be unset for this mode. 2. Only open Tagbar when you want to jump to a specific tag and have it close automatically once you have selected one. This can be useful for example for small screens where a permanent window would take up too much space. You have to set the option |g:tagbar_autoclose| in this case. The cursor will also automatically jump to the Tagbar window when opening it. Opening and closing the Tagbar window~ Use |:TagbarOpen| or |:TagbarToggle| to open the Tagbar window if it is closed. By default the window is opened on the right side, set the option |g:tagbar_left| to open it on the left instead. If the window is already open, |:TagbarOpen| will jump to it and |:TagbarToggle| will close it again. |:TagbarClose| will simply close the window if it is open. It is probably a good idea to assign a key to these commands. For example, put this in your |vimrc|: > nnoremap :TagbarToggle < You can then open and close Tagbar by simply pressing the key. You can also use |:TagbarOpenAutoClose| to open the Tagbar window, jump to it and have it close automatically on tag selection regardless of the |g:tagbar_autoclose| setting. Jumping to tags~ When you're inside the Tagbar window you can jump to the definition of a tag by moving the cursor to a tag and pressing or double-clicking on it with the mouse. The source file will then move to the definition and put the cursor in the corresponding line. This won't work for pseudo-tags. Sorting~ You can sort the tags in the Tagbar window in two ways: by name or by file order. Sorting them by name simply displays the tags in their alphabetical order under their corresponding scope. Sorting by file order means that the tags keep the order they have in the source file, but are still associated with the correct scope. You can change the sort order by pressing the "s" key in the Tagbar window. The current sort order is displayed in the statusbar of the Tagbar window. Folding~ The displayed scopes (and unscoped types) can be folded to hide untinteresting information. Unfortunately the folding state is lost once you leave the Tagbar window, see |tagbar-bugs|. Displaying the prototype of a tag~ Tagbar can display the prototype of a tag. More precisely it can display the line in which the tag is defined. This can be done by either pressing when on a tag or hovering over a tag with the mouse. In the former case the prototype will be displayed in the command line |Command-line|, in the latter case it will be displayed in a pop-up window. The prototype will also be displayed when the cursor stays on a tag for 'updatetime' milliseconds. ------------------------------------------------------------------------------ COMMANDS *tagbar-commands* :TagbarOpen Open the Tagbar if it is closed. In case it is already open jump to it. :TagbarClose Close the Tagbar window if it is open. :TagbarToggle Open the Tagbar window if it is closed or close it if it is open. :TagbarOpenAutoClose Open the Tagbar window and close it on tag selection, regardless of the setting of |g:tagbar_autoclose|. If it was already open jump to it. ------------------------------------------------------------------------------ KEY MAPPINGS *tagbar-keys* These mappings are valid in the Tagbar window: Display key mapping help. / Jump to the tag under the cursor. Doesn't work for pseudo-tags. <2-LeftMouse> Same as . Display the prototype of the current tag (i.e. the line defining it) in the command line. + Open the fold under the cursor. - Close the fold under the cursor. * Open all folds. = Close all folds. s Toggle sort order between name and file order. x Toggle zooming the window. q Close the Tagbar window. ============================================================================== 5. Configuration *tagbar-configuration* *g:tagbar_ctags_bin* g:tagbar_ctags_bin~ Use this option to specify the location of your ctags executable. Only needed if it is not in one of the directories in your $PATH environment variable. Example: > let g:tagbar_ctags_bin = 'C:\Ctags5.8\ctags.exe' < *g:tagbar_left* g:tagbar_left~ By default the Tagbar window will be opened on the right-hand side of vim. Set this option to open it on the left instead. Example: > let g:tagbar_left = 1 < *g:tagbar_width* g:tagbar_width~ Width of the Tagbar window in characters. The default is 40. Example: > let g:tagbar_width = 30 < *g:tagbar_autoclose* g:tagbar_autoclose~ If you set this option the Tagbar window will automatically close when you jump to a tag. The default is to not automatically close the window. Example: > let g:tagbar_autoclose = 1 < *g:tagbar_autofocus* g:tagbar_autofocus~ If you set this option the cursor will move to the Tagbar window when it is opened. The default is to not move the cursor to the window. Example: > let g:tagbar_autofocus = 1 < *g:tagbar_sort* g:tagbar_sort~ If this option is set the tags are sorted according to their name. If it is unset they are sorted according to their order in the source file. The default is to sort them by name. Example: > let g:tagbar_sort = 0 < *g:tagbar_compact* g:tagbar_compact~ Setting this option will result in Tagbar omitting the short help at the top of the window and the blank lines in between top-level scopes in order to save screen real estate. The default is to not use compact mode. Example: > let g:tagbar_compact = 1 < *g:tagbar_expand* g:tagbar_expand~ If this option is set the Vim window will be expanded by the width of the Tagbar window if using a GUI version of Vim. The default is not to expand the window. Example: > let g:tagbar_expand = 1 < ============================================================================== 6. Extending Tagbar *tagbar-extend* Tagbar has a flexible mechanism for extending the existing file type (i.e. language) definitions. This can be used both to change the settings of the existing types and to add completely new types. Every type definition in Tagbar is a dictionary with the following keys: ctagstype: The name of the language as recognized by ctags. Use the command > ctags --list-languages < to get a list of the languages ctags supports. The case doesn't matter. kinds: A list of the "language kinds" that should be listed in Tagbar, ordered by the order they should appear in in the Tagbar window. Use the command > ctags --list-kinds={language name} < to get a list of the kinds ctags supports for a given language. An entry in this list is a string with two parts separated by a colon: the first part is the one-character abbreviation that ctags uses, and the second part is an arbitrary string that will be used in Tagbar as the header for the tags of this kind that are not listed under a specific scope. For example, the string > "f:functions" < would list all the function definitions in a file under the header "functions". scopes: A list of the scopes that ctags supports for a given language, for example classes, structs etc. Unfortunately there is no ctags option to list the scopes, you have to look at the tags ctags generates manually. For example, let's say we have a C++ file "test.cpp" with the following contents: > class Foo { public: Foo(); ~Foo(); private: int var; }; < We then run ctags in the followin way: > ctags -f - --format=2 --excmd=pattern --fields=nksazSmt --extra= test.cpp < Then the output for the variable "var" would look like this: > var tmp.cpp /^ int var;$/;" kind:m line:11 class:Foo access:private < This shows that the scope name for an entry in a C++ class is simply "class". So you would need to put this exact word into the "scopes" list. The order again determines the order in which the tags will be displayed in Tagbar. sro: The scope resolution operator. For example, in C++ it is "::" and in Java it is ".". When in doubt run ctags as shown above and look at the output. kind2scope: A dictionary describing the mapping of tag kinds (in their one-character representation) to the scopes their children will appear in. scope2kind: The opposite of the above, mapping scopes to the kinds of their parents. Most of the time it is the exact inverse of the above, but in some cases it can be different, for example when more than one kind maps to the same scope. If it is the exact inverse for your language you only need to specify one of the two keys. replace: If you set this entry to 1 your definition will completely replace {optional} an existing default definition. This is useful if you want to disable scopes for a file type for some reason. Note that in this case you have to provide all the needed entries yourself! sort: This entry can be used to override the global sort setting for {optional} this specific file type. The meaning of the value is the same as with the global setting, that is if you want to sort tags by name set it to 1 and if you want to sort them according to their order in the file set it to 0. You then have to assign this dictionary to a variable with the name > g:tagbar_type_{vim filetype} < For example, for C++ the name would be "g:tagbar_type_cpp". If you don't know the vim file type run the following command: > :set filetype? < and vim will display the file type of the current buffer. Example: C++~ Here is a complete example that shows the default configuration for C++ as used in Tagbar. > let g:tagbar_type_cpp = { \ 'ctagstype' : 'c++', \ 'kinds' : [ \ 'd:macros', \ 'p:prototypes', \ 'g:enums', \ 'e:enumerators', \ 't:typedefs', \ 'n:namespaces', \ 'c:classes', \ 's:structs', \ 'u:unions', \ 'f:functions', \ 'm:members', \ 'v:variables' \ ], \ 'scopes' : [ \ 'namespace', \ 'class', \ 'struct', \ 'enum', \ 'union' \ ], \ 'sro' : '::', \ 'kind2scope' : { \ 'g' : 'enum', \ 'n' : 'namespace', \ 'c' : 'class', \ 's' : 'struct', \ 'u' : 'union' \ }, \ 'scope2kind' : { \ 'enum' : 'g', \ 'namespace' : 'n', \ 'class' : 'c', \ 'struct' : 's', \ 'union' : 'u' \ } \ } < Which of the keys you have to specify depends on what you want to do. Changing an existing definition~ If you want to change an existing definition you only need to specify the parts that you want to change. It probably only makes sense to change "kinds" and/or "scopes", which would be the case if you wanted to exclude certain kinds from appearing in Tagbar or if you want to change their order. As an example, if you didn't want Tagbar to show prototypes for C++ files and switch the order of enums and typedefs, you would do it like this: > let g:tagbar_type_cpp = { \ 'kinds' : [ \ 'd:macros', \ 'g:enums', \ 't:typedefs', \ 'e:enumerators', \ 'n:namespaces', \ 'c:classes', \ 's:structs', \ 'u:unions', \ 'f:functions', \ 'm:members', \ 'v:variables' \ ] \ } < Compare with the complete example above to see the exact change. Adding a definition for a new language/file type~ In order to be able to add a new language to Tagbar you first have to create a configuration for ctags that it can use to parse the files. This can be done in two ways: 1. Use the --regex argument for specifying regular expressions that are used to parse the files. An example of this is given below. A disadvantage of this approach is that you can't specify scopes. 2. Write a parser plugin in C for ctags. This approach is much more powerful than the regex approach since you can make use of all of ctags' functionality but it also requires much more work. Read the ctags documentation for more information about how to do this. For the first approach the only keys that are needed in the Tagbar definition are "ctagstype" and "kinds". A definition that supports scopes has to define those two and in addition "scopes", "sro" and at least one of "kind2scope" and "scope2kind". Let's assume we want to add support for LaTeX to Tagbar using the regex approach. First we put the following text into ~/.ctags: > --langdef=latex --langmap=latex:.tex --regex-latex=/^\\tableofcontents/TABLE OF CONTENTS/s,toc/ --regex-latex=/^\\frontmatter/FRONTMATTER/s,frontmatter/ --regex-latex=/^\\mainmatter/MAINMATTER/s,mainmatter/ --regex-latex=/^\\backmatter/BACKMATTER/s,backmatter/ --regex-latex=/^\\bibliography\{/BIBLIOGRAPHY/s,bibliography/ --regex-latex=/^\\part[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/PART \2/s,part/ --regex-latex=/^\\part[[:space:]]*\*[[:space:]]*\{([^}]+)\}/PART \1/s,part/ --regex-latex=/^\\chapter[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/CHAP \2/s,chapter/ --regex-latex=/^\\chapter[[:space:]]*\*[[:space:]]*\{([^}]+)\}/CHAP \1/s,chapter/ --regex-latex=/^\\section[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\. \2/s,section/ --regex-latex=/^\\section[[:space:]]*\*[[:space:]]*\{([^}]+)\}/\. \1/s,section/ --regex-latex=/^\\subsection[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\.\. \2/s,subsection/ --regex-latex=/^\\subsection[[:space:]]*\*[[:space:]]*\{([^}]+)\}/\.\. \1/s,subsection/ --regex-latex=/^\\subsubsection[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\.\.\. \2/s,subsubsection/ --regex-latex=/^\\subsubsection[[:space:]]*\*[[:space:]]*\{([^}]+)\}/\.\.\. \1/s,subsubsection/ --regex-latex=/^\\includegraphics[[:space:]]*(\[[^]]*\])?[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\3/g,graphic+listing/ --regex-latex=/^\\lstinputlisting[[:space:]]*(\[[^]]*\])?[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\3/g,graphic+listing/ --regex-latex=/\\label[[:space:]]*\{([^}]+)\}/\1/l,label/ --regex-latex=/\\ref[[:space:]]*\{([^}]+)\}/\1/r,ref/ --regex-latex=/\\pageref[[:space:]]*\{([^}]+)\}/\1/p,pageref/ < This will create a new language definition with the name "latex" and associate it with files with the extension ".tex". It will also define the kinds "s" for sections, chapters and the like, "g" for included graphics, "l" for labels, "r" for references and "p" for page references. See the ctags documentation for more information about the exact syntax. Now we have to create the Tagbar language definition in our vimrc: > let g:tagbar_type_tex = { \ 'ctagstype' : 'latex', \ 'kinds' : [ \ 's:sections', \ 'g:graphics', \ 'l:labels', \ 'r:refs', \ 'p:pagerefs' \ ], \ 'sort' : 0 \ } < Sort has been disabled for LaTeX so that the sections appear in their correct order. They unfortunately can't be shown nested with their correct scopes since as already mentioned the regular expression approach doesn't support that. Tagbar should now be able to show the sections and other tags from LaTeX files. ============================================================================== 7. Bugs and limitations *tagbar-bugs* - Nested pseudo-tags cannot be properly parsed since only the direct parent scope of a tag gets assigned a type, the type of the grandparents is not reported by ctags (assuming the grandparents don't have direct, real children). For example, if we have a C++ with the following content: > foo::Bar::init() { // ... } foo::Baz::method() { // ... } < In this case the type of "foo" is not known. Is it a namespace? A class? For this reason the methods are displayed in Tagbar like this: > foo::Bar* : class init() foo::Baz* : class method() < - Scope-defining tags at the top level that have the same name but a different kind/scope type can lead to an incorrect display. For example, the following Python code will incorrectly insert a pseudo-tag "Inner2" into the "test" class: > class test: class Inner: def foo(self): pass def test(): class Inner2: def bar(self): pass < I haven't found a clean way around this yet, but it shouldn't be much of a problem in practice anyway. Tags with the same name at any other level are no problem, though. - The fold state of the Tagbar window is lost when the window is left. Again, I don't know of any proper way around this that still allows auto-updating -- |winsaveview()| doesn't really help here. ============================================================================== 8. History *tagbar-history* 1.2 (2011-02-28) - Fix typo in Ruby definition 1.1 (2011-02-26) - Don't lose syntax highlighting when ':syntax enable' is called - Allow expanding the Vim window when Tagbar is opened 1.0 (2011-02-23) - Initial release ============================================================================== 9. Todo *tagbar-todo* - Allow filtering the Tagbar content by some criteria like tag name, visibility, kind ... - Integrate Tagbar with the FSwitch plugin to provide header file information in C/C++. - Allow jumping to a tag in the preview window, a split window or a new tab. ============================================================================== 10. Credits *tagbar-credits* Tagbar was written by Jan Larres and is released under the Vim licence, see |license|. It was heavily inspired by the Taglist plugin by Yegappan Lakshmanan and uses a small amount of code from it. Original taglist copyright notice: Permission is hereby granted to use and distribute this code, with or without modifications, provided that this copyright notice is copied with it. Like anything else that's free, taglist.vim is provided *as is* and comes with no warranty of any kind, either expressed or implied. In no event will the copyright holder be liable for any damamges resulting from the use of this software. ============================================================================== vim: tw=78 ts=8 sw=8 sts=8 noet ft=help