unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Allow xref to use other than current major-mode
@ 2015-08-25 10:00 Stephen Leake
  2015-08-25 11:48 ` Dmitry Gutov
  0 siblings, 1 reply; 16+ messages in thread
From: Stephen Leake @ 2015-08-25 10:00 UTC (permalink / raw)
  To: emacs-devel

I have the following use case:

I'm in a C buffer, asking "what elisp function will
semantic-parse-region dispatch to in this buffer?".

semantic-parse-region is a mode-local overloadable function; it
dispatches based on the current major mode. elisp--xref-find-definitions
doesn't currently show mode-local overrides; I'm working on adding that
capability.

I'd like to use xref-find-definitions to answer this question, so I
invoke it with C-u M-. 

That prompts me for an identifier. However, it uses the c-mode value of
xref-identifier-completion-table-function, so I can't complete to
semantic-parse-region.

In addition, xref--show-xrefs uses the c-mode value of
xref-find-function, so it won't find the elisp function.

To handle this, I propose changing both
xref-identifier-completion-table-function and xref-find-function to be
mode-local, instead of buffer-local.

Then, when current-prefix-arg is non-nil, xref--read-identifier can
prompt for the mode to use when completing the identifier, and
xref--show-xrefs can use that mode when calling xref-find-function.


There are similar use cases; from a LaTeX document buffer, looking at the
description of an Ada function, find the Ada code that defines that
function. Or from a text mode notes file, look for a definition in any
one of several languages.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 10:00 Allow xref to use other than current major-mode Stephen Leake
@ 2015-08-25 11:48 ` Dmitry Gutov
  2015-08-25 12:19   ` João Távora
                     ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Dmitry Gutov @ 2015-08-25 11:48 UTC (permalink / raw)
  To: Stephen Leake, emacs-devel

On 08/25/2015 01:00 PM, Stephen Leake wrote:

> To handle this, I propose changing both
> xref-identifier-completion-table-function and xref-find-function to be
> mode-local, instead of buffer-local.

That seems unnecessarily limiting. First, mode-local facility is a part 
of CEDET, so it would need to be always loaded.

Second, how would a minor mode set an xref backend? It might not be tied 
to a particular major mode.

> There are similar use cases; from a LaTeX document buffer, looking at the
> description of an Ada function, find the Ada code that defines that
> function. Or from a text mode notes file, look for a definition in any
> one of several languages.

All similar cases can be solved by a project-aware xref backend that 
knows about all languages used, and allows navigating to identifiers in 
all of them.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 11:48 ` Dmitry Gutov
@ 2015-08-25 12:19   ` João Távora
  2015-08-25 12:25   ` David Engster
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 16+ messages in thread
From: João Távora @ 2015-08-25 12:19 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: Stephen Leake, emacs-devel

> Second, how would a minor mode set an xref backend? It might not be tied to
> a particular major mode.

+1 This is important for me. I would like to make `sly-mode' use
`xref` when it's available.
`sly-mode` is a minor mode active in many buffers of different major modes,
all part of the SLY family. Xref should use the same backend in all of them.

> All similar cases can be solved by a project-aware xref backend that knows
> about all languages used, and allows navigating to identifiers in all of
> them.

Can't see right how I can use this to solve my particular case, but
I'm confident
I will :-)

-- 
João Távora



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 11:48 ` Dmitry Gutov
  2015-08-25 12:19   ` João Távora
@ 2015-08-25 12:25   ` David Engster
  2015-08-25 14:47     ` Stephen Leake
  2015-08-25 15:23   ` Eli Zaretskii
  2015-08-25 15:31   ` Stephen Leake
  3 siblings, 1 reply; 16+ messages in thread
From: David Engster @ 2015-08-25 12:25 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: Stephen Leake, emacs-devel

Dmitry Gutov writes:
> On 08/25/2015 01:00 PM, Stephen Leake wrote:
>
>> To handle this, I propose changing both
>> xref-identifier-completion-table-function and xref-find-function to be
>> mode-local, instead of buffer-local.
>
> That seems unnecessarily limiting. First, mode-local facility is a
> part of CEDET, so it would need to be always loaded.

mode-local does not depend on anything from CEDET.

-David



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 12:25   ` David Engster
@ 2015-08-25 14:47     ` Stephen Leake
  2015-08-25 15:07       ` David Engster
  0 siblings, 1 reply; 16+ messages in thread
From: Stephen Leake @ 2015-08-25 14:47 UTC (permalink / raw)
  To: emacs-devel

David Engster <deng@randomsample.de> writes:

> Dmitry Gutov writes:
>> On 08/25/2015 01:00 PM, Stephen Leake wrote:
>>
>>> To handle this, I propose changing both
>>> xref-identifier-completion-table-function and xref-find-function to be
>>> mode-local, instead of buffer-local.
>>
>> That seems unnecessarily limiting. First, mode-local facility is a
>> part of CEDET, so it would need to be always loaded.
>
> mode-local does not depend on anything from CEDET.

Well, mode-local.el is in cedet/, but it does not depend on anything
_else_ from CEDET.

On the gripping hand, mode-local.el is not pre-loaded, so elisp-mode.el
cannot require it. cl-generic.el is pre-loaded.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 14:47     ` Stephen Leake
@ 2015-08-25 15:07       ` David Engster
  0 siblings, 0 replies; 16+ messages in thread
From: David Engster @ 2015-08-25 15:07 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

Stephen Leake writes:
> David Engster <deng@randomsample.de> writes:
>
>> Dmitry Gutov writes:
>>> On 08/25/2015 01:00 PM, Stephen Leake wrote:
>>>
>>>> To handle this, I propose changing both
>>>> xref-identifier-completion-table-function and xref-find-function to be
>>>> mode-local, instead of buffer-local.
>>>
>>> That seems unnecessarily limiting. First, mode-local facility is a
>>> part of CEDET, so it would need to be always loaded.
>>
>> mode-local does not depend on anything from CEDET.
>
> Well, mode-local.el is in cedet/, but it does not depend on anything
> _else_ from CEDET.

That's what I meant; nothing else from CEDET is loaded when you require
'mode-local. It would probably make sense to move mode-local to
lisp/emacs-lisp, just like we did with EIEIO.

> On the gripping hand, mode-local.el is not pre-loaded, so elisp-mode.el
> cannot require it. cl-generic.el is pre-loaded.

Yes, that's a problem.

-David



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 11:48 ` Dmitry Gutov
  2015-08-25 12:19   ` João Távora
  2015-08-25 12:25   ` David Engster
@ 2015-08-25 15:23   ` Eli Zaretskii
  2015-08-25 17:25     ` Dmitry Gutov
  2015-08-25 15:31   ` Stephen Leake
  3 siblings, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2015-08-25 15:23 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: stephen_leake, emacs-devel

> From: Dmitry Gutov <dgutov@yandex.ru>
> Date: Tue, 25 Aug 2015 14:48:34 +0300
> 
> > There are similar use cases; from a LaTeX document buffer, looking at the
> > description of an Ada function, find the Ada code that defines that
> > function. Or from a text mode notes file, look for a definition in any
> > one of several languages.
> 
> All similar cases can be solved by a project-aware xref backend that 
> knows about all languages used, and allows navigating to identifiers in 
> all of them.

It would be nice to have that capability without the need to create a
project.  E.g., how about adding to Emacs a few back-ends that support
widely used combinations of languages, like C and Lisp in our case?



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 11:48 ` Dmitry Gutov
                     ` (2 preceding siblings ...)
  2015-08-25 15:23   ` Eli Zaretskii
@ 2015-08-25 15:31   ` Stephen Leake
  2015-08-25 15:41     ` Stephen Leake
                       ` (2 more replies)
  3 siblings, 3 replies; 16+ messages in thread
From: Stephen Leake @ 2015-08-25 15:31 UTC (permalink / raw)
  To: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 08/25/2015 01:00 PM, Stephen Leake wrote:
>
>> To handle this, I propose changing both
>> xref-identifier-completion-table-function and xref-find-function to be
>> mode-local, instead of buffer-local.
>
> That seems unnecessarily limiting. First, mode-local facility is a
> part of CEDET, so it would need to be always loaded.

I realized after I posted that mode-local.el is not pre-loaded, so
elisp-mode.el can't require it. That said, mode-local.el is only one
file; nothing else in CEDET is required.

cl-generic.el is preloaded, so we could use a cl-defgeneric, and
dispatch on (mode (eql <major-mode>)).

> Second, how would a minor mode set an xref backend? It might not be
> tied to a particular major mode.

I don't see how a global minor mode can set an xref backend now.

To make such a minor mode work, xref--read-identifier could be a
cl-defgeneric that dispatches on (project <project-type). But if it also
dispatches on (mode (eql <major-mode>)), each backend would have to
define all combinations; that's a pain.

>> There are similar use cases; from a LaTeX document buffer, looking at the
>> description of an Ada function, find the Ada code that defines that
>> function. Or from a text mode notes file, look for a definition in any
>> one of several languages.
>
> All similar cases can be solved by a project-aware xref backend that
> knows about all languages used, and allows navigating to identifiers
> in all of them.

I've started writing such a thing, but it gets defeated by the fact that
xref--read-identifier uses the buffer-local value of
xref-identifier-completion-table-function, which is set by elisp-mode
(or c-mode, etc, or by default to etags). There's no way to change that.

We could require the user to manually enable an xref minor mode in each
buffer, but that's not friendly.

I guess a global xref backend could somehow reset that variable, in all
elisp buffers? Maybe a function on elisp-mode-hook.

The problem is that emacs-lisp-mode sets the buffer-local xref
variables, but I don't want it to.

So a better approach would be to define a way to disable emacs-lisp-mode
(and all other major-modes) setting the xref buffer-local variables, so
that the user choice of xref backend is respected. That would be much
simpler than having to add a function to all the major mode hooks (most
of which are unknown at load time).

We could define a new global variable xref-global-backend; if nil (the
default), major modes can set xref vars; if non-nil, it indicates which
particular global backend is in use. It could be a function that returns
a boolean indicating whether the global backend wants to control xref in
the current buffer. So a semi-global backend could provide C and Ada
xref, but not elisp xref, for example. It could be a list of such
functions; only if all return nil should the major mode set the xref
vars.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 15:31   ` Stephen Leake
@ 2015-08-25 15:41     ` Stephen Leake
  2015-08-25 17:05     ` Dmitry Gutov
  2015-08-25 22:15     ` Stefan Monnier
  2 siblings, 0 replies; 16+ messages in thread
From: Stephen Leake @ 2015-08-25 15:41 UTC (permalink / raw)
  To: emacs-devel

Stephen Leake <stephen_leake@stephe-leake.org> writes:

> I've started writing such a thing, but it gets defeated by the fact that
> xref--read-identifier uses the buffer-local value of
> xref-identifier-completion-table-function, which is set by elisp-mode
> (or c-mode, etc, or by default to etags). There's no way to change that.
>
> I guess a global xref backend could somehow reset that variable, in all
> elisp buffers? Maybe a function on elisp-mode-hook.

There is after-change-major-mode-hook, but we would still have
xref-backends fighting for control.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 15:31   ` Stephen Leake
  2015-08-25 15:41     ` Stephen Leake
@ 2015-08-25 17:05     ` Dmitry Gutov
  2015-08-25 21:13       ` Stephen Leake
  2015-08-25 22:15     ` Stefan Monnier
  2 siblings, 1 reply; 16+ messages in thread
From: Dmitry Gutov @ 2015-08-25 17:05 UTC (permalink / raw)
  To: Stephen Leake, emacs-devel

On 08/25/2015 06:31 PM, Stephen Leake wrote:

> cl-generic.el is preloaded, so we could use a cl-defgeneric, and
> dispatch on (mode (eql <major-mode>)).

A given implementation is, of course, free to use cl-defgeneric and 
dispatch on whatever it wants, internally.

> To make such a minor mode work, xref--read-identifier could be a
> cl-defgeneric that dispatches on (project <project-type).

The plan is to consolidate the various -function's as generic method, 
dispatching on a single xref-backend value. I haven't got around to this 
yet, blocked on find-file-delayed.

> But if it also
> dispatches on (mode (eql <major-mode>)), each backend would have to
> define all combinations; that's a pain.

If a backend needs to dispatch based on the current language, it will. 
It will do that inside the method implementations.

But many backends will only need to deal with one language, a couple, or 
won't really need to check the language of the current buffer.

> I've started writing such a thing, but it gets defeated by the fact that
> xref--read-identifier uses the buffer-local value of
> xref-identifier-completion-table-function, which is set by elisp-mode
> (or c-mode, etc, or by default to etags). There's no way to change that.

A backend is a combination of xref-find-function, xref-i-c-t-function 
and xref-i-a-p-function. If a minor mode changes the current backend, it 
would need to set all these variables (but see the planned change 
mentioned above).

> We could require the user to manually enable an xref minor mode in each
> buffer, but that's not friendly.

We have "globalized" minor modes, to be used in similar situations.

> I guess a global xref backend could somehow reset that variable, in all
> elisp buffers? Maybe a function on elisp-mode-hook.

A minor mode function is indeed normally added to xxx-mode-hook, whether 
it's by user's hand, or somehow automatically.

> So a better approach would be to define a way to disable emacs-lisp-mode
> (and all other major-modes) setting the xref buffer-local variables, so
> that the user choice of xref backend is respected. That would be much
> simpler than having to add a function to all the major mode hooks (most
> of which are unknown at load time).

You're speaking from the standpoint of wanting a single, global xref 
backend everywhere for the duration of the Emacs session.

As previous discussions showed, that approach isn't natural for everyone.

> We could define a new global variable xref-global-backend; if nil (the
> default),

We've discussed a very similar proposal, very recently. As long as a 
minor mode can take over major mode's setting anyway, there's no point 
in adding this kind of explicit override.

> major modes can set xref vars; if non-nil, it indicates which
> particular global backend is in use. It could be a function that returns
> a boolean indicating whether the global backend wants to control xref in
> the current buffer. So a semi-global backend could provide C and Ada
> xref, but not elisp xref, for example. It could be a list of such
> functions; only if all return nil should the major mode set the xref
> vars.

Sounds like an unnecessary complication.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 15:23   ` Eli Zaretskii
@ 2015-08-25 17:25     ` Dmitry Gutov
  2015-08-25 21:17       ` Stephen Leake
  0 siblings, 1 reply; 16+ messages in thread
From: Dmitry Gutov @ 2015-08-25 17:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel

On 08/25/2015 06:23 PM, Eli Zaretskii wrote:

> It would be nice to have that capability without the need to create a
> project.

There may be no need to "create" a project, for a particular backend. 
But a specialized backend (for instance, one for Emacs sources) will 
know the directory tree layout and where to get information from. In 
Emacs's case, for example, from find-func and TAGS files inside lisp/ 
and src/.

And how to combine the information from the different sources better.

> E.g., how about adding to Emacs a few back-ends that support
> widely used combinations of languages, like C and Lisp in our case?

