Grepping Cross References
This tool is like lxr, except it works for most programming languages (as many as supported by ctags-exuberant) and allows you use it in Emacs/Vim instead of a browser.
See some screenshots for c++, python, and shell script (click to view in the original size):
Here I'll explain some of its features and how it works.
1 It's very fast
Because beagrep is being used, which can grep 2G source code in 0.23 second.
For e.g., when checking cross references for MockZip
, first we use
beagrep to find out the (tiny) set of files and line numbers on which
this word occurs. Then we work on these files only.
2 It support most programming languages
Because ctags-exuberant is used.
Given the small set of files containing MockZip
, we use
ctags-exuberant to tag each of these files, then compare line
numbers. If MockZip
occurs on line 88, then the last tag before line
88 is referencing MockZip
.
3 It removes false positives
Currently it can take 2 arguments --nc
(no comment) and --ns=
(no
string) to ignore where MockZip
occurs inside a comment or string
literal.
4 It reuses grep output format
For easy integration with Emacs's grep-mode. Or vim's handling of grep output.
5 It's not perfect
But good enough (at least for me:-)
6 How to use it
- Install beagrep and ctags-exuberant.
- Download and get the package from gxr.
- In your gxr checkout:
cp .globalrc ~ cp $(find . -maxdepth 1 -type f -executable) ~/system-config/bin # or some other dir in your PATH
mkdir ~/.logs
- Create beagrep index in your source tree.
grep-func-call -e MockZip -a --nc --ns
- File a bug on the github project:-)
Here are the arguments:
- -e pattern
- PATTERN is a perl style regexp. When you want to
find only those cross references where a var named
my_var
is assigned a value, use a pattern likemy_var\s*=[^=]
.\b
is added when appropriate, so that a pattern ofmy_var
will not findmy_var2
because I do myself a favor by changing the pattern to\bmy_var\b
. If I also wantmy_var2
I can usemy_var2?
. - -a
-a
is a toggle switch, one-a
will search in all source files, two (even number of)-a
will search only in the file$GTAGS_START_FILE
(the file my Emacs's current buffer is visiting, I added a hook in grep, the current buffer's file will be exported to the environment variable).(defun set-gtags-start-file () (let ((file (ajoke--buffer-file-name (current-buffer)))) (if (file-remote-p file) (let ((process-environment tramp-remote-process-environment)) (setenv "GTAGS_START_FILE" (file-remote-p file 'localname)) (setq tramp-remote-process-environment process-environment)) (setenv "GTAGS_START_FILE" file))))
Always use
-a
if you are not sure of my hack.
- –nc –ns
- These has been explained above.