>>> Gerdin Tobias <Tobias.Gerdin@...> seems to think that:
[ ... ]
>> semantic-ia-fast-jump, for example, gets an analyzer
>>context, pulls out the prefix, and then just visits whatever
>>it found. The analyzer is concerned with getting the semantic
>>context of the local area, and doesn't care where the
>>definition is, as long as a declaration is available. In
>>addition, the analyzer wants to be as fast as possible, so it
>>doesn't parse every file, only the files directly included in
>>the current buffer.
>> There is a way to get the definition of a class, and that is
>>via the "brutish" search. Getting that to work requires
>>parsing every file in your project. There are likely clever
>>ways to get it to associate a header file with some group of C
>>files, but that would not be reliable.
>If parsing all the files is the only way to reliably get the correct
>result I think that is the way to go. Computers excel at number
>crunching, and todays machines are extremely fast (and it would be
>nice if Emacs got some kind of concurrency support now that
>multi-core machines are very common). Nonetheless, I was under the
>impression that Semantic parsing is done at idle time and that tag
>tables are cached to disk making even a brute-force approach feasible
Correct. The idle time parsing has been pushing out collecting more
information so this can be done quickly, and under the covers. There
is also a semanticdb.sh script which I haven't tested in a very long
time which could be used create database tables in a Makefile also.
The brute force search, however, is still more time-consuming, and
less reliable than parsing through header files.
Doing the brute force search would be a good thing for a specialized
jump function to do, not necessary for the analyzer, since often the
analyzer results are only used for basic tag info lookup, which is
exactly what prototypes are meant to provide.
Another brute force search issue is that it requires EDE to tell it
the file-system scope of the current project to really work well.
This has been getting much better, but I haven't tried it in
situations where includes are kept somewhere other than in the same
directory as the sources. It can go from .c to .h well, but I'm not
sure about going the other way. There's only one way to find out.
>> The right solution here would be for someone to take on the
>>project of jumping to a tag, and make an appropriately
>>advanced implementation, as there are many nuances to what a
>>user intends when a jump is done, and as you noticed, often
>>more than one possible destination.
>I can see if I can help out here. I do not have much time to devote
>to Elisp hacking and I already have a long list of other interesting
>Elisp projects to pursue, but I would deem this one very important.
[ ... ]
That would be spiffy. I can certainly imagine a range of jumping
around functions that would suffice, and not require much user input,
(just jump to the most concrete thing the analyzer can find.)
(Jump to the defn for the prototype the cursor is on.)
(jump to the prototype of the current definition)
(superclass of the defn the cursor is on)
(to the datatype of the current tag.)
(jump to the range of subclasses of the current class)
At my work, I have such things bound to [A-left], [A-right] etc. We
use file names to match these things up so I didn't need to use
Senator would probably be the right place for these types of
functions, since it is meant to be the "navigator" for Semantic.
I tried my hand at go-to-definition this morning, and I came up with
the attached fcn. Sadly, my version depends on a semanticdb API I
haven't finished checking in yet, so I put in a hack to make it work
w/out. As the todo comment also suggests, there is the potential for
confusion if you use the same name a lot, so this needs some work.
(defun senator-jump-to-definition ()
"Jump to the definition of the tag under point.
This does not jump to the symbol the cursor is on, but the entire
tag (function, type, etc)."
(let ((tg (senator-current-tag)))
(if (not (semantic-tag-prototype-p tg))
(message "You are already on the definition of %s"
(let ((brute (semanticdb-brute-deep-find-tags-by-name
(when (not brute)
(error "Cannot find any references to %s in wide search"
;; Loop over all the hits to find the right thing.
(let ((match nil)
(while (and brute (not match))
(setq dblist (cdr (car brute)))
(while (and dblist (not match))
(when (not (semantic-tag-prototype-p (car dblist)))
;; @TODO - check we are in the right "parent" too.
(setq match (car dblist)
matchdb (car (car brute)))
(setq dblist (cdr dblist)))
(setq brute (cdr brute)))
(when (not match)
(error "Cannot find any definitions for %s in wide search"
; (let* ((norm (semanticdb-normalize-one-tag matchdb match))
; (db (car norm))
; (tag (cdr norm)))
(semantic-go-to-tag match matchdb)
Eric Ludlam: eric@...
Siege: http://www.siege-engine.com Emacs: http://cedet.sourceforge.net