isymchoose - interactive symbol search and complete for C code
isymchoose [OPTION]... CFILE REGEX
isymchoose is a sort of combination symbol completer/interface explorer/help browser for C language programing. It is primarily intended to be run by editors or other programming tools. See the EDITOR INTEGRATION section for some canned integration solutions for emacs and vim.
isymchoose uses the Makefile (and some minimal assumptions about its contents) in a project directory in combination with a CFILE and perl-compatible REGEX to produce a list of candidate symbols available in the context of CFILE (i.e. symbols declared in the headers #include'ed). The list may then be subjected to further interactive filtration and help browsing, and finally one element of it selected. The selected symbol is then printed out, possibly together with its argument list and return type.
In short: probably nothing your project doesn't already do. The exuberant ctags program (http://ctags.sourceforge.net/) must be available. You will almost certainly want EDITOR INTEGRATION.
In more detail:
isymchoose works by creating a temp_makefile that by default looks about like this:
include /your/project/dir/Makefile
CPPFLAGS += -E -M -MP -MF dep_list_temp_file
CFLAGS += -E -M -MP -MG dep_list_temp_file
If the GNU autotools (autoconf and automake) are being used, these flags usually end up being mostly redundant with or overridden by the ones provided by the autotools. The isymchoose program knows how to react in case this happens.
These additions to the CPPFLAGS and CFLAGS Make variables should ultimately end
up telling gcc to produce header dependency information and not actually
compile anything. So then we (more or less) run make -f temp_makefile
cfile.o, parse the result, run the ctags program on all the depended-on
headers, and cache as much information as possible to make subsequent
executions that share some or all of the context faster.
So: your project must have a Makefile (though you can use --makefile to
specify its name if it isn't 'Makefile'), and the rules that specify how .o
files are produced from .c files must incorporate one or both of the
CPPFLAGS or CFLAGS make variables (unless the
--cpp-options-var option is used), and the compiler must understand the
above options. Note that the implicit Make rule often used to compile C
files:
$(CC) -c $(CPPFLAGS) $(CFLAGS)
meets these requirement as long as $(CC) ends up meaning something gccish. Also, the C preprocessor must not get confused trying to parse your source (it gets confused much less easily than the later compilation stages, usually working even for files that are in the middle of complicated changes).
There are million ways to break/confuse/generally demolish the above mechanism. One obvious one is to change the Makefile in such a way that the real set of included header files changes, but rebuilds are not automatically triggered. In my opinion, this sort of problem usually amounts to a bug in the Makefile. The solution is to fix the makefile such that everything is rebuilt when the Makefile changes:
*.c *.h *.y *.l *.s: Makefile
touch $@
Of course, you may need to tune this rule a bit if you project contains other kinds of sources, subdirectories, and/or automaticly generated sources.
Environment variables and scripts called in the Makefile are other common inputs to the build process. isymchoose makes no effort to detect this sort of thing. Use
isymchoose --clear-cache
when necessary.
Suppose you are using the GNU Scientific Library (GSL) in file foo.c and you want to compute the covariance of some data sets. You already have
#include <gsl/gsl_statistics.h>
in your CFILE. Of course, you don't remember the exact function name you want, or its signature. But you do know that is probably has the string 'cov' in it. So you just type 'cov' in your editor and press whatever keys you have bound to invoke isymchoose this way:
isymchoose foo.c cov
The resulting window should show you all the candidate functions and their signatures. You can add further filters if the list is too long. Your editor integration should take the standard output produced by isymchoose when you select a candidate and paste it in in place of the input regex.
The CFILE argument is the C file name to use as the context in which to search for symbols which match the REGEX argument. Be sure your C file contains the includes required to pull in the symbols of interest.
Change to directory DIR before doing anything else. isymchoose expects to find a make file (called 'Makefile' unless --makefile is used) in the working directory.
Try to use a window HEIGHT pixels high. Note that the window manager or Gtk toolkit itself may decide otherwise in some cases.
Try to use a window WIDTH pixels wide. Note that the window manager or Gtk toolkit itself may decide otherwise in some cases.
Clear the isymchoose cache and exit immediately. No other options or arguments are required (or honored) if this one is given. This may be required if your build environment changes in some way that isymchoose doesn't know about.
Specify that the preprocessor command line options required to cause gcc to produce dependency information instead of compiling normally should be added only to the make variable VAR. By default these options are added to the CPPFLAGS and CFLAGS make variables.
Specify that your project uses a make file named FILE. By default it is assumed that the project make file is named 'Makefile'. Note that FILE probably shouldn't contain a directory part.
Specify additional options to pass to the ctags program. If this command line option appears, its value replaces the setting in ~/.isymchoose/config. This option is probably most useful for passing -I options to ctags in order to prevent it getting confused by crazy preprocessor macros. Another possibility is to pass --exclude options to ignore everything in certain "private" headers that you know is not intended to be part of the API. Inappropriate values of this option will cause isymchoose to fail ungracefully. The --clear-cache option will probably have to be used first to get the desired effect.
Like --ctags-options, but the additional options are appended to those specified in ~/.isymchoose/config rather than replacing them.
Don't try in to complete or insert anything; operate as a documentation launcher/browser only. The interpretation of the input regex argument is changed slightly: if the input with regex anchors '^' and '$' added at the beginning and end matches exactly one symbol, the help for that symbol is launched via help_helper (effectively ignoring any longer symbols which also match the regex). Execution then proceeds normally, except that all output is disabled.
Print usage information and exit.
Print version information and exit.
The idea is to take from the editor the current file and directory and a regex and substitute or append the isymchoose output back into the buffer.
Add the following line to your .emacs file:
(load "PREFIX/share/isymchoose/emacs_isymchoose.el")
where PREFIX is the prefix used at install time (often '/usr/bin' or '/usr/local/bin'). If you used unusual configure options at compile time (to set the share directory or something) this file might end up somewhere else.
The default isymchoose key binding for emacs is shift-tab. There might be problems if this collides with one of your existing bindings. If it doesn't, you should just be able to type this sequence over a word to launch isymchoose. The easiest way to change this default binding is probably to just make your own copy of the above file, change the local-set-key command to whatever you want, and change the load command to load your file.
The integration code for this editor selects the current alphnumeric word, which makes passing full regexes impossible by default. See the magic_sevens option in ~/.isymchoose/config for an approach that should give acces to most of the desirable regex functionality from the editor.
First make sure your vim is compiled with perl support:
vim --version | grep '\+perl'
This command should hopefully generate some output. If it doesn't, you will need to get a copy of vim with perl support compiled in (or rewrite the vim module as native vim script :).
To install the vim interface module use the following shell commands:
mkdir --parents ~/.vim/after/ftplugin/c
cp PREFIX/share/isymchoose/isymchoose.vim ~/.vim/after/ftplugin/c
where PREFIX is the prefix used at install time (often '/usr/bin' or '/usr/local/bin').
The default isymchoose key binding for vim is backslash-t (from normal mode, assuming you haven't remapped Vim's LocalLeader to something other than backslash). There might be problems if this collides with one of your existing bindings. If it doesn't you should just be able to type this sequence over a symbol regex in command mode to launch isymchoose.
This key binding can be changed by adding a two lines like the following to your ~/.vimrc:
map <S-Tab> <Plug>IsymchooseComplete
imap <S-Tab> <Plug>IsymchooseComplete
This will bind Shift-Tab in both normal and insert mode to run isymchoose as a completer.
The integration code for this editor selects the current alphnumeric word, which makes passing full regexes impossible by default. See the magic_sevens option in ~/.isymchoose/config for an approach that should give access to most of the desirable regex functionality from the editor.
Its also possible to use isymchoose as a sort of source code browser help loader. Adding this line to your ~/.vimrc:
map <LocalLeader>l <Plug>IsymchooseLookup
then pressing backslash-l (again assuming LocalLeader is unchanged) will try to invoke help_helper on the symbol under the cursor, without completing or substituting anything.
The graphical interface used for symbol browsing and selection is hopefully fairly self-describing, but some of the options available in $HOME/.isymchoose/config aren't documented there and may be worth checking out. See the comments in the config file.
There exists a small perl script called $HOME/.isymchoose/help_helper that can launch documentation viewers for symbols. If the library you are using (in particular its prefix) isn't already known to help_helper, you can probably train it in a few minutes by looking at the recipes that are already in there. This script could also be entirely replaced if you prefer a different language.
General configuration. There are a couple of settings in here that are probably more comfortable for experienced users, but might confuse new ones and so aren't enabled by default. So take a look :)
Perl script responsible for loading documentation for symbols. Edit this to teach isymchoose how to launch documentation for the libraries you use.
Symbols often go undiscovered because the header files that declare them use strange macros that confuse ctags. Usually passing appropriate -I options to ctags fixes the problem. See the ctags_options option in ~/.isymchoose/config.
For me, programs are still written in ASCII text. The implementation almost certainly reflects this. If anyone writes me to tell me this has saddened them, I'll try to mend my evil ways.
There are a lot of input paths into the build process. The most obvious are environment variable settings, but in build systems that use scripts there are likely to be others as well. Its not possible to keep track of all of these, so if they are changed the cached information will likely fall out of sync with reality, and it will be necessary to run
isymchoose --clear-cache
in order to let isymchoose get a fresh start next time.
The use of thousands of buttons for all the symbols in the GUI is slow and is the limiting factor on the number of symbols we can gracefully handle. All the buttons should be replaced with sensitive GtkTreeView type stuff.
isymchoose currently doesn't work in header files themselves.
ctags(1), gcc(1)
Copyright (C) 2009, Britton Leo Kerin.
This is free software. You may redistribute copies of it under the terms of the GNU General Public License http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the extent permitted by law.
Britton Leo Kerin (isymchoose@letterboxes.org)