Ctags is a handy tool for navigating any programming language’s source code. Ctags parses identifiers, methods, classes, and other elements from the source code and saves the index in a tag file. Each tag is kept in its line. Ctags is a program that is supported by a wide range of programming languages. Functions, variables, class members, macros, and other items may be indexed depending on the language. These tags allow a text editor, a code search engine, or another utility to quickly and readily discover definitions.
There’s also an output mode that creates a cross-reference file with information in a human-readable format regarding numerous names in a set of language files. This tool allows the user to look up the details of any method or function block. Searching for any variable in a vast project is quite beneficial. This guide demonstrates how to install ctags and use it with the vim editor – On Ubuntu, you can navigate the source code of any programming language.
Setting up ctags in Python and Vim Source
Exuberant ctags is a fun, language-independent tool for creating source code tag files. Nice editors like Vim might use these tag files to implement the much-needed “jump to definition” capability.
Ctags is fantastic; it supports Python and is compatible with Vim. There appears to be no reason to write a piece about configuring the world because it seems flawless. It’s almost there.
When using Python, ctags has one drawback: it treats import lines as definitions, at least at ctags v5.8. In most circumstances, there’s no need to explain why it’s irritating. However, after two years of agony, I discovered that all it takes is adding the –python-kinds=-i option to the command line, or better yet, to /.ctags.
To round things out, here’s a simple recipe for setting everything up and utilizing it:
How is Ctags installed?
Ubuntu does not come with Ctags installed by default. To install ctags on Ubuntu, type the following command.
sudo apt-get install ctags
or
sudo apt-get install exuberant-ctags
Select the project folder option
To check the use of ctags, pick any source code or programming project folder. This tutorial uses Python scripts to demonstrate how to utilize ctags. First, navigate to the folder where the ctags should be applied. To inspect the file list in the python folder, use the following two commands.
tuts@codeunderscored:~$ cd ~/Documents/codeunderscored_blog
Configuration of Ctags
Ctags saves all data in a tags file. Before utilizing this tool, you must first establish the tags file’s location in the .vimrc file. Then, with root permission, open the .vimrc file in vim editor and add the following set command, which specifies where the tags file will be kept.
tuts@codeunderscored:~$ sudo vim ~/.vimrc set tags+=$HOME/code/python/
Making tags
To create tags for all the files in the selected project folder, run the commands’ ctags -R *’. The ‘ls’ command is then used to see if the tag file has been created.
tuts@codeunderscored:~$ ctags -R * tuts@codeunderscored:~$ ls
In the vim editor, open the file, tags. The file holds all of the current folder’s tag information.
vim tags
Pattern-based tag search
In the vim editor, you may use the pattern to search for any tag name. In addition, you can open the app.py python file. Type’ :/if’ to find the tag ‘if’.
tuts@codeunderscored:~$ vim app.py : /if
After pressing the enter key, the following output will show. If the ‘If’ tag is found in the source code, it will be highlighted.
Tag-by-tag searching
It is a command that allows you to search for specific tags.
To search for any tag in the file that exists in the tag file, type ‘:tag tagname’ in the vim editor. In this case, the ‘create’ tag is present in the tags file. To search for the tag ‘create’ in the app.py file, type the following ctags command and press Enter. It will draw attention to the variable ‘create.’
:tag create
Go to the next tag
Ctags has a command that moves to the following tag in a list of the same kind. To advance the cursor to the next ‘num’ tag, type the following ctags command in the vim editor.
:tnext
Go back to the initial tag
Moving to the preceding tag in a list of tags of the same kind is also possible with ctags. To shift the cursor to the previous ‘num’ tag, use the ctags command in the vim editor.
:tprev
Go to the final tag
If there are many instances of the same tag in the source code, use the ctags command to advance to the last tag position in the tag list. In the tag list, the abs_num.py file has three ‘num’ tags. The cursor will be placed in the third position of the ‘num’ tag when ‘:tlast’ is used.
:tlast
Go to the first tag now
You may also use the ctags command to shift the cursor to the first tag in the same tag list. In the abs_num.py file, the following command will change the cursor to the initial position of the ‘num’ tag.
:tfirst
Choose a tag from the list
Using the ctags command after opening the file in the vim editor, you can select a specific tag from the tag list. Use the vim editor to open any source code and use ‘:tselect’ to see the current source code’s tag list. This command is checked using the same file, abs_num.py.
:tselect
After running the command as mentioned earlier, the following output will show. It reveals that the ‘num’ tag has three entries. To select a tag from the list, the user must type any number between 1 and 3 and then hit Enter.
Locate the position of a specific tag
The ‘:tags’ command can locate a specific tag position and retrieve information about it. For example, a list of three ‘num’ tags can be found in a file. When searching for the ‘num’ tag and the cursor is above the first ‘num’ tag in the list, after running the tags command as shown below.
: tags
The output indicates that the tag ‘num’ is the first in the tag list.
Using Vim and ctags to navigate your Django project
Vim’s built-in code navigation feature, which uses ctags, is handy. It can let you jump from one file to the next in a project with just one or two keystrokes if properly configured. Press Ctrl + ] when the cursor is over an object or function name, and Vim will take you straight to its definition; Ctrl +o or Ctrl+ t will take you back to the starting point. You can use g] to get a list of several matches. The tag functionality in Vim is sophisticated and extensively documented; if you’ve never used it (and you use Vim), you should give it a try.
Tags, in particular, can be a tremendous help in Django projects. A reasonably complicated Django project might include code from dozens of third-party modules scattered across hundreds of files (not to mention Django’s vast codebase). It can be a real annoyance to figure out which method of a class-based view.
Alternatively, it could be a form that you may want to override in your subclass. A properly configured tag file may drastically speed up this process by allowing you to skip to method and object descriptions with just a few keystrokes. Unfortunately, properly indexing all of your project’s dependencies with ctags might be tricky.
Ctags are simple to set up. The exuberant-ctags application must be installed (apt-get install exuberant-ctags on Debian). This has been illustrated in the initial sections of this article.
It’s as simple as telling Vim where to find the tags file; something like set tags=tags in our vimrc does the trick. Then we’ll be able to sprint:
ctags -R --fields=+l --languages=python --python-kinds=-iv -f /.tags ./
To produce our tags in the root of our project, this creates a tags file by recursively indexing all python files in the current directory, ignoring imports and variables (-iv). However, this will not index the standard library modules or any pip-installed modules.
Ctags is told to look in the current directory by the . / at the end of the command. It isn’t going to help us navigate generic class-based views or comparable objects using ctags! We need a way to list the paths where ctags should seek for modules to utilize it fully.
Even though we expected it, we were startled to see that a few solutions are floating around the internet, none of them function correctly. If we’re using a virtualenv, we may look for our packages in the $VIRTUAL ENV environment variable. On the other hand, this fails to index the standard Python libraries and fails if we’re not working in a virtualenv. To locate Python’s lib directory, use distutils.sysconfig.get python lib. It is a little more complicated technique. Whether or not we’re using a virtualenv, this works, but it still doesn’t index the standard libraries.
Packages installed with pip install -either of these methods does not index. Of course, we could hack together a solution that combines both ways with some logic to detect any installed source, but that’s getting a little elaborate. We can do better.
Why don’t we utilize the list of locations where Python checks for modules that Python keeps? Python will look for modules in the folders listed in sys.path. To produce the data for the shell, we’ll need to make a few changes, but it’s not too difficult:
python -c "import os, sys; print(' '.join('{}'.format(d) for d in sys.path if os.path.isdir(d)))"
When we add everything up, we get:
ctags -R --fields=+l --languages=python --python-kinds=-iv -f ./tags $(python -c "import os, sys; print(' '.join('{}'.format(d) for d in sys.path if os.path.isdir(d)))")
This indexes only the modules that are available to the current Python installation. It’s just what we were looking for! If we wish to index our work as well, we can add . / to the directories, but we like to use ctags strictly for exploring third-party code. You don’t want to be constantly typing this command. Thus, we have a keybinding to execute the command in Vim; since we are just tagging third-party code, we only have to remember to run it when we install new packages.
In any case, you’re now ready to use Vim to browse your Django codebase swiftly and efficiently! Furthermore, if you put up a git hook to run ctags, you index your work automatically.
P.S. Emacs users aren’t entirely forgotten here. ctags can also generate tags that are compatible with Emacs! Take a look!
Conclusion
If the tag entry exists in the tags file and the user knows the relevant tag name, Ctags makes it simple to locate a specific source code area. However, the use of ctags has a drawback. Any file’s source code can be modified at any moment. Because ctags can’t update tags files automatically, you’ll need to configure it every time your source code changes. This problem can be solved with the Autotag plugin. This plugin updates the tags file. However, to utilize this plugin, you must use vim with Python.