Skip to content

Document (?) how to change the eldoc signature #151

Open
@slotThe

Description

@slotThe

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:

2022-06-29-110620_636x131_scrot

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} or lsp-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 my lsp-mode configuration

(defun slot/lsp-get-type-signature (lang str)
  "Get LANGs type signature in STR.
Original implementation from https://github.com/emacs-lsp/lsp-mode/pull/1740."
  (let* ((start (concat "```" lang))
         (groups (--filter (s-equals? start (car it))
                           (-partition-by #'s-blank? (s-lines (s-trim str)))))
         (name-at-point (symbol-name (symbol-at-point)))
         (type-sig-group (car
                          (--filter (s-contains? name-at-point (cadr it))
                                    groups))))
    (->> (or type-sig-group (car groups))
         (-drop 1)                      ; ``` LANG
         (-drop-last 1)                 ; ```
         (-map #'s-trim)
         (s-join " "))))

(cl-defmethod lsp-clients-extract-signature-on-hover 
  (contents (_server-id (eql lsp-haskell)))
  "Display the type signature of the function under point."
  (let* ((sig (slot/lsp-get-type-signature "haskell" (plist-get contents :value))))
    (lsp--render-element (concat "```haskell\n" sig "\n```"))))

which, in the above example, produces the "expected" output of

2022-06-29-120008_635x132_scrot

As noted in emacs-lsp/lsp-mode#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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions