Open slotThe opened 2 years ago
Ugh, this is pretty ugly. I wonder if this is something we could plausibly fix in HLS. It seems reasonable to have the doc of the actual function as the "first" bit of the hover, perhaps?
@michaelpj in fact there was, but they deprecated it although IMHO it is much more useful. Check MarkedString in the spec. The best from lsp-mode perspective is to have two items one with language = \
I meant changing HLS, not the spec :D probably we'd rather avoid deprecated stuff even if it is better
TBH, I don't quite understand the heuristic that's being used for which bit goes in the eldoc, could someone give me a one-sentence summary? Then we can maybe make HLS produce output that does the right thing.
TBH, I don't quite understand the heuristic that's being used for which bit goes in the eldoc, could someone give me a one-sentence summary? Then we can maybe make HLS produce output that does the right thing.
Having the type signature as the actual first bit of the response would get us most of the way there, I think. Currently, a typical response we want to process looks like this:
```haskell
$dFoldable :: Foldable []
```
* * *
```haskell
$dContravariant :: Contravariant f
```
* * *
```haskell
$dApplicative :: Applicative f
```
* * *
```haskell
folding :: forall (f :: * -> *) s a. Foldable f => (s -> f a) -> Fold s a
```
*Defined in ‘Control.Lens.Fold’*
*(lens-5.0.1)*
* * *
```haskell
_ :: (MultiMap k v -> [(k, v)])
-> ((k, v) -> f (k, v)) -> MultiMap k v -> f (MultiMap k v)
```
* * *
```haskell
_ :: forall (f :: * -> *) s a. Foldable f => (s -> f a) -> Fold s a
```
What we probably want to extract here is
folding :: forall (f :: * -> *) s a. Foldable f => (s -> f a) -> Fold s a
The default implementation (where contents
is a response the like above) for lsp-clients-extract-signature-on-hover
is
(car (s-lines (s-trim (lsp--render-element contents))))
which essentially just gets the first line (modulo the GFM markup), which would be $dFoldable :: Foldable []
here. If we pushed the type signature to the very front, we still could not quite use this (ime, it's not uncommon for the signature to span over multiple lines), but the override would be trivial: "get everything in the first Haskell GFM block".
What I did above more or less does the following:
I don't know whether HLS will ever actually return a signature across multiple lines, so reordering it might just be sufficient. It's probably better UX for the hover itself too!
I don't know where it happens (on the HLS side or the lsp-mode side) but we definitely receive multi-line type signatures in Emacs. For example, the function
iAmTooLong :: String -> String -> String -> String -> String -> String -> String -> String
iAmTooLong = undefined
will generate the response
```haskell
iAmTooLong :: String
-> String
-> String
-> String
-> String
-> String
-> String
-> String
```
*Defined at /home/slot/repos/haskell/sandbox/src/Main.hs:4:1*
By default, only iAmTooLong :: String
is shown in the minibuffer.
Great example. That seems like something that could plausibly be improved in lsp-mode
, some behaviour like "grab the entire contents of the first GFM block if there is one". WDYT @yyoncho ?
(For some reason since yesterday Ctrl-Enter now triggers close+comment instead of comment. I'm going insane.)
Any updates on this? FWIW, I've been using a variation of the code posted in the OP for quite a while now, and it never broke :)
I'd accept a PR that changes things, but I'd prefer a generic change in lsp-mode
if possible.
Currently, when hovering over an identifier, the first "thing" that we can grab is shown in the minibuffer area (as per the default implementation of
lsp-clients-extract-signature-on-hover
). While this is probably fine for a lot of languages, for Haskell this seems problematic. As soon as there is at least one type class involved, the hover info will just show the instantiation of that type class and not the signature of the function at point:I find this to be a bit unintuitive. It's true that knowning the specific instantiations of type classes can be very useful at times, but if one wants to know such things, there is always
lsp-ui-doc-{show,glance}
orlsp-describe-thing-at-point
(which also show all of them and not just the first one in what is probably an arbitrary ordering).It's possible to override
lsp-clients-extract-signature-on-hover
with a more appropriate implementation, but that knowledge is somewhat buried inside e.g. the rust documentation, referring to this unmerged pr. Since I think Haskell suffers from this problem as much as Rust does, it might be worth adding it to the documentation here (or somewhere else, I'm not super familiar with how documentation is structured in this project). For example, I have the following in mylsp-mode
configurationwhich, in the above example, produces the "expected" output of
As noted in https://github.com/emacs-lsp/lsp-mode/pull/1740, while this implementation works (even for Rust, I might add) it's probably too hacky/brittle to include somewhere verbatim, but I think it's worth to perhaps add some documentation somewhere on how to get (imo) sane hover behaviour.