Source code browsing using GNU ID and Emacs

Source code comprehension programs are amongst the most important tools that every software developer needs to master. Using these tools in an integrated way from the comfort of you favourite editor is important to minimise the context switches that kill the developer’s productivity (you know, “the zone…”).

Here it is a short HowTo on how I use GNU ID Utils from Emacs. This assumes some Linux/Debian derivative (in my case Ubuntu 12.04) and a C/C++ project, but other languages like Perl or Java are also supported by GNU ID.

Verify that the id-utils Debian package is installed

$ dpkg -l | grep id-utils
ii  id-utils  4.5-3  Fast, high-capacity, identifier database tool

Alternatively, install it

$ sudo apt-get install id-utils

Download idutils.el and put it somewhere in your Emacs search path

The idutils source distribution comes with idutils.el, an Emacs interface to gid, the utility that comes with idutils and that let’s you query the ID database from the command line. At the time of writing, 4.6 is the latest version of the idutils package. However, it probably is safer to use the idutils.el from the same release as the idutils package installed on your system (in my case that is 4.5).

$ cd ~/temp
$ wget http://ftp.gnu.org/gnu/idutils/idutils-4.5.tar.xz
$ xz -d idutils-4.5.tar.xz
$ tar xvf idutils-4.5.tar
$ cp idutils-4.5/lisp/idutils.el "somewhere where emacs can find it"

Update your Emacs config

Add the following to your dotemacs file:

;; Emacs GNU ID utils interface
;; M-x gid to run the command
;; more info at http://www.gnu.org/software/idutils/manual/idutils.html
(autoload 'gid "idutils" nil t)

Build the ID database

The next step is to run mkid to build the identifier database. The following commands will produce an ID file in you project’s root directory. This will index your system headers as well as your project’s source code. E.g.:

$ cd "your favorite project"
$ mkid -s /usr/include/ .

Run gid from within Emacs

Open up any source file from your project, point your cursor at some identifier and run M-x gid. Emacs will ask you something like this:

Run gid (with args): thread_mutex_create

Just hit enter and Emacs will bring up a *compilation* buffer with the results:

-*- mode: gid; default-directory: "/home/juanrubio/3rdparty/icecast/src/" -*-
Gid started at Wed Apr 10 12:57:01

gid thread_mutex_create
thread/thread.h:104:#define thread_spin_create(x)  thread_mutex_create(x)
thread/thread.h:111:#define thread_mutex_create(x) thread_mutex_create_c(x,__LINE__,__FILE__)
thread/thread.h:136:# define thread_mutex_create_c _mangle(thread_mutex_create)
auth.c:683:        thread_mutex_create (&auth->lock);
cfgfile.c:94:    thread_mutex_create(&_locks.relay_lock);
connection.c:147:    thread_mutex_create(&move_clients_mutex);
format_mp3.c:122:    thread_mutex_create (&state->url_lock);
global.c:45:    thread_mutex_create(&_global_mutex);
slave.c:139:    thread_mutex_create (&_slave_mutex);
source.c:106:        thread_mutex_create(&src->lock);
stats.c:134:    thread_mutex_create(&_stats_mutex);
stats.c:138:    thread_mutex_create(&_global_event_mutex);
stats.c:864:    thread_mutex_create (&(listener.mutex));
util.c:719:         thread_mutex_create (&localtime_lock);
xslt.c:101:    thread_mutex_create(&xsltlock);
yp.c:282:    thread_mutex_create (&yp_pending_lock);
net/resolver.c:41:#define thread_mutex_create(x) do{}while(0)
net/resolver.c:206:        thread_mutex_create (&_resolver_mutex);
thread/thread.c:164:    thread_mutex_create(&_threadtree_mutex);
thread/thread.c:165:    thread_mutex_create(&_library_mutex);    

Gid finished at Wed Apr 10 12:57:01

The results can be navigated with the usual Emacs commands M-x next-error and M-x previous-error, (usually assigned to M-g n and M-g p)

Similar tools

There are a number of other source browsing/navigation tools that are specific for Emacs or that also integrate well with Emacs, some of them are: