Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the which-func package, i.e. which-function-mode #758

Closed
wants to merge 1 commit into from

Conversation

sfllaw
Copy link
Contributor

@sfllaw sfllaw commented Nov 13, 2021

which-func assumes that imenu is enabled and determines which function your current point is in using imenu--index-alist.

However, it doesn’t understand special elements in imenu--index-alist so those entries must be handled by a hook installed in
which-func-functions.

  • eglot.el (eglot-which-func): Hook to determine the function which your current point is in, based on Eglot’s special Imenu element.

  • eglot.el (eglot--managed-mode): Add and remove the eglot-which-func hook in which-func-functions.

  • eglot-tests.el (basic-which-func): Test which-function-mode.

which-func assumes that imenu is enabled and determines which function
your current point is in using imenu--index-alist.

However, it doesn’t understand special elements in imenu--index-alist
so those entries must be handled by a hook installed in
which-func-functions.

* eglot.el (eglot-which-func): Hook to determine the function which
your current point is in, based on Eglot’s special Imenu element.

* eglot.el (eglot--managed-mode): Add and remove the eglot-which-func
hook in which-func-functions.

* eglot-tests.el (basic-which-func): Test which-function-mode.
@joaotavora
Copy link
Owner

However, it doesn’t understand special elements in imenu--index-alist so those entries must be handled by a hook installed in which-func-functions.

Ah, but why isn't that hook installed by default in which-func-function? IOW, is it really impossible to have LSP-agnostic imenu clients?

The special elements in imenu--index-alist have been giving me trouble for a while now. It seems a lot of clients simply don't understand them. I don't understand why, but it's the reality. Maybe a better solution for your use case and all those other clients would be to simply stop using the special elements. I think some functionality would be lost, but perhaps much more "free" functionality would be gained.

@sfllaw
Copy link
Contributor Author

sfllaw commented Nov 13, 2021

However, it doesn’t understand special elements in imenu--index-alist so those entries must be handled by a hook installed in which-func-functions.

Ah, but why isn't that hook installed by default in which-func-function? IOW, is it really impossible to have LSP-agnostic imenu clients?

But which-func-functions is provided by the which-func package specifically to support imenu--index-alist special elements?

Are you asking why this patch doesn’t install the hook? It does here, inside eglot--managed-mode.

Or are you asking why which-func doesn’t rely on imenu’s interface to do the reverse lookup? I think this would be too slow. Imenu doesn’t expose this kind of API, and because the special function is arbitrary, you’d basically have to walk imenu--index-alist with save-excursion to locate the right entry, which would probably be super slow.

The special elements in imenu--index-alist have been giving me trouble for a while now. It seems a lot of clients simply don't understand them. I don't understand why, but it's the reality. Maybe a better solution for your use case and all those other clients would be to simply stop using the special elements. I think some functionality would be lost, but perhaps much more "free" functionality would be gained.

Yeah, it seems like overloading imenu--index-alist to present rich location information was a good attempt but imenu’s API isn’t flexible enough for other clients to deal with? What kind of existing functionality would be lost?

As an alternative, we could store the rich information returned by textDocument/documentSymbol in eglot--document-symbol-alist, which gets reduces to the simple elements in imenu--index-alist. But perhaps that would be better done in another PR?

If eglot--document-symbol-alist existed, I can also imagine a world where overlay properties are used to directly annotate the buffer. The documentation in which-func-mode actually points this out:

;; TODO LIST
;; ---------
;;     1. Dependence on imenu package should be removed.  Separate
;; function determination mechanism should be used to determine the end
;; of a function as well as the beginning of a function.
;;     2. This package should be realized with the help of overlay
;; properties instead of imenu--index-alist variable.

@stephe-ada-guru
Copy link
Collaborator

stephe-ada-guru commented Nov 13, 2021 via email

@joaotavora
Copy link
Owner

@sfllaw

Are you asking why this patch doesn’t install the hook? It does here, inside eglot--managed-mode.

