RTags is a client/server application that indexes c/c++ code and keeps a persistent in-memory database of references, symbolnames, completions etc. It allows you to find symbols by name (including class and namespace scope), we integrate with dabbrev for intelligent completion (we could integrate with ‘autocompletion but honestly, if you want that, Qt Creator, Eclipse and Visual Studio has your back). Most importantly we give you proper follow-symbol and find-references support.
While existing taggers like gnu global, cscope, etags, ctags etc do a good job for C they often fall a little bit short for C++. With its incredible lexical complexity parsing C++ is an incredibly hard task and we make no bones about the fact that the only reason we are able to improve on the current tools is because of clang (http://clang.llvm.org/). RTags is named rtags in recognition of Roberto Raggi on whose C++ parser we intended to make this project but he assured us clang was the way to go. The name stuck though.
RTags is meant to be used like this:
rdm runs in the background and monitors all your indexed files for changes and reindexes when a source file or one of its dependencies is modified.
To get information about a symbol or find references to it you would use the command line client rc.
E.g.
$ rc --follow-location Job.cpp,400 /home/abakken/dev/rtags/src/Job.h,2186 List<RegExp> *mPathFiltersRegExp;
We maintain a set of elisp bindings so you don’t acually have to call this yourself but we feel that this architecture allows us to add bindings to other editors (like vim) at a later point.
Since clang requires us to really compile the file we need to know the actual c(xx)flags for parsing the source files. In essence RTags indexes all the source files it has been told about and all the headers included by these source files. To tell rtags about a source (you only need to do this once, after that it will monitor the file for changes using inotify/kqueue) you need call this command:
$ rc --compile "gcc -W... -I... -D... source.c"
One could do this manually or script some per/project parsing of Makefiles/CMakeLists.txt/etc but the way we normally recommend doing it is like this:
$ ln -s /path/to/rtags/gcc-rtags-wrapper.sh /somewhere/that/is/in/your/path/before/usr/bin/gcc $ ln -s /path/to/rtags/gcc-rtags-wrapper.sh /somewhere/that/is/in/your/path/before/usr/bin/c++ $ ln -s /path/to/rtags/gcc-rtags-wrapper.sh /somewhere/that/is/in/your/path/before/usr/bin/cc $ ln -s /path/to/rtags/gcc-rtags-wrapper.sh /somewhere/that/is/in/your/path/before/usr/bin/g++ $ ls -la | grep wrapper lrwxrwxrwx 1 abakken abakken 44 Jan 12 15:37 c++ -> /home/abakken/dev/rtags/gcc-rtags-wrapper.sh lrwxrwxrwx 1 abakken abakken 44 Jan 12 15:37 cc -> /home/abakken/dev/rtags/gcc-rtags-wrapper.sh lrwxrwxrwx 1 abakken abakken 44 Jan 12 15:37 g++ -> /home/abakken/dev/rtags/gcc-rtags-wrapper.sh lrwxrwxrwx 1 abakken abakken 44 Jan 12 15:37 gcc -> /home/abakken/dev/rtags/gcc-rtags-wrapper.sh
This script will essentially stick itself in the middle of your compiles and notify rtags that you want this file indexed and then invoke the next entry in the $PATH that matches $0.
RTags will group source files into projects based on some heuristics.
Essentially it will look for certain files/dirs (like configure/CMakeLists.txt/scons.1/.git) etc to try to determine the likely project root for each source file. For generated source files that end up in the build dir we try to find the source root based on similar heuristics around config.status/CMakeCache.txt etc. Usually this works out reasonably well.
RTags’ only gives you information about current project when you ask for things by name. You can explicitly change the current project using:
$ rc -w foobar
The emacs integration tries to do it automatically for you.
RTags keeps a cache of indexed data so you don’t have to reindex everything if you restart it. The location of this data is by default ~/.rtags but can be overridden by passing –data-dir /other/dir to rdm.
RTags also maintains a list of active projects It also maintains an ini-format file for which projects currently are indexed that by default sits in ~/.rtagsprojects.
Building rtags:
cd /path/to/rtags cmake . make 3rdparty # This step will take quite a while. It will download trunk of clang and llvm and build it make export PATH=/path/to/rtags/src:$PATH ln -s /path/to/rtags/gcc-rtags-wrapper.sh ~/bin/c++ ln -s /path/to/rtags/gcc-rtags-wrapper.sh ~/bin/cc ln -s /path/to/rtags/gcc-rtags-wrapper.sh ~/bin/g++ ln -s /path/to/rtags/gcc-rtags-wrapper.sh ~/bin/gcc rdm & # This starts the rtags daemon
Add something like this to your .emacs:
(add-to-list 'load-path "/path/to/rtags")) (require 'rtags)
Or something to that effect.
To enable the standard keybindings (using a prefix of C-x r) you could call something like this:
(rtags-enable-standard-keybindings c-mode-base-map)
There are lots of interactive functions to call but the most important ones are:
(rtags-find-symbol-at-point) ;; follow symbol under cursor (rtags-find-references-at-point) ;; find all references to symbol under cursor (rtags-find-symbol) ;; prompt for name of symbol to go to (rtags-find-references) ;; prompt for name of symbol to find references to
Here are some videos demonstrating how to use rtags with emacs:
Find symbol/references under cursor: http://youtu.be/k4driyVYSRU
Find symbol by name: http://youtu.be/DUkT3CCpHVw
RTags is still in development and is not the most stable piece of software you’ll ever find. We crash sometimes (though admittedly mostly inside clang). We’re constantly working to improve on it.