Ctags is a tool that makes it easy to navigate large source code projects. It provides some of the features that you may be used to using in Eclipse or other IDEs, such as the ability to jump from the current source file to definitions of functions and structures in other files. Ctags will make it much easier to find the Linux kernel files that you have to modify for your CSE 451 projects. Ctags also supports many languages besides C, so you may find it useful for future projects.
Compatibility: Windows, Linux, Mac OS, IOS, Android, UNIX, AmigaOS, and MorphOS. Top plugins and features: Scripts that allow you to perform almost all of the programming tasks in Python. Ctags for better tag navigation. Built-in basic word completion. Pros: It has a keyboard interface to improve efficiency.
- There other things where building ctags on OSX differs from building on GNU/Linux. Filenames on HFS+ (the Mac OS filesystem) are case-preserving, but not case-sensitive in 99% of configurations. If a user manually formats their disk with a case sensitive version of HFS+, then the filesystem will behave like normal GNU/Linux systems.
- Download Exuberant Ctags for free. Exuberant Ctags is a multilanguage reimplementation of the Unix ctags utility. Ctags generates an index of source code definitions which is used by numerous editors and utilities to instantly locate the definitions.
Ctags should already be installed on CSE instructional servers such as forkbomb and attu. Ctags is first run on its own to generate a 'tags' file, then it is invoked from within another Linux text editor such as Emacs or Vim.
These steps assume you want to use Ctags on the Linux kernel, but should generalize to other projects.
Important
If you are not on forkbomb or attu, make sure that the system you are using has 'Exuberant Ctags' installed, rather than the original 'Ctags,' by running ctags --version.
![For For](https://upload.jianshu.io/users/upload_avatars/6278390/6ddd42c8-3271-4248-b87b-05541dd7c09b.jpeg)
Tip
Like all Linux programs, Ctags has a man page (man 1 ctags). All of the information in this tutorial, and lots more advanced information, can be found there.
Tip
If you are unfamiliar with Emacs, you should go through the Emacs tutorial. Run emacs, then press C-h t (Ctrl+h, then t) to begin the interactive tutorial. It shouldn't take too long, and it's worth your time. You can also check out the online tour. If you get stuck, press C-g to cancel pending commands, and exit Emacs by pressing C-xC-c.
Disclaimer
The author of this tutorial is not an Emacs expert; if you notice potential flaws or improvements, please contact him.
- cd to the root directory of your Linux kernel code:
- Run Etags (Ctags for Emacs) over the kernel to generate the TAGS file. etags will overflow its stack if called recursively over the entire kernel, so we use the find command to find all of the .c, .h, and .S (assembly) files in the kernel, then tell etags to append the tags in those files to the TAGS file. For Linux 2.6.13, this should only take a minute or so:NoteYou may see messages like 'Warning: cannot open source file '.' : Permission denied' while etags is building the tags file. These warnings can be ignored.
- Open any Linux source file in Emacs and use the following basic commands:Keyboard commandActionM-. <RET>Jump to the tag underneath the cursorM-. <tag> <RET>Search for a particular tagFind the next definition for the last tagM-*Pop back to where you previously invoked 'M-.'ImportantThe first time you run an Etags command within Emacs, you may have to specify the location of your TAGS file (i.e. /cse451/./linux-2.6.13.2/TAGS). Say yes when prompted to load the really big tags file.The first command is probably the one you will use most often: it jumps to the definition of the tag (function name, structure name, variable name, or pretty much anything). The second command can be used to search for any tag in the TAGS file, regardless of the file you are currently viewing. Sometimes Etags will find multiple definitions for a given tag; when this is the case, use the third command to jump through the possible definitions until you find the one that you want. Finally, use the fourth command to jump back up in the tag 'stack.'You'll probably find that for some tags (common structures, for example), Etags finds hundreds or thousands of uses in the code, and jumping through them (with the third command above) to try to find the original definition is useless. In this case, you can run the following two commands to list all of the uses of a given <tag>:This will display a list of the tag definitions in another buffer. Switch to the new buffer (C-x o), scroll through the list of definitions to the one that you want, then press Enter to open the file. When you're done, instead of jumping back up in the tag stack, close the new buffer (C-x k). To switch back to your original buffer and expand it, use C-x o to switch to it, then C-x 1 to expand.NoteEven the list of all definitions given by tags-apropos may be too large to find the definition that you're looking for. This is mostly a problem for structs (struct inode, for instance) that are used frequently in the kernel. You should still find Etags useful for jumping to function definitions and less-commonly-used structs. Ctags for Vim appears to do a better job of separating 'definitions' from 'uses' in its tags file, so this is less of a problem for Vim; for Emacs, there may be other ways to mitigate this problem (see this page, for example). Alternatively, you may wish to use cscope to find function and structure definitions, or just use the third step of the Vim instructions below.
Note
These commands were tested with Vim (7.2), but will likely work with Vi or other Vi emulators as well.
- cd to the root directory of your Linux kernel code:
- Run Ctags recursively over the entire kernel to generate the tags file. For Linux 2.6.13, this should only take a minute or so:NoteYou may see messages like 'Warning: cannot open source file '.' : Permission denied' while ctags is building the tags file. These warnings can be ignored.
- To search for a specific tag and open Vim to its definition, run the following command in your shell:
- Or, open any Linux source file in Vim and use the following basic commands:Keyboard commandCtrl-]Jump to the tag underneath the cursor:ts <tag> <RET>Search for a particular tag:tnGo to the next definition for the last tag:tpGo to the previous definition for the last tag:tsAma in word for mac computer. List all of the definitions of the last tagCtrl-t The cracker factory.Jump back up in the tag stackThe first command is probably the one you will use most often: it jumps to the definition of the tag (function name, structure name, variable name, or pretty much anything) under the cursor. The second command can be used to search for any tag, regardless of the file that is currently opened. If there are multiple definitions/uses for a particular tag, the tn and tp commands can be used to scroll through them, and the ts command can be used to 'search' a list for the definition you want (useful when there are dozens or hundreds of definitions for some commonly-used struct). Finally, the last command is used to jump back up in the tag stack to the location you initiated the previous tag search from.
Author: Peter Hornyack (pjh@cs)
Posted June 25, 2015With projects like cocoa.vim and vim-ios, iOS developers have a variety of helpful tools when deciding to build an app in Vim. However, with implementation files, header files, and the numerous set of frameworks we use to build apps, I’ve always found auto-completion and code navigation to be particularly difficult when writing Objective-C, especially when dealing with larger projects.
To remedy this, I’ve started using a very old tool, called ctags. ctags is able to parse source code and index methods, functions, classes, etc. for quick access later. Modern versions of Vim are built with ctags support by default, so this makes for a very easy integration.
Let’s get started.
Setup
Luckily for us, Mac OS X comes with ctags installed by default …but unfortunately for us, this version (despite what the documentation says) doesn’t support Objective-C. We’ll have to use Homebrew to install a newer version. Start by executing the following to install the latest and greatest version of ctags:
Next, let’s define a few default flags to always use when running ctags. These can be specified in a
.ctags
file in your home directory:Finally, we’ll set up a bash alias to make our lives easier when running ctags. Unfortunately, ctags assumes all
.m
files are Matlab files, not Objective-C implementation files, so we’ll create a new command we can use that will ensure .m
files are treated in the way that we need. Go ahead and add the following line of code to the .bash_profile
file in your home directory:At this point, we’re ready to start processing our code.
Indexing Your Project
If you’ve been following along word-for-word so far, you can simply run the following command from your project’s root directory to create a local tag index:
This will create a file called
tags
that Vim is smart enough to read. Now, if you open Vim in this directory, you should be able to start jumping through your project’s source code already. Try the following command from within Vim:You should be taken directly to the
@interface
declaration for your class.This is a great start, but oftentimes as iOS developers we find that we need to take a deeper look and check out the headers or documentation for an Apple Framework instead of our own code.
Indexing System Headers
Let’s begin by generating tags for some of the more commonly-used Apple Frameworks. We’ll start by opening up the folder containing all of the iOS and Mac OS X frameworks and peering inside:
Here, every Framework that we can include and link to has a corresponding
*.framework
folder with parseable header files inside. We can use these files to generate a global tag list for all of the Frameworks we use on a daily basis. I’d start with just a few Frameworks - a tag file containing all of them gets pretty slow to search, at least on my system.By using the
--append
and -f
flags in ctags, we can output and append tags to a file of our choice. I like to keep the MapKit, CoreLocation, and Foundation frameworks in my database. Anytime you want to add a Framework to your tags database, a command like the following will work:Ctags For Mac Pro
Do this for a couple of your most often-used Frameworks to get a good base.
Next, we’ll add tags for UIKit. The UIKit frameworks are stored on a per-iOS SDK basis deep inside of the
Xcode.app
folder, so we’ll need to start by navigating there (make sure to substitute the 8.3
in the next command for the iOS version you want):Now, we can just run the same command as above to append to our global tag list:
At this point we’ve got two tag databases ready — one for our project, and one for the Frameworks we intend to use. Let’s jump back over to Vim.
Vim Configurations
As we saw above, Vim was smart enough to find and automatically take a look at the local
tags
file to process our codebase. However, we need to tell Vim about the global Objective-C tags we just generated. Using an autocmd will be a great solution to make this database searchable only when we’re in an Objective-C file.Open your
.vimrc
file and add the following:Now, we’ll be able to automatically search our local and global tag databases for any project that we open.
Basic Usage
Now that we’ve built our full tag archive, we can start querying and jumping around our (and Apple’s) codebases. The following commands and key combinations will form a good start for poking around.
This command will let you go to the definition of the given tag (try it with an Apple Framework class this time —
UITableViewDataSource
always has details to the method signatures that I forget). Once you’re done, you may use <c-t>
or :bd
to leave.This form is the same as the above
tag
except that if more than one match is found, a menu is presented where you may choose which definition you want to jump to. Additionally, this is a good command to use the /
search modifier with. For example, to find tags beginning with NSAss
the :tselect /NSAss
command may be issued.This command provides a menu of previously-found tags from your current session. Simply type the number of the tag you want to view and press Enter to jump to it again.
This normal mode command will perform a
:tag
command for the currently selected word. Try putting your cursor within a class name and executing this.In insert mode, this will provide an autocompletion menu based on tag file contents. The arrow keys navigate the list,
<c-y>
accepts and inserts, and <c-e>
cancels the prompt.Finally, if you’re a ctrlp.vim user (which you should be!), you can use this command to search tags in realtime. I use this often enough that I’ve bound it to
<leader>t
.Conclusion
You should now have a basic working knowledge of how to generate and view tags for Objective-C projects in Vim. However, there are many, many more commands available to aid in navigating your source with ctags. Give the
:help tags
page a read for more information.Ctags For Macbook
Additionally, it’s worth noting that there are a wide variety of user-contributed plugins that can aid your usage of ctags. Check out TagBar and EasyTags for viewing and maintaining your tags, respectively.
Vim Ctags Plugin
Shameless plug: If you’re a Vim user and iOS developer, you also may enjoy my vim-carthage plugin. Give it a shot!