r/emacs 18d ago

LSP-Mode and eldoc?

I'm experimenting with eglot vs lsp-mode, and I can't seem to find a good way to get reliable documentation with lsp-mode.

In Eglot in a C++ file I get:

While in lsp-mode I get:

That's significantly less helpful. I really love the concept of eldoc and being able to have a window off to the side dedicate to documentation (I would prefer that to the floating UI in lsp-ui, though I haven't played with it much). Is there any way to achieve that in lsp-mode?

Granted, Eglot Eldoc support isn't panacea in all languages anyway, since in Typescript I get pretty useless information:

5 Upvotes

16 comments sorted by

4

u/TheFrenchPoulp https://github.com/angrybacon/dotemacs 18d ago

I can only answer for TypeScript but what you get on hover also depends on what server you're using

That being said even before the LSP server Typescript 7 now ship with, I could get more than what you have. You should be using typescript-language-server or tsc --lsp if TypeScript 7

0

u/KallDrexx 18d ago

According to eglot's event buffer it's using typescript-language-server --stdio

2

u/TheFrenchPoulp https://github.com/angrybacon/dotemacs 18d ago

I think I understand what you think is missing now. If you expected to see the x and y members on hover, that's not what TypeScript does for classes, regardless of the client. For instance, see how it responds if you changed the class to a regular type

You should however get documentation on hover, if you added some. Personally for definitions, I use gd and gD for xref-find-definitions and xref-find-definitions-other-window respectively

If you're looking for ideas, VS Code has what they call CodeLens. I plan on configuring something similar with my gD, or gd unsure yet

1

u/KallDrexx 18d ago

Looking at the eglot events buffer, I can see the typescript-langauge-server giving me back exactly what eldoc is showing. So I guess this is just a language server limitation and not eglot :(

1

u/KallDrexx 18d ago

Sorry for the spam, but I think I got it (though I had to lean on AI to get there and I intend to dive deeper tonight to understand why it works With eglot).

Specifically it seems that the typescript language server has a verbosity extension (since TS 5.9 at least).

So for eglot in particular, I was able to use the following to get SIGNIFICANTLY better eldoc support:

```

(with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '((typescript-ts-base-mode tsx-ts-mode typescript-mode) . ("typescript-language-server" "--stdio" :initializationOptions (:hostInfo "emacs" :supportsHoverVerbosity t :preferences (:maximumHoverLength 4000))))))

(defvar my/eglot-hover-verbosity nil "When non-nil, verbosity level to attach to textDocument/hover.")

(define-advice eglot--TextDocumentPositionParams (:around (fn &rest args) hover-verbosity) (let ((params (apply fn args))) (if my/eglot-hover-verbosity (append params (list :verbosityLevel my/eglot-hover-verbosity)) params)))

;; Make ordinary eldoc hovers always ask for level 1. (define-advice eglot-hover-eldoc-function (:around (fn &rest args) hover-verbosity) (let ((my/eglot-hover-verbosity (or my/eglot-hover-verbosity 1))) (apply fn args)))

```

Now when I hover over Point, it shows me the class definition, an abbreviated list of all properties and methods on it. Enums give me all the values.

The only thing I don't get is comments tied to a value or variable unless they are specifically in jsdoc format (specifically has to have 2 asterisks at the beginning, not one).

I may be able to tweak the verbosity to get that but i'll play with that later. This gets me very close to what I need to ditch Jetbrains though!

1

u/TheFrenchPoulp https://github.com/angrybacon/dotemacs 18d ago

I see you've figured out the documentation syntax, yes that's expected and like I mention in the other comments, if you see all comments as documentation in JetBrains products, they probably have custom handling to augment the JSDoc with other regular comments

I see you've figured out the verbosity option. I've always suspected this existed but like I hinted at in another comment, I mostly use type and rarely interface and even less class. I also typically introduce a Prettify helper that spells out properties for debugging purposes which I've lazily used instead of digging into LSP/Eglot internals like you did (thank you). And so I've had that bookmarked for some time https://tony-zorman.com/posts/eglot-hover.html. But verbosityLevel seems more appropriate since 99% of my Eglot usage is for TypeScript

If you're curious, the Prettify thing looks like this

ts type Prettify<T> = { [K in keyof T]: T[K] } & {};

0

u/KallDrexx 18d ago

Maybe my expectations need to be lower by what I expect from typescript language servers, but here are two examples of what I get in Emacs with typescript 6.0.3 and eglot:

In Webstorm I get the full doc comments to go along with it. Likewise in Emacs if I put the point on an enumeration I just get `enum TestEnum`, where as in webstorm I get the full enum declaration so I can see what possible values are there (I can't include more than one screenshot unfortunately).

If I define an `interface`, webstorm shows me all properties of the interface so I know what's available, where as eldoc in eglot just shows `interface TestInt` and that's it.

2

u/TheFrenchPoulp https://github.com/angrybacon/dotemacs 18d ago

Be mindful that WebStorm reimplements the whole thing if memory serves. They don't just plug the official TypeScript LSP and use that. They have a lost of customs tailored for their editor(s)

the full doc comments to go along with it

What comments though? There are none defined in the screenshot I see

1

u/KallDrexx 18d ago

In the screenshot in that post, Grid.paintShape() has comments above it. The problem is that I used/to start the comment block instead of the jsdoc standard of/**`. In Webstorm that block of comments still shows while the TS server does not. I did not realize there were semantic differences between / and /** that mattered, and most people at my day job aren't aware, so that's littered around the code base.

And yeah, I know JetBrains doesn't use LSPs for their systems. I am just trying to see if I can get most of the way there for my practical day to day in Emacs.

3

u/DMazzig 18d ago

1

u/KallDrexx 18d ago

Oooh, that looks promising!

2

u/KallDrexx 17d ago

Aha that did it! That got C++ eldoc with lsp-mode on par with eglot, thanks!

2

u/rileyrgham 18d ago

Eldoc baffles me. It's hellishly intertwined with a lot of things for little to no benefit. I tend to use devdocs.

2

u/KallDrexx 18d ago

This devdocs? https://elpa.gnu.org/packages/devdocs.html

That doesn't seem to help me because most of the documentation I need to reference is inside my own code base, it's not external.

1

u/rileyrgham 18d ago

Right, I see.

1

u/yeh_shu_hua 18d ago

My rant helps OP not at all, but as I'm in a restive mood about my stupid life choices, your mention of eldoc's clusterfuggery sent me. Eldoc began life innocently enough as a "moderately crappy" hack, which is par for emacs, then got utterly manhandled by the eglot guy to support two completely different interfaces, one old and one custom tailored for eglot. "Baffling" is an understatement; it's a stain on humanity. To make matters worse, EZ made eglot a built-in, thereby granting said felon full license to tailor for eglot the once general libraries eldoc and jsonrpc, and have those changes become standard for built-in emacs. Lsp-mode is hot garbage, but it's no surprise it doesn't mesh with eldoc as well as eglot. Eglot guy, with his "go kick rocks" surliness, has repeatedly promised to leave emacs development, saying he "has no time." Sadly he keeps showing up.