2009-01-31

which function is this?

As a short tip: in many of the programming modes, you can get the name of the function where your cursor is currently in using which-function-mode. You can set it globally in your .emacs, or make it mode specific using some hook, for example:
(add-hook 'c-mode-common-hook 
  (lambda ()
    (which-function-mode t)))
After you do this, the name of the current function will appear in the modeline (the status-bar).

Now, apart from the mode line, emacs also knows the concept of the header line. This is the first line of the display; it seems little used. However, if you'd like to have the function name there, maybe because the mode line is full already, see this trick on EmacsWiki (scroll down).

which-function-mode does not work for all modes; it needs some help from the major mode to figure out what counts as a function; in my emacs, the following modes work (you can check from the which-func-modes variable):

(emacs-lisp-mode c-mode c++-mode perl-mode cperl-mode python-mode makefile-mode sh-mode
 fortran-mode f90-mode ada-mode diff-mode)

I hope your own functions do fit on your screen, making which-function-mode less needed -- function should not be too long or complex. But it's still useful when reading other people's code, of course. Note, there are other ways to not loose your orientation when reading code; earlier, we discussed hideshow, which enables showing/hiding the function bodies.

2009-01-28

drawing pictures

Even though we sometimes use words and sentences etc., many things are better expressed using pictures. Especially in technical discussions it's often useful to convey thoughts through various kinds of boxes and lines between them. For this, emacs has picture-mode. It's a bit hard to textually describe how to draw pictures in it, but a lot of it can be explained with the following little matrix (think of the directions on a compass).
NW
C-c `
N
C-c <UP>
NE
C-c '
W
C-c <LEFT>
  E
C-c <RIGHT>
SW
C-c /
S
C-c <DOWN>
SE
C-c \
The key pressed determines your typing direction; ie. type C-c ' and the some '/'-characters will get you a line to the upper-right (north-east).

This will be only available after you activate picture-mode, (M-x picture-mode). Now, because picture-mode is often used in combination with another (say, you want to draw a nice little ascii-art diagram in an e-mail), you can activate picture mode, do your drawing action, and then go back to the previous mode with C-c C-c. There are some more interesting commands; please see the emacs reference manual for details.

ditaa

Now, after you've written all these fine ascii-art diagrams, you might want to make them a bit more flashy for inclusing in another document. For that, there is Ditaa, which I learned from my dear colleague Stefan. Ditaa is a GPL Java program, that takes an ascii-art diagram, and turns it into something flashy. See below for an example; we take some simple ascii art, and ditaa turns it into the nice picture on the right:
                        
                              +----------+
          Drawing with        |cYEL   {s}|
            ditaa             +          +
                              | emacs fu |
                              +----------+
                                  ^  
                                  |  
    +--------+   +-------+    +-------+    
    |cGRE    |-->+ ditaa +--> |       |    
    |  Text  |   +-------+    |diagram|  
    |Document|   | magic!|    |       |    
    |     {d}|   |cBLU   |    | cRED  |    
    +---+----+   +-------+    +-------+     
        ^     
        |
    +--------+
    |cPNK{io}| 
    |  user  |
    +--------+
Ditaa is a bit slow, but the results are quite nice. You could run ditaa from within emacs with something like:
(setq ditaa-cmd "java -jar <path-to-ditaa>ditaa0_6b.jar")
(defun djcb-ditaa-generate ()
  (interactive)
  (shell-command
    (concat ditaa-cmd " " buffer-file-name)))
after which you can generate those pictures with M-x djcb-ditaa-generate. This is rather primitive of course. For example, it should be possible to integrate this with DocView (screencast), which is to be part of emacs 23. But this is left as an exercise to the reader...

artist-mode

There's another mode for emacs, called artist-mode, which is better suited when you want to express your emotions through art. It must be said, however, that it's often quicker to create some figures in artist-mode than in picture-mode; that's not really a problem, as you can switch between the two. There's a nice screen cast of someone using artist-mode to draw a linked-list in a code comment.

For artist-mode, the most important thing to remember is Shift + middle-click on your mouse to change the tool you are using. And see the picture, which is my interpretation of naïve art. My lack of talent, however, cannot be blaimed on artist-mode, I'm afraid...

2009-01-24

using d-bus: an example

In the previous entry, I mentioned Emacs version 23. This time, let's see what we can do with one of its new features: D-Bus-support. As you might know, D-Bus is an IPC system used on Linux/Unix to communicate between applications; it's a kind-of successor to systems like Bonobo (Gnome) and KParts (KDE). With support for D-Bus in Emacs, it's easy to control other applications. More and more programs are providing D-Bus interfaces.

As a semi-useful example of that, let's look at using D-Bus to control the Tomboy Note Taker application. Tomboy takes a novel approach (at least for me) at note taking -- your notes are connected like a wiki. Tomboy was originally designed and written by Alex Graveley, who has a talent for coming up with interesting ideas, and then turning them into software. Anyhow, I only use Tomboy as example of the use of D-Bus from emacs; there are many other interesting programs controllable through D-Bus.

Note, I won't discuss the details of D-Bus itself here; there's a lot of good material available already. Specifically, for some more background on using D-Bus with emacs, I can recommend the documentation (info-page) that comes with Emacs-23.

Back to Tomboy. First, let's make it easy to call Tomboy. It obviously assumes you have Tomboy installed, but it does not have to be running. First, a helper function that uses the new dbus-call-method-function, sets the service, path and interface names for Tomboy; this way, we don't have to specify them for each call:

(require 'dbus)
(defun djcb-call-tomboy (method &rest args)
  "call the tomboy method METHOD with ARGS over dbus"
  (apply 'dbus-call-method 
    :session                            ; use the session (not system) bus
    "org.gnome.Tomboy"                  ; service name
    "/org/gnome/Tomboy/RemoteControl"   ; path name
    "org.gnome.Tomboy.RemoteControl"    ; interface name
    method args))

Then, djcb-tomboy-create-note-region creates a new note from the region (selection) use CreateNamedNote and SetNoteContents; it even does some rudimentary error checking:

(defun djcb-tomboy-create-note-region (b e name)
  "Create a new note with in the Tomboy notetaker from region"
  (interactive "r\nsName for new Tomboy note:")
  (let ((note-uri (djcb-call-tomboy "CreateNamedNote" name)))
    (if (and note-uri (> (length note-uri) 0))
      (djcb-call-tomboy "SetNoteContents" note-uri 
        (concat name "\n" (buffer-substring b e)))
      (message "hmmm... it did not work. maybe try a different name"))))
With djcb-tomboy-insert-note-contents we can insert the contents of some tomboy note into the current buffer, using FindNote/GetNoteContents There's auto-completion available for the name of the note, using ListAllNotes:
(defun djcb-tomboy-insert-note-contents (name)
  "Insert Tomboy note with NAME"
  (interactive 
    (list (let ((lst))
            (dolist (uri (djcb-call-tomboy "ListAllNotes"))
              (add-to-list 'lst (djcb-call-tomboy "GetNoteTitle" uri)))
            (completing-read "Name of Tomboy Note:" lst))))
  (let ((note-uri (djcb-call-tomboy "FindNote" name)))
    (when note-uri
      (insert (djcb-call-tomboy "GetNoteContents" note-uri)))))

So, easy enough to do, even for an Elisp novice like myself. Again, this is more to show the use of dbus from emacs than about Tomboy itself -- but it is somewhat useful. I'm actually not using Tomboy so much anymore - org-mode better fits my emacs-centric workflow. But Tomboy has some very interesting plugins which might be nice for org-mode as well.

As I said before, Tomboy is only an example here -- there are many other D-Bus services available ('dbus-list-activatable-names') And D-Bus services are introspectable - you can search through them, and retrieve information about the interfaces they provide, as well as the methods and signatures. Again, the Emacs D-Bus infopages are quite useful.

2009-01-21

emacs 23

As per January 2009, the current stable version of GNU/Emacs is 22. However, there is a development version 23 available from CVS. The development version should become the next stable version in the not-too-distant future. I've been using emacs 23 for more than one year now, and have found it very reliable.

I'll be discussing some of the Emacs 23 specific tricks in some future entries, here I will discuss a small number of visible ones. This does not even scratch the surface of what is new - it's just a little taster.

One of the biggest, user-visible changes in Emacs 23 is the support for anti-aliased fonts on X11. This means that the fonts will look much smoother -- and as noted, users feel more effective when using pretty technology. In this case, some pictures are probably in order; the two screenshots show emacs-22 versus emacs-23, using default settings. The difference is striking, to say the least.

Emacs also supports variable-width fonts, so you could use any TrueType (and some other) font. However, I prefer to use a fixed-width font; a nice one is the Inconsolata font (ttf-inconsolata in Ubuntu/Debian, inconsolata-fonts in Fedora).

Another interesting new feature is DBUS-support; D-Bus is an IPC system used on Linux/Unix to communicate between applications. Using D-Bus, Emacs now even has support for querying the network for ZeroConf-devices when you are using Avahi; for example, insert a list of all printers in the local network into the current buffer, you could do something like:

(require 'zeroconf)
(zeroconf-init)
(dolist (srv (zeroconf-list-services "_printer._tcp"))
  (insert (format "\nprinter: %s" (nth 2 srv))))
Of course, this is not so useful. But being able to use Zeroconf (and D-Bus) easily from within emacs enables all kinds of interesting hacks... to be continued.

A maybe-useful graphical gimmick is that you can now change the 'opacity' (non-transparency) of your emacs frame (window) if you're on MS-Windows, or on some X with compositing enabled (Compiz, metacity-with-compositing, ...).

(modify-frame-parameters (selected-frame) 
  `((alpha . 90)))
will make your frame (window) 90% opaque (ie., 10% transparant).

If you're very conservative, you should of course wait for the official release of the new emacs. If you are a bit more adventurous, I can definitely recommend it. I have not come across any bugs. Of course, your mileage may vary.

The easiest way to get emacs 23 is to get some prebuilt packages;

  • For Windows, Ian Eure's MacOS-packages (haven't tested those);
  • For Debian, you can get emacs-snapshot-packages from orebokech, which are update weekly;
  • For Ubuntu, there are emacs-snapshot-packages from Ubuntu-Elisp
I guess there must be similar packages for Fedora/Suse/... but I could only find some older packages from EmacsCvsAndFedora. That says more about my searching skill than anything else, I guess... You can however also compile the new emacs yourself; it's not too difficult and there are some instructions in EmacsWiki, but note that the page is partly outdated.

Final note: if you have to have some emacs-23 specific code in your .emacs, but you also need emacs-22, you can use some like:

(when (>= emacs-major-version 23)
  ;; do something only in emacs 23
  )

2009-01-19

commenting your functions

When writing source code, it's nice to leave some comments, so others can understand what you were thinking. Of special concern is the documentation of public methods / functions -- that is, code that is designed to be used by other people. It's a far cry from Knuthian literate programming, but it's a start...

There are some systems to generate documentation (PDFs, html etc.) from these comments, such as JavaDoc, GTK-Doc and Doxygen. The idea is that your format your comments in such a way that these tools can understand them, and generate documentation from them. The details of this format are remarkably similar, at least between the systems mentioned here. Note that these are for C/C++ and Java; other languages have different systems.

I've found that I am much more likely to properly document my code when I have tools like the once discussed here. They take away enough of the boredom-factor to make me do it.

doxygen

I am mostly familiar with doxymacs, which is the system that adds support for Doxygen in emacs. In practice, this means that in doxymacs-mode, you can go to a function, press C-c d f (doxymacs-insert-function-comment), and a template with the arguments for this functions appears. For example, after doing this for frobnicate_numbers, we get:
/** 
 * 
 * 
 * @param a
 * @param b 
 * 
 * @return 
 */
int frobnicate_numbers (int a, int b);
Now, all we need to do is write some nice comments. Apart from a description and requirements for a and b, we should say something about the return value, if any values need to be freed, exceptions and so on. Note, I usually put the comments in the header file; that way, people can read the documentation by scanning the header files. Some people however prefer to put the comments in the implementation file.

Apart from the doxymacs-insert-function-comment mentioned above, there are also functions to include file comments (C-c d i, doxymacs-insert-file-comment) and others; see the doxygen documentation.

To install doxygen, get the package (for debian/ubuntu users: get the doxymacs-package), and then add to your .emacs:

(add-hook 'c-mode-common-hook
  (lambda ()
    (require 'doxymacs)
    (doxymacs-mode t)
    (doxymacs-font-lock)))
Of course, after nicely commenting your functions this way, you can create documentation for your code. For some example of this, see the KDE API documentation, which uses Doxygen.

I can recommend learning those keybindings; they are great timesavers.

gtk-doc

As an alternative, popular in the GLib/GTK+-world, there is GTK-Doc, which works in a very similar way. It can be a bit tricky to set up, but the integration with DevHelp is very nice -- and DevHelp you can be integrated with emacs. Anyway, GTK-Doc also provides some integration with emacs; so can get this by installing gtk-doc-tools, and then adding to your .emacs (assuming that gtk-doc lives in your load-path, see installing packages):
(add-hook 'c-mode-common-hook
  (lambda ()
    (load "gtk-doc")))
After that you can add comments to your functions with C-x 4 h ('gtk-doc-insert') in the gtk-doc format, which is slightly different from the doxygen one. (Gtk-Doc has special support for GTK/Glib-specifics but that's beyond my scope here...)
/**
 * frobnicate_numbers:
 * @a: 
 * @b: 
 *
 * 
 *
 * Returns: 
 **/
int frobnicate_numbers (int a, int b);

other

Finally, if you're programming Java, you'll be happy to hear that there is specific support for JavaDoc-style comments when you're using the excellent JDE (Java Development Environment). I haven't used it recently though, let alone its Javadoc support. So please refer to the documentation for details.

2009-01-17

balancing your parentheses

One of the biggests problems in the world today are unbalanced parentheses - i.e., an opening '(' without a corresponding ')'. Especially the closing ones are often forgotten, and not even the invention of :-) smileys has restored the balance. Fortunately, as with most problems, emacs has a solution: show-paren-mode.

show-paren-mode will visually indicate corresponding parentheses, so you are much less likely to forget them. Note that 'parentheses' are not just '()', but also '[]', '{}'; and others (for example, in html-mode, '<>' are also considered to be parentheses). Also note that 'parentheses' is the plural of 'parenthesis'.

Even without show-paren-mode, emacs gives small visual cues by temporarily moving the cursor to the opening parenthesis when it is positioned just after the closing one. What show-paren-mode does is to improve upon that, and decide exactly how that happens. This is best explained using an example; to put in your .emacs:

(setq show-paren-delay 0)           ; how long to wait?
(show-paren-mode t)                 ; turn paren-mode on
(setq show-paren-style 'expression) ; alternatives are 'parenthesis' and 'mixed'
This will enable show-paren-mode globally. The show-paren-delay determines how long to wait before any visual cues; if you set it to, say, 1, you won't see anything when you're quickly scrolling, but only after you're 'standing still' for a second.

Then, show-paren-style:

  • if you set it to 'expression, the whole expression will be highlighted - when your cursor is just before the 'world', you'll get:
    (hello)world
  • if you set it to 'parenthesis, only the corresponding parenthesis will be highlighted:
    (hello)world
  • finally, if you set it to 'mixed, it will behave like 'parenthesis when the matching parenthesis is visible, and like 'expression otherwise.
Now, of course it does not stop here. You can determine exactly what color, boldness, underline and other properties are used, by setting the faces that show-paren-mode uses. For example, if we add:
(set-face-background 'show-paren-match-face "#aaaaaa")
(set-face-attribute 'show-paren-match-face nil 
        :weight 'bold :underline nil :overline nil :slant 'normal)
This will give the whole expression a grayish background (the "#aaaaaa"), and makes it bold. There is lots of room for experimentation here, obviously. Note that show-paren-mode can also detect mismatches, e.g. when try to close a '(' with a ']'. You can tune this with show-paren-mismatch-face, e.g.:
(set-face-foreground 'show-paren-mismatch-face "red") 
(set-face-attribute 'show-paren-mismatch-face nil 
                    :weight 'bold :underline t :overline nil :slant 'normal)

2009-01-14

mutt inside emacs

There are some emacs-native programs for e-mail, such as gnus, vm and a couple of others. I never really got into them for some reason; I found them rather hard to set up and a bit counter-intuitive. Maybe I should give them another try, but for the last decade, I've been using the mutt console e-mail client - even with graphical alternatives like Evolution and Thunderbird available.

mutt is not perfect -- you cannot read older e-mails when composing a new one (without starting a new instance) and the macro language is a joke compared to elisp. Still, because it's totally keyboard-driven, I'm really efficient with mutt. Side note: if you need quick searching capability which can be integrated with mutt, see my mu search tool.

Mutt does not have a built-in editor -- instead, it relies on an external program. Obviously, I use emacs for that. Now, I don't want to start a new emacs for each new message that I write; instead I make use of the emacs server functionality. Practically, we can start an emacs server by adding to .emacs:

(server-start)
Now, we can open files in the existing emacs by calling emacsclient instead of emacs; and tell mutt to use that editor. Put in your .muttrc:
set editor="emacsclient +8 %s -a emacs"
This opens new messages in an existing emacs, and put the cursor on line 8 (after the mail headers). If no emacs is running yet, a new one will be started, due to the '-a'-argument.

This solution will work nicely, but requires you to start mutt in a console, and start emacs in a separate window. I prefer, however, to run everything inside emacs. This can easily be done - please look at the 'running console programs inside emacs'-entry again, to create a short-cut.

Now, when editing e-mail messages, it's nice to use one the special modes for that; they provide some interesting 'syntax highlighting' to your mail. You can use mail-mode, or my favorite, post-mode. To automatically use it, download and install it, and add some code to your .emacs:

(autoload 'post-mode "post" "mode for e-mail" t)
(add-to-list 'auto-mode-alist 
             '("\\.*mutt-*\\|.article\\|\\.followup" 
                . post-mode))
This will automatically load post-mode when editing a message from mutt (and for some other programs). You might also want to set up some other things when editing mails, using a hook:
(add-hook 'post-mode-hook 
  (lambda()
    (auto-fill-mode t)    
    (setq fill-column 72)    ; rfc 1855 for usenet messages
    (require 'footnote-mode) 
    (footmode-mode t)
    (require 'boxquote)))
Obviously, you need to install the boxquote and footnode modes, if you want to use those.

Final note: this same setup works nicely for the slrn news reader as well; just use the set editor_command= in your .slrnrc.

2009-01-13

counting words

Emacs has many obscure functions (M-x phases-of-moon...) - but a function to count words is missing. So, every Emacs user, at one time in their life, wants to write their own version. So here is mine -- inspired by the version of Rudolf Olah.
(defun djcb-count-words (&optional begin end)
  "count words between BEGIN and END (region); if no region defined, count words in buffer"
  (interactive "r")
  (let ((b (if mark-active begin (point-min)))
      (e (if mark-active end (point-max))))
    (message "Word count: %s" (how-many "\\w+" b e))))
The difference between this one and many others ones is that it uses the how-many function that returns the number of matches; this simplifies things quite a bit. I changed Rudolf's version in that it counts the words in the region (selection) if you have one, otherwise, use the whole buffer.

Now, as an exercise to the reader: implement a similar function to determine the Flesch-Kincaid Readability Tests (Reading Ease and Grade Level). Good luck!

2009-01-09

the kill-ring

Last time, I discussed registers, and mentioned the kill-ring. The kill-ring is the 'normal' clipboard emacs uses for cut/copy/paste of text. The cool name comes from the fact that in emacs terminology, 'killing' means what 'cutting' means in many other programs. The kill-ring contains the cut (and copied!) text parts; cut-copy-paste have their own entry.

As mentioned in the registers entry, many programs only allow you to paste the last copied/cut text block, and that is what the kill-ring does by default (when you press C-y). However, you can choose older ones using the menu (Edit/Paste from kill menu). Alternatively, you can use a prefix key (e.g., M-3 C-y will insert the third most recently killed ('cut') text).

The kill 'ring' behaves mostly like a list; by default (emacs 22, 23) there are 60 positions available in the ring, after which older entries are thrown away. You can put (setq kill-ring-max 120) in your .emacs in the unlikely case that 60 is not enough.

Update:An anonymous commenter mentions the useful M-y ('yank-pop') key binding, which lets you cycle through the items in the kill-ring. Quite useful indeed, thanks!

If you're using the GTK+-version of emacs (the graphical version in X/Linux/Unix environments), you can even have the Edit/Paste from kill menu-menu in a separate frame (window), and paste text by clicking there. To this, go to the menu Edit/Paste from kill menu, and click on the dotted line at the top of the sub menu.

2009-01-07

using registers

UPDATED Emacs is full of wonderful features, but sometimes it takes some time to find them. Today, let's discuss one such feature, registers. Registers are dicussed in the Emacs Manual, but it took me quite some time before I understood what they're good for. So let me discuss them here - maybe I am not the only one.

To explain the use of register, let's look at the normal cut-copy-pasting of text first. When you have cut or copied some text, it lives in a place we call the clipboard, from with you can then paste it. But in most programs, if you copy/cut text again, it replaces what was already on the clip board.

Now, what about registers? In emacs, we have a special clipboard with multiple places to store things, each named by a single number or letter. We call these places registers. Thus, you can save some text to register A, some other text to register B, and later paste the contents of register A or B. The key bindings (shortcuts) for this are good to remember:

C-x r s Rsave region (selection) into register R
C-x r i Rinsert the contents of register R
So, to save the current region/selection in register 2, you would type: C-x r s 2, and to insert the contents of that register later, you'd do C-x r i 2. It's a really useful thing to add to your emacs muscle memory.

(Note: the clipboard that emacs uses for 'normal' cut/copy/paste, the 'kill-ring', allows for multiple (but unnamed) entries as well - but we'll discuss the kill-ring in some other entry.)

viewing register contents

One obvious problem with registers is that for most people it's very hard to remember what went into which register, if you use more than two or three registers. There is M-x view-register, but that's only marginally useful. It would be much nicer if we could get a list of all registers in use and a preview of their contents. To do that, we can use the list-register.el package (see installing packages). The package adds a function list-registers (and some others). I use a key binding C-x r v for that, which somewhat logically follows the other ones:
C-x r vview registers
(require 'list-register)
(global-set-key (kbd "C-x r v") 'list-register)
An alternative would be to use C-x r l (for list registers), but that one has already been taken by bookmark-bmenu-list, which shows a list of your bookmarks -- to be discussed some other time).

I would vote for including the list-registers functionality in emacs. Having registers without a way to view them, makes them much less useful.

more than words

Personally, I seldomly use registers for anything but text; however, you can store other things in registers as well (see the Emacs Manual registers section for details):
objectstoreretrievenotes
rectangleC-x r r RC-x r i R save rectangle into register R (see working with rectangular selections, and insert it);
buffer/positionC-x r <SPC> RC-x r j Rsave buffer/position in register R, and jump back to it
windowC-x r w RC-x r j Rsave window configuration in register R, and jump back to it. Note that what emacs calls a window is called a window pane elsewhere, see emacs terminology)
frameC-x r f RC-x r j Rsave frame configuration in register R, and jump back to it. Note that what emacs calls a frame is called a window elsewhere, see emacs terminology
As you can see, some of the objects share the keybinding for retrieving them. In other words, what happens when you retrieve register R depends on the type of object you put in there before.

While registers are quite useful, I think they would be easier to use if they were integrated with the normal cut-copy-paste (the 'kill-ring'). Another issue is that you cannot access your registers from other programs. Actually, recent MS-Office versions do this in a bit nicer way...

2009-01-05

navigating through source code using tags

[Updated] I was always amazed by the way emacs gurus navigated through source code. It almost seemed like magic. They see some function call, and then with some short keyboard combo jump to another file, on the exact place where the function was defined.

The 'magic' in this case is a tag file. A tag file is a file that maintains an index of all the symbols in source code, where they are used and where they are defined. If you use grep and the like to look for things, you'll find tag files very useful.

There are different programs to create and deal with tag files; emacs ships with etags and there's also ctags. I'm not too familiar with those systems, but instead rely on GNU-Global for my tagging needs; it's available for Unix-like systems. The instructions below assume that you have installed GNU-Global.

tags from the command line

First, let's see how to create and update a tag file from the command line. GNU-Global works recursively on a directory tree; that is, you can run it in the top of your source directory, and it will then index all the files found, traversing through subdirectories. To create a tag file, go to the top of your source tree and run:
$ gtags
This will create a bunch of files (GPATH, GRTAGS, GSYMS and GTAGS) that together form your tagfile. If you have run gtags before, and only want to update for changes in your source files, run:
$ global -u
This is usually much faster than running gtags. Also note that you can run this from anywhere in your source tree. The program will locate the G*-files by itself.

After that, you can search for symbols etc from the command line; please refer to the global man page for details. However, let's see how we can do all that from within emacs.

Using GNU-Global from emacs

GNU-Global comes with support for emacs, which makes it very convenient to use. It still relies on the command line to use create / update the tagfiles though; but we can do something about that with a bit of elisp. First, we define the following function djcb-gtags-create-or-update in our .emacs:
(defun djcb-gtags-create-or-update ()
  "create or update the gnu global tag file"
  (interactive)
  (if (not (= 0 (call-process "global" nil nil nil " -p"))) ; tagfile doesn't exist?
    (let ((olddir default-directory)
          (topdir (read-directory-name  
                    "gtags: top of source tree:" default-directory)))
      (cd topdir)
      (shell-command "gtags && echo 'created tagfile'")
      (cd olddir)) ; restore   
    ;;  tagfile already exists; update it
    (shell-command "global -u && echo 'updated tagfile'")))
This function will check if there is an existing tagfile; if so, it will update it. If not, it asks where to create the tag file; you should provide the name of the top of your source directory there.

Now, we can automatically run this function whenever we open a C/C++/...-file, so we always have an up-to-date tagfile available:

(add-hook 'gtags-mode-hook 
  (lambda()
    (local-set-key (kbd "M-.") 'gtags-find-tag)   ; find a tag, also M-.
    (local-set-key (kbd "M-,") 'gtags-find-rtag)))  ; reverse tag

(add-hook 'c-mode-common-hook
  (lambda ()
    (require 'gtags)
    (gtags-mode t)
    (djcb-gtags-create-or-update)))
I've found GNU-Global fast enough to run djcb-gtags-create-or-update automatically. However, if you work with really huge code bases (for example, the linux kernel sources) it's better to use a tag file for some not-too-big sub-tree, or turn tagging off. To turn off automatic updating/creating tagging for some particular directory, you could do something like: [Update: fix elisp error, thanks Anatoly]
(add-hook 'c-mode-common-hook
  (lambda ()
    (require 'gtags)
    (gtags-mode t)
    (when (not (string-match "/usr/src/linux/" (expand-file-name default-directory)))  
      (djcb-gtags-create-or-update))))
instead of the above add-hook. You can then still run djcb-gtags-create-or-update by hand for some particular subdirectory.

usage

Now, having done all this, tagging is quite easy - and quickly through your source code is even easier. To find the definition of a function (or symbol), type M-. (Alt + dot). If your cursor is on a function name (or on other symbol), it will be the default target. Otherwise, you type the name; autocompletion is available with the Tab-key.

If you want to do the reverse, ie. finding all the uses of a certain symbol, use M-, (Alt + comma) and we get a list of locations. There are some more functions available, all starting with gtags-; see the built-in documentation for details.