No sorry, I wasn't making myself clear. I'm going to try to say more or less the same thing in three different ways :-)

  1. I was asking:
  • if currently which-func depends on imenu structures to work correctly, AND

  • if Eglot is already providing imenu structures

    then why should any new code be added to Eglot to support which-func?

  1. Another way to see point 1

    a. if it's possible to avoid adding a dependency of which-func in Eglot, I'd like to do so, even if that means changing some of which-func.el (in a backward compatible way, of course)

    b. if it's not possible to avoid this dependency, or somehow not desirable, then OK, let's add it this PR, but I'd like to be as minimal as possible.

  2. My other comment about imenu, which probably also confused you, is asking about Eglot's usage of imenu's "special" interfaces.
    I know from other issues (not very hard to find in the tracker, though I haven't done so now) that this usage is problematic and breaks some imenu clients, who don't understand it. If which-func were to be yet another such client, then it could make sense to revisit Eglot's usage of imenu and perhaps kill many birds with just one stone.

@joaotavora
Copy link
Owner

@sfllaw

Yeah, it seems like overloading imenu--index-alist to present rich location information was a good attempt but imenu’s API isn’t flexible enough for other clients to deal with? What kind of existing functionality would be lost?

You are asking the right questions, I think. But unfortunately, I have lost the answer to this (maybe the Commit log remembers?)

As an alternative, we could store the rich information returned by textDocument/documentSymbol in eglot--document-symbol-alist, which gets reduces to the simple elements in imenu--index-alist. But perhaps that would be better done in another PR?

That seems interesting. Especially so if it could somehow magically solve all the other imenu-related issues in addition to this which-func special-hook need. But yes, another PR.

@sfllaw
Copy link
Contributor Author

sfllaw commented Nov 17, 2021

That seems interesting. Especially so if it could somehow magically solve all the other imenu-related issues in addition to this which-func special-hook need. But yes, another PR.

@joaotavora I started drafting this implementation in #760. I would appreciate your thoughts about my approach.

@joaotavora joaotavora closed this in fdd87b7 Sep 8, 2022
@joaotavora
Copy link
Owner

Hi @sfllaw, I briefly tested the latest code with which-func-mode in a cpp file with clangd as the supporting server and it seems to work OK.

Can double check if anything is missing?

@sfllaw
Copy link
Contributor Author

sfllaw commented Sep 12, 2022

@joaotavora: It seems to work OK for me as well, so thank you for doing this! Also, I’m glad that you removed the magic closures!

bhankas pushed a commit to bhankas/emacs that referenced this pull request Sep 18, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
bhankas pushed a commit to bhankas/emacs that referenced this pull request Sep 19, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
bhankas pushed a commit to bhankas/emacs that referenced this pull request Sep 19, 2022
Fix #758, #536, #535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example #758, #536, #535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change

#758: joaotavora/eglot#758
#536: joaotavora/eglot#536
#535: joaotavora/eglot#535
#758: joaotavora/eglot#758
#536: joaotavora/eglot#536
#535: joaotavora/eglot#535
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this pull request Oct 12, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this pull request Oct 20, 2022
Fix joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.

Eglot's eglot-imenu returned a structure compliant with the rules
outlined in imenu--index-alist.  In particular, it returned some
elements of the form

  (INDEX-NAME POSITION GOTO-FN ARGUMENTS...)

The original intention (mine) must have been to allow fancy
highlighting of the position navigated to with a custom GOTO-FN.

Not only was access to that fanciness never implemented, but many
other imenu frontends do not support such elements.

See for example joaotavora/eglot#758, joaotavora/eglot#536, joaotavora/eglot#535.  And also related issues in other
packages:

colonelpanic8/flimenu#6
bmag/imenu-list#58

So it's best to remove this problematic feature for now.  It can be
added back later.

* eglot.el (eglot-imenu): Simplify.

* NEWS.md: Mention change
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants