dgutov / robe

Code navigation, documentation lookup and completion for Ruby
584 stars 37 forks source link

Find semantic references? #116

Closed ylluminarious closed 5 years ago

ylluminarious commented 6 years ago

Robe supports the oft-used M-. key binding which lets one jump to a symbol's definition in the codebase. But does a function exist which allows one to find semantic references to a given symbol? grep can always be used for this sort of thing, but it can also be unreliable since sometimes a grep match is not referring to the symbol which is sought after. I've seen several other Emacs development modes which support this functionality including elisp-refs, OmniSharp, ggtags, and Semantic.

dgutov commented 5 years ago

How would you define a semantic reference in a dynamic language? (Almost) any method call to a method with the same name could be a reference, even though that might never occur in practice. With exceptions being calls on local values, but filtering out those would require some complex analysis.

I think ggtags might be the best choice if you manage to generate Global tags for Ruby. And M-x xref-find-references probably the second best, though it's a bit slower since it's based on Grep.

ylluminarious commented 5 years ago

@dgutov Hmm, I thought you could use the Robe server to the same kind of effect as robe-jump (i.e., M-.). If you can find a method's definition or documentation, I thought you might be able to find occurrences of that method. Although, I'm not familiar with how robe-jump works so maybe it's not that simple. If GNU Global would do the job, perhaps it would suffice for this...

dgutov commented 5 years ago

The Ruby VM records where each individual method was defined. That won't help with references, naturally.

dgutov commented 5 years ago

Do try M-x xref-find-references, though. It might be the easiest solution.

ylluminarious commented 5 years ago

@dgutov Thanks for the tip. I went ahead and tried xref-find-references as you said. It seems to work decently well, not quite as accurate as what I've seen in other modes since it picks up some false positives, but it's certainly better than grep and it'll get the job done.

I've also found that ctags is better than straight etags because it supports recursively walking a directory. I used ctags -eR to generate my Ruby TAGS file, in which -e means to emulate etags and -R means to recurse. I think it would be a good idea to put this information in the README file or other documentation for robe, since it may not be immediately obvious to users that tags are the way to do semantic referencing in robe.

dgutov commented 5 years ago

it's certainly better than grep and it'll get the job done

It actually uses Grep, but performs some post-filtering.

ctags might be okay for your use, but the latest etags has its own benefits, even though it does not scan recursively by itself. Try it with find -type f -name "*.rb" -exec etags -o TAGS \{\} +.

BTW, tags do not contain references, only definitions. xref-find-references only uses the tags file for completion.

ylluminarious commented 5 years ago

It actually uses Grep, but performs some post-filtering.

Right, I meant it's better than plain grep.

ctags might be okay for your use, but the latest etags has its own benefits, even though it does not scan recursively by itself.

What are those benefits, if you don't mind my asking?

Try it with find -type f -name "*.rb" -exec etags -o TAGS \{\} +.

Thanks for the tip again. I thought about using something like that, but I don't particularly like getting attached to long find incantations if I can avoid it. ctags sufficed for me thus far, unless there are some advantages of etags that I'm not aware of.

BTW, tags do not contain references, only definitions. xref-find-references only uses the tags file for completion.

Thanks for letting me know that.

dgutov commented 5 years ago

What are those benefits, if you don't mind my asking?

Better indexing: methods defined by attr_* macros, constants, def self.*. Some of these might be supported by ctags already, but not all, last I checked.

ylluminarious commented 5 years ago

@dgutov Hmm, thanks for the advice yet again. I found some documentation on this topic while searching for more info. Perhaps I would be better off with etags.