Ross Wolin - last updated 2013.03.05
I am a big fan of Source Insight for code browsing... when I'm working on Windows. I have also heard people use newer versions of Visual Studio w/ intellisense. Unfortunately neither program runs on Linux.
My goal was to find a simple source browsing solution for C/C++ and Java that runs roughly the same on Linux, Windows, and OSX.
I'm partial to Emacs as a universal platform editor.
Yes, you with your hand up in the back? Yes, using ECB and CEDET/Sematic/EDE/Senator I think you can probably do everything in my list. However, when I set up ECB+CEDET, I found CEDET overwhelmingly complex, and a tad slow. It's very possible I didn't have them set up correctly, didn't spend enough time with the configuration, etc. Couple that with the problem that the included version of CEDET didn't seem to work right with ECB, forcing me to disable the included version, then download/set up ECB and CEDET manually... I spent more time trying to make that setup work than I'd like to admit, I did get it to work somewhat, but ultimately I wasn't that satisfied with the results. =)
This article details a simpler solution, using Emacs in combination with GLOBAL and Speedbar for code browsing.
I'm going to assume you already have Emacs installed, and recent versions of Emacs include Speedbar as part of CEDET. If you don't have GNU Global, on a Debian based Linux system you can install that via:
apt-get install global
Start by adding a few lines to your init.el to do a basic setup for Global.
First, tell Emacs where your gtags.el file, if it is someplace other than the standard macro directory. (I installed Global via apt-get on Debian, and the gtags.el was in /usr/share/emacs/site-lisp/global, so I didn't need to modify the load-path)
(setq load-path (cons "/path/to/gtags.el" load-path))
Next, tell Emacs to load gtags on start-up:
(autoload 'gtags-mode "gtags" "" t)
The next part is preference. If you would like Emacs to go into gtags mode whenever you enter c mode, add the following section. (If instead you would rather control when gtags mode starts, omit this section and turn on gtags mode when you want it, via M-x gtags-mode)
(add-hook 'c-mode-hook '(lambda () (gtags-mode t) ))
Note: I have actually set Emacs to use c++-mode even when I am editing C files. If you've done that, then you want to add-hook to c++-mode-hook rather than c-mode-hook)
Additional, I like to have Speedbar start when I run Emacs. To do that, add the following section to init.el. (If you want to start Speedbar manually instead, omit this and use M-x speedbar
; Start speedbar automatically if we're using a window system like X, etc (when window-system (speedbar t))
The simplest way to make a set of tags is to go to the top directory in your source tree and run
gtags -v
This will recursively tag all the files in the tree, including C, C++, Java, PHP, assembler, and YACC source files.
If you wish to limit the files Global tags (or add more) look in the Global documentation, including the settings in the ~/.globalrc config file.
This simple script is something I used for an ARM Linux kernel source project, to specify which parts of the source tree I want to tag. It uses gtag's -f option to read the list of files to tag from a file.
#!/bin/bash rm .files2gtag for f in block crypto Documentation drivers firmware fs include init ipc kernel lib \ mm net samples scripts security sound tools usr virt do find $f -iregex '.*\(c\|h\)' >>.files2gtag done for f in boot common configs include kernel lib mach-dove mm nwfpe oprofile \ plat-orion tools do find arch/arm/$f -iregex '.*\(c\|h\)' >>.files2gtag done gtags -v -f .files2gtag
Place the cursor on the function name and run
M-x gtags-find-tag
to jump to the function's defintion.
This function is also bound to M-. key combination.
Place the cursor on a symbol name and run
M-x gtags-find-symbol
to jump to the symbol's defintion.
This function is not bound by default, you could bind it a key in your init.el, etc.
The middle mouse button is somewhat of a context sensitive version, it runs an Emacs function called gtags-find-tag-by-event which either runs gtags-find-tag or gtags-find-symbol, depending on if you click on a function name or a symbol. (I might be tempted to bind this to a key combination also...)
TO DO: would be nice to know how to limit symbol definition by scope, if possible
After jumping to a function, symbol, or references buffer, you can return back to where you jumped from using the M-x gtags-pop-stack function.
This function is bound to M-* key combination, as well as the right mouse button.
Place the insertion point (i.e. the cursor) on the function name in the code, and run
M-x gtags-find-rtag
Speedbar will do this for you (click image to expand)
To start Speedbar, use: M-x speedbar
or you can start Speedbar in your init.el with:
(when window-system ;start speedbar if we're using a window system like X, etc (speedbar t))
(Probably a good idea to not start Speedbar if you are running console Emacs =)
Once Speedbar is running, you might want to make sure "Auto Update" is turned on. (Right click in Speedbar, it's on the menu)
TO DO: It would be cool to have Speedbar automatically expand only the current file's functions...
Emacs will show the current function name within a file when "which function mode" is enabled. (The name is displayed on the right side of the status bar.)
Toggle this mode from the command line with: M-x which-function-mode
Enable it at startup via your init.el with:
(which-function-mode 1)
Run find in files with the Emacs command:
M-x find-grep
You could also bind find-grep to an Emacs key (i.e. Shift+F3 in this case) in your init.el with:
(global-set-key [S-f3] 'find-grep)
I tweaked the find-grep command to work more to my liking, by adding this line to init.el:
(setq grep-find-command "grep -rnH --exclude=.hg --include=\*.{c,cpp,h} --include=-e 'pattern' ~/src_top/*")
When you invoke find-grep, you cursor to where 'pattern' is and change it to your search regex. You can also change any of the other parameters. Next time you run the command, you can arrow up through the command history if desired.
While the grep results buffer exists, you can jump forward (M-g M-n) and backward (M-g M-p) among the items in the list.
This section binds find-grep to Shift+F3 all the time. You can obviously do more sophisticated stuff like in a mode hook limit the bind the key based on mode, write a function that pulls the selection from the point into the pattern, asks for the pattern, etc.
Note: find-grep will search ALL the files recursively, not just the ones that are tagged by Global.
The gtags-find-pattern command is also useful, as it will search all the tagged files for a regular expression.
There is also gtags-find-with-grep, I THINK THESE ARE THE SAME COMMAND, VERIFY THIS.
TO DO: How to update tags as files are changed in emacs? Might be possible to run with -u for incremental update?
Speedbar/CEDET
Speedbar - Emacs Wiki
GNU Global Source Code Tag System, section 3.6, Extended Emacs using GLOBAL
Send comments, questions, money in large denominations, etc to android at wolinlabs.com
If you enjoyed this article, please consider buying my products ...
ATX PS Adapter
Use an ATX PC power supply as a 5V, 3.3V, and +12V/-12V bench supply the easy way, without cutting the case or mounting external connectors, resistors, LEDs, switches, and fuses. Provides visual indication when supply is plugged in and turned on, also fuses the power voltage outputs for safety. Run USB powered development boards via the USB connectors on the 5V line. |
Ultimate Serial Port (Debug Buddy)
USB serial port with standard, 5V and 3V RS232, plus integrated null modem and gender changer. Implements TX/RX and RTS#/CTS# for optional hardware handshake. Also includes 3.3V<->5V level shifters, debug LEDs, and 13 clock sources. Valuable tool for hands on problem solving and hacking |