Ctags is a source code indexing tool. With ctags, we can easily find the definitions of the classes, functions, and variables. According to my experiences, ctags can significantly reduce the time to browse the source code. In this post, I would like to give a brief introduction to ctags and vim.
Installation
First, we have to install exuberant-ctags
package for ctags. On
Ubuntu or Debian, we can install exuberant-ctags
with:
$ sudo apt-get install exuberant-ctags
Second, I would suggest to tweak the .vimrc
as well. By default,
vim will only load the tags file from:
- the current working directory, or
- the directory containing the opened source file.
For example, if you have opened the file foo/bar.c
, then vim will
only check the tags file named after tags
, TAGS
,
foo/tags
, or foo/TAGS
. However, the tags file in the
parent directories, such as ../../tags
won't be considered.
To ask vim to search for tags file in the parent directories, we should
add an extra semicolon ;
after ./tags
and ./TAGS
. For
example,
set tags=./tags;,./TAGS;,tags,TAGS
Third, if you wish to put the generated tags file in the .git
directory so that the tags file won't be added to git repository, then you
may wish to add the following snippets to the .vimrc
as well:
" Check .git/tags for ctags file.
fun! FindTagsFileInGitDir(file)
let path = fnamemodify(a:file, ':p:h')
while path != '/'
let fname = path . '/.git/tags'
if filereadable(fname)
silent! exec 'set tags+=' . fname
endif
let path = fnamemodify(path, ':h')
endwhile
endfun
augroup CtagsGroup
autocmd!
autocmd BufRead * call FindTagsFileInGitDir(expand("<afile>"))
augroup END
This snippet allows vim to search for the tags file in the .git
directory of the parent directories of the source file, such as
../../.git/tags
.
Usage
After installation, we have to generate the tags file as the index. We can generate the tags file with the following commands:
$ ctags -R [dir]
$ ctags -R -f [tags-file] [dir]
$ ctags --tag-relative=yes -R -f [tags-file] [dir]
Usually, I prefer to run this command in the git repository:
$ ctags --tag-relative=yes -R -f .git/tags .
It is highly recommended to add --tag-relative=yes
to the ctags
command. Without this option, vim won't be able to open the correct source
file under certain circumstances.
Sometimes, there might be some special naming convention in your project. To
index those files, we can change the programming language map with
--langmap
option. For example, to treat the .inc
file
extension as C++ source code:
$ ctags --langmap=c++:+*.inc ...
This options adds .inc
to the C++ file extensions (in addition to the
default file extensions such as .c
, .cpp
, and etc.)
Vim Keys
After generating the tags file, we can browse the source code with vim and ctags. Vim has excellent built-in support for ctags. We can simply jump to or preview the definition with a little key stroke. Here are some combinations for your reference.
Basic Usage
First, we can jump to the matching patterns with the :ta
command.
If we are not satisfied by the first match, we can jump to the next match
with :tn
. Conversely, we can jump to the previous match with
:tN
. We can also list all matches with :ts
.
Command | Usage |
---|---|
:ta [pattern] | Jump to the best matching tag |
:ta /[regex] | Jump to the best matching tag |
:ts [pattern] | List the tags and jump to the selected one |
:ts /[regex] | List the tags and jump to the selected one |
:tn | Jump to next matching tag |
:tN | Jump to previous matching tag |
Here are some tips to search for the keyword pointed by the cursor:
- To show the best matching in the new window, press
Ctrl+W
then]
. (This is my favorite!) - To list all matchings and show the selected one in the new window, press
Ctrl+W
theng]
. - To jump to the best matching directly, press
Ctrl+]
. - To list all matchings and jump to selected one, press
g]
. - To search a pattern by selection, press
v
to enter visual mode, select the text, and press eitherCtrl+]
org]
.
Preview Window
The preview window is a separated window that will pop up on the top for
quick reference. Unlike the "Ctrl-W
then ]
" command mentioned
above, the cursor won't be moved to the preview window.
To preview the keywords pointed by the cursor, press Ctrl-W
and
}
. Alternatively, we can open the preview window by the :pt
command. To close the preview window, use the :pc
command.
Command | Usage |
---|---|
:pt [pattern] | Preview the best matching tag |
:ptn | Preview the next matching tag |
:ptN | Preview the previous matching tag |
:pc | Close the preview window |
Tag Stack
If we jump to a matching tag with :ta
or g]
, we may wish to go
back and forth. When we jump to a new tag, the current position will be pushed
to the tag stack. To go back to previous position (i.e. pop the tag
stack), we can use the :po
command. To go forward, we can use the
:ta
command.
Command | Usage |
---|---|
:tags | List the tag stack |
:po | Pop the tag stack (go up) |
:[n]po | Pop n items from the tag stack (go up) |
:ta | Push the tag stack (go down) |
:[n]ta | Push n items to the tag stack (go down) |
Conclusion
In this post, we gave a brief introduction to the basic usages of ctags. We
have mentioned some handy .vimrc
tweaks and some important ctags
option. Besides, we have walked through several useful vim commands for
code browsing and navigation. This should would be sufficient for most
use cases. You can find more materials from the references.
Last, but not the least, I would like to say that ctags is an amazing source code indexing tool. I found my programming productivity has been significantly improved by ctags. Hope you enjoy it too. Happy coding!
Reference
- Andrew Stewart, Vim and Ctags
- Vim Wikia, Browsing programs with tags
- Vim Documentation, Tags and special searches