-
Notifications
You must be signed in to change notification settings - Fork 201
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
Implement code lens #71
Conversation
When I read the spec, I don't understand very well what code lens are. Can you explain in your words, maybe with examples? I'd like to find the best available Emacs abstraction to represent them |
They're clickable overlays that are placed on symbols. The eclipse.jdt.ls language servers puts them on function and class names. They provide information about a symbol and action to perform on this symbol. E.g. the eclipse server puts on each symbol the number of references to it, and a clickable action "find references". |
I rewrote everything after I realized that the previous version had some flaws:
I tried vscode to see how the code lens are implemented there. The current version is very similar, although unlike in vscode, the code lens are not visible at all times. Currently you have to toggle them with the command This command will make the buffer read only and enable a new minor mode which provides keybindings Tell me what you think. If you think that a minor mode is too much, I believe I could also use a transient map, or simply read the events (go to next/previous lens, act on it) from the minibuffer. That will make the command self-contained. |
If you want to test this, I recommend cquery and eclipse.jdt.ls servers. |
@joaotavora, for what it's worth, this vscode blog post on code lenses helped me to get a better understanding of what they are and how they can be used. |
Thanks. From what I understand they're very valuable for editors which don't have the capabilities of Emacs. For example, in emacs you can But that doesn't mean this shouldn't be supported. I'm evaluating @mkcms proposal. I mostly need to sit down and configure Java in a medium or small sized project so I can start testing all these features, which seem to be big in that language. |
I agree with you. My own take away from the article was the importance of distinguishing between the links (overlays), actions, and the displaying of actions. I see lenses (the overlays) mostly as a discoverability tool, but would almost certainly leave them disabled in my own configuration, provided that I could independently access whatever actions are made available by the code lens. They could still be very useful for being made aware of obscure or less commonly used capabilities. Similarly, finding a reference via an action might still use |
Unlike in vscode, this implementation is not automatic. You only see the lenses when you explicitly toggle them with |
I definitely took note of that, and do think it's the right approach. |
For displaying a list of commands based on the text properties and/or overlays at a particular buffer position, it might be worth considering using prop-menu. We use this in Something like this could be used to have the commands always be available without putting the buffer in a read-only mode, but without the visual noise of some other approaches. |
One more potential gain from |
@david-christiansen Nice package. Would it be possible to have support for it and at the same time not actually require it? |
Would something like this be too ugly? (with-eval-after-load prop-menu
(setq-local prop-menu-item-functions '(eglot-prop-menu-items-function))
(define-key eglot-mode-map (kbd "C-c C-SPC") 'prop-menu-by-completing-read)
(define-key eglot-mode-map (kbd "<mouse-3>") 'prop-menu-show-menu)) If the concern for avoiding a dependency is the eventual desire to put eglot into ELPA or Emacs proper, I'm happy to assign copyright to the FSF for the library. |
@joaotavora Should I continue this develop this branch, or do you think code lens shouldn't be included in eglot? I personally find them distracting (when they're present all the time), but when browsing code they have some use. I know that ccls, cquery and eclipse.jdt.ls servers all have code lens support. |
I'll be looking at this in the near future. What servers currently support codelens? EclipseJDT and some other one? |
Like I said above, ccls and cquery :-) |
sorry 😊 |
* eglot.el (eglot-code-lens): New face. (eglot--lens-mode): New minor mode. (eglot-lens-act, eglot-next-lens, eglot-previous-lens eglot-code-lens): New commands.
Hey, I finally tried this with |
Ha, that's very interesting. I've never even considered that. Can flymake be modified to display some special diagnostics different than others? |
Not yet :-) |
* eglot.el (eglot--lsp-interface-alist): New CodeLens interface. (eglot--current-flymake-report-fn) (eglot--unreported-diagnostics): Move up here. (eglot--report-diagnostics): New helper. (eglot-handle-notification textDocument/publishDiagnostics): Use it. (eglot--post-self-insert-hook, eglot--pre-command-hook) (eglot--before-change): Fix docstring. (eglot-lens-act, eglot-next-lens, eglot-previous-lens): Unimplement. (eglot-code-lens): Implement using new Flymake. (eglot--eclipse-jdt-contact): Fix docstring.
Just pushed a new Flymake to Emacs master, should be on GNU ELPA soon. Use it to test the new approach (which is very broken still). |
It's pretty cool. Although it messes up my display, because it "splits" the line in two to show the lens there. This happens when the end of a lens region is not the end of some line. |
Out of curiosity, would you mind sharing a screenshot of what it looks like? |
Here's screenshot of my version. @joaotavora's looks a bit different because of the display issue I described above. |
The screenshot looks great, however, the code lenses occupy some vertical space. Putting code lenses at line ends is better IMHO. I've experimented with the idea before but my elisp-fu isn't strong enough to tame display properties https://www.reddit.com/r/emacs/comments/9k3rf6/put_a_codelens_overlay_sticking_in_the_end_of_the/ |
@joaotavora What's the status of this? I'd love to have proper code lens support in eglot (haskell-language-server and rust-analyzer both use them to great effect in displaying type signatures) |
@mkcms Did you get any further with this? Thanks! |
I would love to see this feature implemented. My immediate need is that it would be nice when editing a test--which in Go is a (Aside: this particular feature seems like it belongs in the core LSP protocol since the concept is entirely language-agnostic.) Ideally, the overlay offering code lenses would be queried automatically after each edit to the file, avoiding the clumsiness of an extra step to request the overlay. |
Did the flymake version get merged or is it testable somehow? (Should code lenses show with flymake-show-buffer-diagnostics or is there a different function?) |
AFAIK every code developed for Flymake has been merged. But Eglot code lens support has not. I didn't even remember authoring the commit above (and I forgot what codelenses are, to be honest). |
I think they're basically code actions that come with a button label, e.g. in the "Refresh …" text is not part of the source, but provided by the code lens, and you can click it to run the action (which in this case does the haskell equivalent of As others have mentioned, the useful part isn't really the button (I would prefer not to see it), but getting access to these code actions which for many language servers are often just available as code lenses. |
Can you, please, list a couple of those language servers? Thanks. |
The haskell-language-server uses them. For example for evaluating example code snippets in the documentation (as shown in the screenshot above). So it would be awesome if eglot would support these code lenses as well. |
Sure. But that is just one, not "many". Can you name additional language servers that only provide some code actions in code lenses and not in any other way? Thanks. |
From the top of my head:
As far as I know, none of these features are available as code actions, only as lenses (though type signatures may be available as local hover actions). |
Thank you for the list.
At least references can be accessed by other means ( I agree the code-lenses support would be a useful addition, but I do not think it is a show-stopper in general. |
Yes, it seems code lenses are a UI-opinionated generic way to access LSP functionality that could be accessible via other commands (finding definition/references to go to places, code actions to transform)
I agree. Fairly useful. And probably implementing them with Flymake (as was my initial idea) isn't the best. A hand-rolled implementation like for inlay hints (based on |
The LSP server for Go (gopls) exposes a handful of features via code lenses, but none of them are enabled by default because the UI elements tend to be distracting. We have found that code actions tend to be a less intrusive (if less discoverable) way to expose the same features, and we plan to migrate these features towards code actions. So, contra my earlier comment, I don't have any pressing desire for eglot code lens support. |
Run and Debug relies on the Runnables lsp-extension. Extensions are usually out of scope for Eglot. (Eglot-x does support Runnables and the |
This is a work in progress code lens implementation.
What's currently missing is executing commands.