Someone is welcome to take that up. It won't be on my list for a while, 
probably not until after the 25.1 feature freeze.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 17:05     ` Dmitry Gutov
@ 2015-08-25 21:13       ` Stephen Leake
  2015-08-25 22:11         ` Dmitry Gutov
  0 siblings, 1 reply; 16+ messages in thread
From: Stephen Leake @ 2015-08-25 21:13 UTC (permalink / raw)
  To: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

>> We could require the user to manually enable an xref minor mode in each
>> buffer, but that's not friendly.
>
> We have "globalized" minor modes, to be used in similar situations.

Ok. I missed that globalized minor modes are automatically run in every
new buffer created, after the major mode hook. That's equivalent to
putting the mode enable function on after-change-major-hook.

I think it would be clearer to not have major modes set things that a
minor mode will then unset, but I can live with it.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 17:25     ` Dmitry Gutov
@ 2015-08-25 21:17       ` Stephen Leake
  0 siblings, 0 replies; 16+ messages in thread
From: Stephen Leake @ 2015-08-25 21:17 UTC (permalink / raw)
  To: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 08/25/2015 06:23 PM, Eli Zaretskii wrote:
>
>> It would be nice to have that capability without the need to create a
>> project.
>
> There may be no need to "create" a project, for a particular backend.
> But a specialized backend (for instance, one for Emacs sources) will
> know the directory tree layout and where to get information from. In
> Emacs's case, for example, from find-func and TAGS files inside lisp/
> and src/.
>
> And how to combine the information from the different sources better.
>

That is one of the things I'm doing.


-- 
-- Stephe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 21:13       ` Stephen Leake
@ 2015-08-25 22:11         ` Dmitry Gutov
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitry Gutov @ 2015-08-25 22:11 UTC (permalink / raw)
  To: Stephen Leake, emacs-devel

On 08/26/2015 12:13 AM, Stephen Leake wrote:

> Ok. I missed that globalized minor modes are automatically run in every
> new buffer created, after the major mode hook. That's equivalent to
> putting the mode enable function on after-change-major-hook.

Pretty much.

> I think it would be clearer to not have major modes set things that a
> minor mode will then unset, but I can live with it.

Even with the current state of affairs, there's no reason to expect that 
a given xref backend doesn't require setting all xref variables to its 
own implementations.

And in the future, a minor mode will do (add-hook 'xref-backends 
'foo-xref nil maybe-locally)



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 15:31   ` Stephen Leake
  2015-08-25 15:41     ` Stephen Leake
  2015-08-25 17:05     ` Dmitry Gutov
@ 2015-08-25 22:15     ` Stefan Monnier
  2015-08-25 22:29       ` Dmitry Gutov
  2 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2015-08-25 22:15 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

> I've started writing such a thing, but it gets defeated by the fact that
> xref--read-identifier uses the buffer-local value of
> xref-identifier-completion-table-function, which is set by elisp-mode
> (or c-mode, etc, or by default to etags). There's no way to change that.

Could it help if those major modes were careful to use add-function and
to not completely override the global value?


        Stefan



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Allow xref to use other than current major-mode
  2015-08-25 22:15     ` Stefan Monnier
@ 2015-08-25 22:29       ` Dmitry Gutov
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitry Gutov @ 2015-08-25 22:29 UTC (permalink / raw)
  To: Stefan Monnier, Stephen Leake; +Cc: emacs-devel

On 08/26/2015 01:15 AM, Stefan Monnier wrote:

> Could it help if those major modes were careful to use add-function and
> to not completely override the global value?

Supposedly, the minor mode would need to disable or remove that piece of 
advice, then, but how? It wouldn't know what FUNCTION to pass to 
advice-remove.

The question of being able to use add-function might be important, 
however. The planned move to xref-backends will eliminate that possibility.



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-08-25 22:29 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-25 10:00 Allow xref to use other than current major-mode Stephen Leake
2015-08-25 11:48 ` Dmitry Gutov
2015-08-25 12:19   ` João Távora
2015-08-25 12:25   ` David Engster
2015-08-25 14:47     ` Stephen Leake
2015-08-25 15:07       ` David Engster
2015-08-25 15:23   ` Eli Zaretskii
2015-08-25 17:25     ` Dmitry Gutov
2015-08-25 21:17       ` Stephen Leake
2015-08-25 15:31   ` Stephen Leake
2015-08-25 15:41     ` Stephen Leake
2015-08-25 17:05     ` Dmitry Gutov
2015-08-25 21:13       ` Stephen Leake
2015-08-25 22:11         ` Dmitry Gutov
2015-08-25 22:15     ` Stefan Monnier
2015-08-25 22:29       ` Dmitry Gutov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).