Thursday, June 21, 2007

emacs - buffer inheritence

You create a list of files that you want to be in the database and call it cscope.files. So something like: find . -name '*.[ch]' -print > cscope.files

Then you do cscope -q, it grinds for a bit and then pops up with a user interface. The user interface is a curses type thing. You can search for all of the places that foo is used. You can search for where foo is defined. You can search for where foo is assigned. These searches are extremely fast. You can also do a number of slower searches like find a string, regexp, etc.

There is a programatic interface to cscope that a number of people have hooked into emacs. In my weird case, I have the concept of buffer inheritance. This is a different concept from cscope that my cscope interface ties in to. With buffer inheritance, each buffer has a parent. So foo.c would have a parent of cscope: dog. cscope: dog is a buffer (and thus a window) that formats the output of the programatic interface to cscope. So, for example, I can search for the places that var is used. The list pops into the cscope: dog buffer. I then click on one of the lines and that file is opened and I'm placed at that line. The last bit is much like tags. But the search is much broader. The search will find any place that var is used in any of the files listed in cscope.files. If you open a file from the cscope:dog interface, then its parent is assigned to cscope:dog.

The reason for inheritance is so I can have multiple cscopes running at the same time and things stay organized. So, for example, I can have a cscope running on the version 1 code and a cscope running on the version 2 code. Clicking and searching while in a buffer from the version 1 source base will search the version 1 cscope. Clicking and searching while in a version 2 buffer will search the cscope for the version 2 code.

Other implementations of cscope.el I've seen have the concept (instead of inheritance) of a list of cscopes. All of the cscopes are searched each time. That would not work for me at all. I do support mostly and ping ponging between different versions and keeping things straight is key for me.

The user interface I have is I have Control-\ hooked to a personal-map. In the personal-map I have each of the nine or so functions that cscope can do hooked to a different key. e.g. C-\ s does a search for a variable. C-\ f does a find of the variable's definition. C-\ F will find a file. etc.

I also have these hooked up to mouse functions but I rarely use the mouse. I think, while in a buffer that has a cscope parent, I can double click on a variable and it will do a search. Double click with the different cord keys does different things: find, etc.

Oh... now the hate part. cscope when it parses the files is not doing a real parse. It can not. You get into problems with conditional compilations and needing to include header files, etc. So, it is a 90% parse (maybe 95%). It is pretty accurate but it fails at times. Also, the thing that I want is to be able to have a more precise search. For example, I want to be able to find where the field foodog of the structure henry is used. Right now, I can only find all foodog's which may be fields of any structure, variables, or globals. But alas, the truth is, this desire wells up inside of me fairly rarely. (Obviously, not often enough for me to do something about it).

I don't know what languages cscope supports. Originally it was c. It does a fairly decent job of c++. I think it has been extended but I'm not up to date with how many languages it supports. It does seem like most of the newer languages like Ruby, cscope could do a 100% parse fairly easily.

The way I was going to integrate cscope into ecb (before this discussion) was to make the names of the cscope buffers match the name of the "compile" window. I have not used ecb's compile window any yet. But, my thought is that you want the cscope window somewhat present all the time (if it is displayed at all). So, as you click around, the cscope window stays put. But, I have not used it that way yet so I may quickly decide that that is not what I want at all.

Perry Smith disclose here a very great opinion, the "buffer inheritence" in emacs, I am using xcscope, but not coding on that, so I may not be clear on how the core works in emacs. That will be a great area for me to explore emacs-lisping.

KScope (the KDE version) is doing good on linux kernel, but does not doing good on itself -- the Qt C++ language parsing. Why cscope is not doing good on C++ compared to C, I think C++ is more complex than C, usually people will only use a part of C++ as a lanuge, for Qt, it has MOC preprocessing the C++ code.

Without cscope, I am using doxygen, and I have quite a few years experence using it, usually it's more suit for C++. Maybe I have too few experience on cscope. The success of doxygen is a little bit like "WEB" from Don Knuth, it displays each small part of code very well, then with web browser's help, people can navigate code. Don knuth designed WEB originally just for layout, but found it is also good to design program with it, that is the magic of WEB. So doxygen with web browser's help is still the best practical way to browse source code (c,c++) right now for me.

But still cscope is impressed to me since it is so fast to search a symbol, I think it is still a very powerful tool with simple goals. The magic will be how emacs use it.