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

From: Dmitry Gutov <[email-masked]>
Date: Sat, 24 Jan 2015 00:23:24 +0200

On 01/23/2015 11:03 PM, Eli Zaretskii wrote:

> I also like commands that work on the current project, I just don't
> like them to depend too much on the current buffer.

To cut this part of discussion short, yes, the project system can well 
be designed so that the "current project" depends not on the current 
buffer but on the user's choice. So to switch between projects, you 
invoke an explicit command, but don't visit a buffer belonging to the 
other project. And xref can work with such a system (just as it works 
with etags) without significant problems.

> Realistically, we need a command to switch to
> another project, and xref should plug into it, instead of trying to
> second-guess what I want.

Instead of xref plugging into whatever, any project system (which I'm 
assuming is implemented as a minor mode) can plug into xref and set up 
xref-find-function, etc, to use itself.

> It doesn't matter if there's one or many.  The important part is that
> the active one(s) need to be switched when I change to another
> project, and otherwise kept until I say-so.

That depends on the backend's implementation. etags works that way.

>> If you're using the etags backend, it should be just as affected by
>> `M-x visit-tags-table', as `find-tag' is.
>
> I don't understand what that means, sorry.  find-tag cannot work
> without me visiting a TAGS table.

etags-xref-find, likewise, will ask you for the path to the TAGS file, 
if it's not set yet.

> Seriously, though: I very much hope this was a semi-joke, because we
> really don't want asking users to do that.  A single instance of Emacs
> should be able to cope with such a simple task.  FWIW, I regularly
> have about a dozen projects in my Emacs session, and switch between
> them quite a lot.

Semi-joke, yes. That's just what I often do to avoid the clutter of 
buffers opened from different projects. It could work almost as well 
using different frames, but I'd have to find a way to hide the one 
frame's file buffers from the other frames.

You can continue doing what you've always done, no problem.

>> But the tags-file-name/tags-table-list approach should still work,
>> as long as the etags backend is used.
>
> I thought you were asking whether I must stick to etags, and was
> trying to explain which features I need to have, not necessarily in
> etags.  If the only conclusion from this discussion is that I must
> stick to etags or give up on features that it has been offering for
> years, then I'm sorry to say that xref doesn't seem progress to me.

Not at all. When I say "etags backend", I mean "etags backend for xref", 
since the latter is the subject of our discussion.

I think it's high time you've tried the snippets I wrote.

>> Note that currently the only thing that depends on a specific buffer is
>> the backend used.
>
> I fail to understand the rationale behind such a design.  As long as
> we are talking about buffers that hold source code of some programming
> language, why would it be a good idea to switch backends depending on
> the buffer?

You may not like it, but it's the easiest viable approach we can take, 
and a lot of people find it natural. For instance, both original 
proposals for the xref implementation used it.

However, like I mentioned, when a project system is used, we can use its 
backend in all project files, and so the backend would depend on the 
directory you in. But also see my first paragraph in this email.

> projectile-switch-project is conceptually the same as
> visit-tags-table, so I see no difference.

Except it visits the "root file" of the project after switching, and 
immediately "forgets" the previous project. So it's the kind of design 
you don't like.

It's the most popular project solution for Emacs that I know.

> That's not the issue.  The issue is that the logic behind determining
> the current project cannot be reliable enough to decide for the user
> which collection(s) of symbols are of interest to me at any given
> time.  Only the user knows that.  Unlike some other heuristics, where
> it's okay to have an imperfect success rate, in this case it's
> terribly annoying when Emacs refuses to admit that a symbol exists and
> show it to you, when you _know_ for sure it does exist.  This kind of
> annoyance _will_ happen if you rely on automated logic for deciding
> which symbols are or aren't relevant.

While I can understand it, that's just your (i.e. not universal) 
opinion, and I believe it's addressed above. That is, a backend can use 
this approach as well.

> That's not user-level customization.  It's too complex to be that.  We
> need simpler, higher-level customizations.

We don't even know what and how to customize yet. It might be time for 
you to swap the user shoes for the developer shoes.

>>> Is it possible to turn on xref-etags-mode (or its equivalents)
>>> globally?
>>
>> It's "turned on" by default.
>
> Then why did you propose to use hooks?

Because emacs-lisp-mode overrides it, and to reach certain level of 
happiness, you seem to need to revert that override. I believe I've 
explained that in the previous email, no?

>> Compared to etags, it also won't jump to the C functions that are not
>> exposed to Emacs Lisp. The overwhelming majority of our users (myself
>> probably included), won't ever need this.
>
> You can't build useful features on such assumptions.

I can, and I do.

> Btw, this mode of work, in more than one language, is not limited to
> Emacs.  You will see it in Guile, in Python, in Awk, in GDB, and in
> many other places.  It begins to be the rule rather than exception
> these days.  It's not good if Emacs will ask developers to jump
> through hoops to support that.

You seem to be clamoring for project support in Emacs. That's 
commendable, and it's a separate discussion.

Meanwhile, a lot of features currently depend just on the current major 
mode and buffer. There's nothing new about it. The easiest example is 
code completion.

In emacs-lisp-mode, it will parse the current buffer context and offer 
completions from obarray, somewhat filtered. If you have a README in the 
same directory as foo.el (so we might consider them to be in the same 
project), when you open it, you definitely won't get the same 
completions as in emacs-lisp-mode. In fact, if there's no current tags 
file visited, in the default Emacs configuration you won't get any 
completions at all.

Similarly for python-mode (python-shell-completion-at-point only works 
in Python buffers, and only when an inferior shell is running). Likewise 
for Octave, and I just haven't looked at Guile, Awk and GDB support.