How to use ctags with Emacs effectively
UPDATE on counsel-etags, a complete solution for Ctags/Emacs.: I released
See http://emacswiki.org/emacs/EmacsTags for general usage of tags file. A file name of tags files is
TAGS by default. But in Emacs manual the
tags file is named
tags table. Either
tags file or
tags table or
TAGS is only different name for the same thing.
According wiki page, people usually use ctags to do two things,
- Code navigation
In my opinion, ctags is OK for code navigation because it's integrated into Emacs well and ctags supports more programming language. But ctags only uses regular expression to analyze the code. So it's not as precise as professional tools like cscope or GNU Global. According to my own experience, ctags plus grep is actually good enough for code navigation in big enterprise projects with mixed environments. If you are among a few talented geeks who are developing Linux Kernel in the most efficient way, you should use better tools like GNU Global. See the head up from Nick Alcock. His summary of the Pro/Con of GNU Global is great.
My typical work flow is:
- Load the tags file for my own code.
- Load other tags files built from third party libraries related to my current task.
- Unload third party tags immediately if its not needed.
The purpose to load tags files is to look up API easily. For example, I use C++ library wxWidgets to develop my application. I want to use its API called
wxWindow::Maximize. I type
M-x find-tag and input the keyword
Maximize. So I can check the function definition and know what parameters I need fill in to use "Maximize".
Produce tags files for all the environments
For example, I produce tags files of Library A for Mac and Linux. I put tags file from Mac at directory "/home/cb/tags/Library_A/mac" and file from Linux at
Use git and github to manage the tags files
So I can have copies of the tags files at github server and my local computers. That's also a part of my strategy to setup the development environment. My projects on different computers usually use same external library.
EmacsWiki discusses how to update your tags file frequently because your own code are updated frequently. But the tags file from a big library like wxWidgets need not be updated to often because I only use limited old APIs in that library.
Write emacs lisp code to load/unload these tags files
Here is the code. In this example, if I need load tags file for wxWidgets, I call the function "add-wx-tags". If I need unload the tags file, I press "Ctrl-u" and call the same function "add-wx-tags". Since I use Smex, calling function doesn't mean pressing many keys.
; Set up tags built from third party libraries ===begin ; define tags alias like "wx-tags" here (setq wx-tags (expand-file-name "~/tags/wx/osx/TAGS")) ; @see <Selecting a Tags Table> in Emacs manual for details. ; We only change the list "tags-table-list". It is documented officialy. (defun insert-into-tags-table-list(e) (add-to-list 'tags-table-list e t)) (defun delete-from-tags-table-list (e) (setq tags-table-list (delete e tags-table-list))) ; This is a sample command, all you need is copy/paste this template ; for other new commands (defun add-wx-tags (&optional del) "Add or delete(C-u) wxWidgets tags into tags-table-list" (interactive "P") (let (mytags) ; here add your third party tags files ; Usually you need load/unload tags files combination in one command ; change below line to add them (setq mytags (list wx-tags)) (if del (mapc 'delete-from-tags-table-list mytags) (mapc 'insert-into-tags-table-list mytags))))
This solution only uses one standard variable
tags-table-list in Emacs. So it will always work with any other Emacs plugins you install. And you can use all the old hotkeys and functions ("find-tag", for example) without any problem.
See Emacs manual for technical details.