-
Notifications
You must be signed in to change notification settings - Fork 200
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
Provide a decent C-u M-. with completion. (Was: Workspace Symbol can have a better UI) #131
Comments
Eglot shouldn't implement such a feature, instead it should be implemented in a separate package so it can work with all xref backends. It should be pretty easy to do with e.g. ivy (not tested much): (defun my/dynamic-xref-apropos ()
(interactive)
(let ((buf (current-buffer)))
(ivy-read "Search for pattern: "
(lambda (str)
(cond
((< (length str) 1) (counsel-more-chars 1))
(t
(with-current-buffer buf
(when-let ((backend (xref-find-backend)))
(unless (eq backend 'etags)
(mapcar
(lambda (xref)
(let ((loc (xref-item-location xref)))
(propertize
(concat
(when (xref-file-location-p loc)
(with-slots (file line column) loc
(format "%s:%s:%s:"
(propertize (file-relative-name file)
'face 'compilation-info)
(propertize (format "%s" line)
'face 'compilation-line
)
column)))
(xref-item-summary xref))
'xref xref)))
(xref-backend-apropos backend str))))))))
:dynamic-collection t
:action (lambda (item)
(xref--pop-to-location (get-text-property 0 'xref item)))))) |
Abstractly, I agree that this indeed is out of scope of eglot. Practically speaking, I think having an off-the-shelf solution for this problem is important, because it significantly improves the usability of a core feature, even if that solution is "add this snippet to your .init.el". |
There is an external package to support this feature. It works on top of |
@danielmartin I would like to update Eglot in this regard, as I think Keep in mind I don't use consult or know much about it. Whatever enhancements are to be added should be added in terms of Emacs UI primitives. |
It produces the same result as
In terms of Emacs UI primitives, the closest thing in vanilla Emacs may be |
yes, that would be it. I'll see what can be done |
* NEWS.md: Mention change. * eglot.el (eglot--lsp-interface-alist): Add WorkspaceSymbol (eglot--xref-workspace-symbols-completion-table): New variable (xref-backend-identifier-completion-table): Improve. (xref-backend-definitions): Use eglot--xref-workspace-symbols-completion-table.
@danielmartin Can you test the commit to that branch I just pushed? It's minimally tested, but works well with completion in vanilla Emacs 28 with Anyway It's a bit hacky because the |
Thanks! The main problem I see is that the list of identifiers is far from being complete (I also tested So I think we'd need to build the completion table asynchronously, ie. as the user enters characters in the minibuffer. I'm not very familiar with the different completion mechanisms, but that's probably what the GNU ELPA |
They're not easy, but they're not as rocket-sciency as on may think. An example of them is already in |
* eglot.el (eglot--xref-workspace-symbols-completion-table): Remove. (eglot--workspace-symbols-chosen-completion): New variable. (xref-backend-identifier-completion-table): Complicate. (xref-backend-definitions): Simplify. (completion-category-overrides): Register a category and a style here. (completion-styles-alist): Add eglot--lsp-backend-style style (eglot--lsp-backend-style-call): New funtion. (eglot--lsp-backend-style-all-completions): New function. (eglot--lsp-backend-style-try-completion): New function.
Can you give this last version a try? |
* eglot.el (xref-backend-identifier-completion-table): Simplify. (xref-backend-definitions): Cleanup whitespace
None of them look very good. Grouping probably also needs a sorting function. * eglot.el (xref-backend-identifier-completion-table): Add stuff.
Now it completes every symbol in the workspace, thanks. However, when I choose any symbol and press RET I get "No definitions found for: ". |
That's odd, can you explain how you are launching emacs? Do you have some special configuration etc. This works for me, as long as I have
It also works without |
Thanks. I can't try this out right now and comment in detail, but the approach looks quite reasonable. 👍 Happy to see this feature materialize. |
João Távora ***@***.***> writes:
That's odd, can you explain how you are launching emacs? Do you have
some special configuration etc. This works for me, as long as I have
`clangd` installed (I suppose you do, too)
```
~/Source/Emacs/emacs/src/emacs -Q -L ~/Source/Emacs/eglot -l eglot ~/tmp/something.cpp -f fido-vertical-mode -f eglot
```
It also works without `fido-vertical-mode` of course.
What I see is that the go to definition goes to the definition of the
symbol at point, not the symbol that you selected with completion. So,
if the point is not at any symbol, it returns an error.
Here's an example of Eglot's verbose stderr when I do C-u M-. Symbol RET
with point at line 8 of Foo.cpp:
V[10:34:09.042] <<< {"id":1045,"jsonrpc":"2.0","method":"textDocument/definition","params":{"position":{"character":0,"line":7},"textDocument":{"uri":"file:///Foo.cpp"}}}
I[10:34:09.042] <-- textDocument/definition(1045)
V[10:34:09.042] ASTWorker running Definitions on version 0 of Foo.cpp
I[10:34:09.042] --> reply:textDocument/definition(1045) 0 ms
V[10:34:09.042] >>> {"id":1045,"jsonrpc":"2.0","result":[]}
If I'm not mistaken, it should use the textDocument, position, etc. from
the reply to the workspace/symbol call instead.
|
* eglot (eglot--workspace-symbols-cache): Move closer to point of usage. Don't clear on every command. (eglot--recover-workspace-meta): Be aware of minibuffer.el improper lists. (eglot--pre-command-hook): Simplify. (xref-backend-identifier-completion-table): Clear cache here.
… (tm) The symbols returned by the LSP server must be converted to unique strings if Emacs is to present them in a list. On the other hand, the search operates on the pattern and is completely controlled by the backend. There is not much Eglot, the LSP client, can do about this. Decided to present the unique string to the user, even though it could be hidden. All the manner of :annotation-function, :affixation-function, :group-funcion etc didn't seem to add much value. Grouping was especially useless, since it makes sense to respect the LSP server's account of sorting score, so that better results bubble up to the top. * eglot.el (xref-backend-identifier-completion-table): Uniquify symbols with containerName and kind.
I was asking about a reproducible recipe, i.e. something that I can run in my machine to observe the same error you observe. Anyway, it might not matter. Please try out the very latest version of the branch, commit d178736. The "metadata" recovery process has been tweaked there. If the problem still happens, then please provide an |
João Távora ***@***.***> writes:
> What I see is that the go to definition goes to the definition of the
> symbol at point, not the symbol that you selected with completion. So,
> if the point is not at any symbol, it returns an error.
I was asking about a reproducible recipe, i.e. something that I can run in my machine to observe the same error you observe.
Anyway, it might not matter. Please try out the very latest version of the branch, commit d178736. The "metadata" recovery process has been tweaked there.
If the problem still happens, then please provide an `emacs -Q` reproduction recipe, preferably for the `clangd` server.
Thanks, it works now.
|
OK, then just to confirm a suspicion, you aren't using a simple |
I use mct (https://elpa.gnu.org/packages/mct.html). |
OK. This would maybe point to a slight non-conformance of that framework: the Are you actually using |
…with the LSP identifier guess If the user is not requesting a prompt, opt for the safer approach which is to get the location from textDocument/definition, not from workspace/symbol. Because of things like function overloading, the latter is not always successful in finding exactly the definition of the thing one is invoking M-. on. This requires using an xref-internal symbol, which is kind of unfortunate. * eglot.el (xref-backend-identifier-at-point): Rework.
it's mostly useful for developers/debugger. It's better to have the latter remember to set it than users being hindered by it. See joaotavora/eglot#131 (comment) * eglot.el (eglot-strict-mode): default to nil.
* NEWS.md: Mention change. * eglot.el (eglot--lsp-interface-alist): Add WorkspaceSymbol (eglot--workspace-symbols-cache): New variable. (eglot--recover-workspace-meta): New helper. (xref-backend-identifier-completion-table): Complicate. (xref-backend-definitions): Complicate. (completion-category-overrides): Register a category and a style here. (completion-styles-alist): Add eglot--lsp-backend-style style (eglot--lsp-backend-style-call): New funtion. (eglot--lsp-backend-style-all-completions): New function. (eglot--lsp-backend-style-try-completion): New function.
…entifier-completion-table Doesn't look very good. * eglot.el (xref-backend-identifier-completion-table): Add stuff.
…omeone somewhere (tm) The symbols returned by the LSP server must be converted to unique strings if Emacs is to present them in a list. On the other hand, the search operates on the pattern and is completely controlled by the backend. There is not much Eglot, the LSP client, can do about this. Decided to present the unique string to the user, even though it could be hidden. All the manner of :annotation-function, :affixation-function, :group-funcion etc didn't seem to add much value. Grouping was especially useless, since it makes sense to respect the LSP server's account of sorting score, so that better results bubble up to the top. * eglot.el (xref-backend-identifier-completion-table): Uniquify symbols with containerName and kind.
eglot--recover-workspace-symbol-meta had a bug that still made it choke on improper lists. Also, when simply M-. to the thing at point, let's not lose time on iterating a potentially out-of-date eglot--workspace-symbols-cache. So clear it early in the pre-command-hook. * eglot.el (eglot--workspace-symbols-cache): Move up. (eglot--pre-command-hook): Clear eglot--workspace-symbols-cache here. (eglot--recover-workspace-symbol-meta): Check for consp.
…fier at point" * eglot.el (eglot--workspace-symbols): New helper. (xref-backend-identifier-completion-table): Rework. (xref-backend-identifier-at-point): Rework.
…with the LSP identifier guess If the user is not requesting a prompt, opt for the safer approach which is to get the location from textDocument/definition, not from workspace/symbol. Because of things like function overloading, the latter is not always successful in finding exactly the definition of the thing one is invoking M-. on. This requires using an xref-internal symbol, which is kind of unfortunate. * eglot.el (xref-backend-identifier-at-point): Rework.
it's mostly useful for developers/debugger. It's better to have the latter remember to set it than users being hindered by it. See joaotavora/eglot#131 (comment) * eglot.el (eglot-strict-mode): default to nil.
* NEWS.md: Mention change. * eglot.el (eglot--lsp-interface-alist): Add WorkspaceSymbol (eglot--workspace-symbols-cache): New variable. (eglot--recover-workspace-meta): New helper. (xref-backend-identifier-completion-table): Complicate. (xref-backend-definitions): Complicate. (completion-category-overrides): Register a category and a style here. (completion-styles-alist): Add eglot--lsp-backend-style style (eglot--lsp-backend-style-call): New funtion. (eglot--lsp-backend-style-all-completions): New function. (eglot--lsp-backend-style-try-completion): New function. #131: joaotavora/eglot#131
…ion-table Doesn't look very good. * eglot.el (xref-backend-identifier-completion-table): Add stuff. #131: joaotavora/eglot#131
… (tm) The symbols returned by the LSP server must be converted to unique strings if Emacs is to present them in a list. On the other hand, the search operates on the pattern and is completely controlled by the backend. There is not much Eglot, the LSP client, can do about this. Decided to present the unique string to the user, even though it could be hidden. All the manner of :annotation-function, :affixation-function, :group-funcion etc didn't seem to add much value. Grouping was especially useless, since it makes sense to respect the LSP server's account of sorting score, so that better results bubble up to the top. * eglot.el (xref-backend-identifier-completion-table): Uniquify symbols with containerName and kind. #131: joaotavora/eglot#131
eglot--recover-workspace-symbol-meta had a bug that still made it choke on improper lists. Also, when simply M-. to the thing at point, let's not lose time on iterating a potentially out-of-date eglot--workspace-symbols-cache. So clear it early in the pre-command-hook. * eglot.el (eglot--workspace-symbols-cache): Move up. (eglot--pre-command-hook): Clear eglot--workspace-symbols-cache here. (eglot--recover-workspace-symbol-meta): Check for consp. #131: joaotavora/eglot#131
* eglot.el (eglot--workspace-symbols): New helper. (xref-backend-identifier-completion-table): Rework. (xref-backend-identifier-at-point): Rework. #131: joaotavora/eglot#131 #314: joaotavora/eglot#314
If the user is not requesting a prompt, opt for the safer approach which is to get the location from textDocument/definition, not from workspace/symbol. Because of things like function overloading, the latter is not always successful in finding exactly the definition of the thing one is invoking M-. on. This requires using an xref-internal symbol, which is kind of unfortunate. * eglot.el (xref-backend-identifier-at-point): Rework. #131: joaotavora/eglot#131 #314: joaotavora/eglot#314
it's mostly useful for developers/debugger. It's better to have the latter remember to set it than users being hindered by it. See joaotavora/eglot#131 (comment) * eglot.el (eglot-strict-mode): default to nil.
* NEWS.md: Mention change. * eglot.el (eglot--lsp-interface-alist): Add WorkspaceSymbol (eglot--workspace-symbols-cache): New variable. (eglot--recover-workspace-meta): New helper. (xref-backend-identifier-completion-table): Complicate. (xref-backend-definitions): Complicate. (completion-category-overrides): Register a category and a style here. (completion-styles-alist): Add eglot--lsp-backend-style style (eglot--lsp-backend-style-call): New funtion. (eglot--lsp-backend-style-all-completions): New function. (eglot--lsp-backend-style-try-completion): New function. GitHub-reference: fix joaotavora/eglot#131
Doesn't look very good. * eglot.el (xref-backend-identifier-completion-table): Add stuff. GitHub-reference: per joaotavora/eglot#131
The symbols returned by the LSP server must be converted to unique strings if Emacs is to present them in a list. On the other hand, the search operates on the pattern and is completely controlled by the backend. There is not much Eglot, the LSP client, can do about this. Decided to present the unique string to the user, even though it could be hidden. All the manner of :annotation-function, :affixation-function, :group-funcion etc didn't seem to add much value. Grouping was especially useless, since it makes sense to respect the LSP server's account of sorting score, so that better results bubble up to the top. * eglot.el (xref-backend-identifier-completion-table): Uniquify symbols with containerName and kind. GitHub-reference: per joaotavora/eglot#131
eglot--recover-workspace-symbol-meta had a bug that still made it choke on improper lists. Also, when simply M-. to the thing at point, let's not lose time on iterating a potentially out-of-date eglot--workspace-symbols-cache. So clear it early in the pre-command-hook. * eglot.el (eglot--workspace-symbols-cache): Move up. (eglot--pre-command-hook): Clear eglot--workspace-symbols-cache here. (eglot--recover-workspace-symbol-meta): Check for consp. GitHub-reference: per joaotavora/eglot#131
* eglot.el (eglot--workspace-symbols): New helper. (xref-backend-identifier-completion-table): Rework. (xref-backend-identifier-at-point): Rework. GitHub-reference: per joaotavora/eglot#131 GitHub-reference: per joaotavora/eglot#314
If the user is not requesting a prompt, opt for the safer approach which is to get the location from textDocument/definition, not from workspace/symbol. Because of things like function overloading, the latter is not always successful in finding exactly the definition of the thing one is invoking M-. on. This requires using an xref-internal symbol, which is kind of unfortunate. * eglot.el (xref-backend-identifier-at-point): Rework. GitHub-reference: per joaotavora/eglot#131 GitHub-reference: per joaotavora/eglot#314
it's mostly useful for developers/debugger. It's better to have the latter remember to set it than users being hindered by it. See joaotavora/eglot#131 (comment) * eglot.el (eglot-strict-mode): default to nil.
* NEWS.md: Mention change. * eglot.el (eglot--lsp-interface-alist): Add WorkspaceSymbol (eglot--workspace-symbols-cache): New variable. (eglot--recover-workspace-meta): New helper. (xref-backend-identifier-completion-table): Complicate. (xref-backend-definitions): Complicate. (completion-category-overrides): Register a category and a style here. (completion-styles-alist): Add eglot--lsp-backend-style style (eglot--lsp-backend-style-call): New funtion. (eglot--lsp-backend-style-all-completions): New function. (eglot--lsp-backend-style-try-completion): New function. GitHub-reference: fix joaotavora/eglot#131
Doesn't look very good. * eglot.el (xref-backend-identifier-completion-table): Add stuff. GitHub-reference: per joaotavora/eglot#131
The symbols returned by the LSP server must be converted to unique strings if Emacs is to present them in a list. On the other hand, the search operates on the pattern and is completely controlled by the backend. There is not much Eglot, the LSP client, can do about this. Decided to present the unique string to the user, even though it could be hidden. All the manner of :annotation-function, :affixation-function, :group-funcion etc didn't seem to add much value. Grouping was especially useless, since it makes sense to respect the LSP server's account of sorting score, so that better results bubble up to the top. * eglot.el (xref-backend-identifier-completion-table): Uniquify symbols with containerName and kind. GitHub-reference: per joaotavora/eglot#131
eglot--recover-workspace-symbol-meta had a bug that still made it choke on improper lists. Also, when simply M-. to the thing at point, let's not lose time on iterating a potentially out-of-date eglot--workspace-symbols-cache. So clear it early in the pre-command-hook. * eglot.el (eglot--workspace-symbols-cache): Move up. (eglot--pre-command-hook): Clear eglot--workspace-symbols-cache here. (eglot--recover-workspace-symbol-meta): Check for consp. GitHub-reference: per joaotavora/eglot#131
* eglot.el (eglot--workspace-symbols): New helper. (xref-backend-identifier-completion-table): Rework. (xref-backend-identifier-at-point): Rework. GitHub-reference: per joaotavora/eglot#131 GitHub-reference: per joaotavora/eglot#314
If the user is not requesting a prompt, opt for the safer approach which is to get the location from textDocument/definition, not from workspace/symbol. Because of things like function overloading, the latter is not always successful in finding exactly the definition of the thing one is invoking M-. on. This requires using an xref-internal symbol, which is kind of unfortunate. * eglot.el (xref-backend-identifier-at-point): Rework. GitHub-reference: per joaotavora/eglot#131 GitHub-reference: per joaotavora/eglot#314
it's mostly useful for developers/debugger. It's better to have the latter remember to set it than users being hindered by it. See joaotavora/eglot#131 (comment) * eglot.el (eglot-strict-mode): default to nil.
Hi!
My understanding is that currently workspace/Symbols request is exposed via
xref-find-apropos
command, which takes a query as a parameter and renders a list of results.However, IntelliJ and VS Code use a significantly different UI for this feature: instead of supping the query string up-front, the results are re displayed immediately as the user types query characters. That is, the interface is like that of Helm, but, instead of filtering a complete list on client's side, the langauge server is re-queried continuously.
I think that such UX can significantly improve the usability of this (imo, the most important) feature, and it would be cool if eglot could do this out of the box.
The text was updated successfully, but these errors were encountered: