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

From: Eli Zaretskii <[email-masked]>
Date: Sat, 24 Jan 2015 11:40:57 +0200

> Date: Sat, 24 Jan 2015 00:23:24 +0200
> From: Dmitry Gutov <[email-masked]>
> CC: [email-masked], [email-masked]
> 
> 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.

Can you tell how can this be set up with xref, or point me to the
relevant documentation?

> > 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.

Any of these two will do (a plug has 2 parts).

> > 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.

That's not my point.  My point is that it is up to the user to decide
when she switches projects, and tell Emacs about that.  Emacs should
not try doing that on its own, whatever the backend's implementation
is.  The backend cannot make this decision for the user.

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

I said I will -- when I have time.  I didn't have that time yet,
sorry.

> >> 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.

I believe you it's the easiest approach.  But that doesn't yet make it
viable, because IMO it doesn't scale.  Only very simple projects will
be happy with such a design.  The example I described is not very
complicated, either, but it already bumps into this limitation.  I
think this is a clear sign that the limitation should be lifted.

> 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.

If lifting the above limitation requires some project system, then we
should provide a simple one for a project that uses only Makefile's.
That could be a single command that just specifies the top-level
directory of the project, or something similar.

However, it sounds like xref is not yet ready for that, either, is it?
If so, I suggest to add these simple features, because that would
allow to lift the limitation and make the feature much more scalable.

> > 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.

Then there should be a projectile-add-project and
projectile-remove-project as well.  I'm sure someone already thought
about that.  (I know nothing about Projectile, except that I think the
name is unfortunate -- take this from someone who has an intimate
familiarity with real projectiles.)

> > 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

I'd be surprised if it was just mine.  I know people who work on
projects much more complex than the use case I described.  Perhaps
they don't use Emacs, which would be an indirect approval of my
opinions.

> That is, a backend can use this approach as well.

"Can" and "does" have a large gap between them, from the user's POV.
Do we already have such a backend?  If not, I suggest to add it.

> > 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.

Unlikely to happen.  Given that etags exists and pretty much satisfies
my needs (with 30-year old technology!), there's not enough itch here
for me to scratch.  If xref is going to be as good as etags, let alone
better, I _will_ switch, I can promise you that much.  Until then, I'm
happy enough with etags, thank you very much.  I'm here merely as a
user, providing feedback for features someone else develops.  I hope
this is helpful; if not, feel free to discontinue the discussion at
any point you like.

> >>> 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?

No, I only understood that now.  Sorry for being dense.

So perhaps some users, like myself, will benefit from preventing the
override?  Is that possible with the current master?

> > 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.

Maybe I am, I don't know.  I don't care how this is called.  What I do
care is to be able to start working on a project with minimal fuss.
Having to spend a significant time telling Emacs just what constitutes
the project is therefore a turn-off: it is why I dislike Visual Studio
like "projects" and "solutions" system -- it might be OK for starting
a project from scratch, but sucks when you need to work on an existing
project, let alone a large one.

> That's commendable, and it's a separate discussion.

It is a very much related discussion, since you think the features I
miss in xref should be implemented by "project support".  Because
etags seems to seamlessly let me have that.  So if xref is meant to
replace etags, it should provide the same functionality, and if that
requires some rudimentary "project support", we should include it when
we announce deprecation of etags.

> Meanwhile, a lot of features currently depend just on the current major 
> mode and buffer. There's nothing new about it.

I never said that no feature can ever depend on the major mode.  All
I'm saying is that this particular feature shouldn't, and I gave
simple enough use cases to demonstrate why it is IMO wrong in this
case.

> 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.

I'm not sure what completions are alluded to here.  Completions are
context-dependent, i.e. their DWIM-ish nature should depend on what is
being completed, and for what purposes.  For example, I hope you'd
agree that it would be bad in general for completion in "C-x C-f" to
show only files from the current project.  By contrast, a specialized
command that is meant to find files only from the current project
should probably limit the candidates to the project.

Likewise with symbols -- when the user wants only symbols from the
current project, or from the programming language of the current
buffer, that's what Emacs should show.  But there are also situations
where such limitations produce bad results.

Since only the user knows what she wants to see at any given moment,
Emacs must support that.  It can do that in several ways:

  . have dedicated commands for each kind of situation

  . apply some heuristics to order the candidates in a particular way,
    so that the ones deemed more DWIM-ish appear first; this
    heuristics could use the current major mode or the current project
    or something else

  . maybe some other possibilities I haven't thought about

The important point is we cannot limit the user to just one possible
context, even if it is the most frequent one.  Such a feature would be
too limited.