Subject: Re: bug#19466: 25.0.50; xref-find-def doesn't find C functions

From: Dmitry Gutov <[email-masked]>
Date: Fri, 02 Jan 2015 19:52:54 +0200

On 12/31/2014 12:44 AM, Stefan Monnier wrote:

> I think it's not just a matter of combining several major modes: you
> need to know where the various files are and how they relate.  IOW there
> needs to be some other logic on top of it and different systems will
> require different such logic.

Or, to put it another way: if someone is editing ELPA code in its own 
repo and presses `C-u M-.', I'm not sure it's reasonable to include all 
C functions and macros in the list of suggested identifiers. After all, 
they are writing Elisp, not C.

One way to deal with this would be to add a minor mode, one that people 
could enable on by-file or by-project basis (say, in Emacs's 
.dir-locals.el).

This xref-emacs-sources-mode would merge identifiers from both the Elisp 
and Etags backends, and try to merge the search results for different 
search actions as well.

It will return duplicate results, though. And filtering them out will be 
non-trivial.

For instance, if find-func and src/TAGS are merge, jumping to `car' 
would yield one xref-elisp-location, and one xref-file-location. How do 
you compare them, if one has fields with values "car" and "src/data.c", 
and the other "DEFUN ("car", Fcar," and "/full/p/t/emacs/src/data.c"?

Do we really want to include lisp/TAGS? It has both pros and cons.

Pros: we can jump to all functions, even non-autoloaded ones in all 
packages.

Cons: we do see all the functions, even ones we don't care about (their 
packages aren't loaded). Based on my positive experience with find-func, 
maybe 98% of the time the user won't really need them.

And duplicates, a lot more than with src/TAGS.

So someone should really consider if we ever need find-func and 
lisp/TAGS used together. Because if Eli only wants to use tag files when 
working on Emacs, the respective minor mode looks a lot simpler:

(defvar xref-etags-mode--save nil)

(define-minor-mode xref-etags-mode
   "Toggle using only the tag files for navigation."
   :lighter ""
   (if xref-etags-mode
       (progn
         (setq xref-etags-mode--save
               (cons xref-find-function
                     xref-identifier-completion-table-function))
         (kill-local-variable 'xref-find-function)
         (kill-local-variable 'xref-identifier-completion-table-function))
     (setq-local xref-find-function (car xref-etags-mode--save))
     (setq-local xref-identifier-completion-table-function
                 (cdr xref-etags-mode--save))))

Add it to find-file-hook, maybe predicated on buffer-file-name.