haskell / haskell-language-server

Official haskell ide support via language server (LSP). Successor of ghcide & haskell-ide-engine.
Apache License 2.0
2.61k stars 352 forks source link

Inlay hints usage #2938

Open July541 opened 2 years ago

July541 commented 2 years ago

In order to prevent spam, I open a thread to discuss about the inlay hint usage in Haskell.

Previous info is here: https://github.com/haskell/haskell-language-server/issues/2019#issuecomment-1144502854

lsp-3.17 had supported inlay hint, in which can embed some useful info, it wildly used by displaying function parameter names in other languages. But it is not suitable in Haskell since Haskell have a lot of currying, which looks not valid to display parameter name in Haskell.

Sample of inlay hint: image

I don't want Haskell missing this straightforward function, so I wrote these to discuss what we can do to use inlay hint best, here are some I'd like:

  1. Show type signature for let expressions

    f = let g {- inlay hint here, should be `:: Bool` -}= True
     in g
  2. Show operator fixity as mentioned in https://github.com/haskell/haskell-language-server/issues/2019#issuecomment-1144499665

All these are initial ideas for discussion, feel free to put forward any suggestions:)

drsooch commented 2 years ago

+1 for let bindings.

I'd have to see what the fixity one actually looks like, but in my head it seems like overload.

pepeiborra commented 2 years ago

+1 for let bindings too

Can we use this to show the implicit imports list, instead of a code lens?

July541 commented 2 years ago

Can we use this to show the implicit imports list, instead of a code lens?

Not sure, I haven't seen any inlay hint in a new line. But is there any shortcoming for code lens?

pepeiborra commented 2 years ago

The idea is to show the implicit imports list inline, not in a new line. We have wanted this for a while:

https://github.com/haskell/haskell-language-server/issues/426#issuecomment-698216817

michaelpj commented 2 years ago

Note that inlay hints aren't supported by the lsp library yet. I'm working on generating the types from the new machine-readable version, which will hopefully include this, but it may be a while.


More ideas

Type signatures

Lambda arguments? i.e.

\x {- :: Int -} -> ...

Function arguments? i.e.

foo x {- :: Int -}

(probably not, a bit redundant with the main type signature?)

Bindings in do blocks? i.e.

x {- :: Int -} <- ...

These are all really special cases of "put an inlay hint every time a variable is bound without a type signature", but I think that would probably be too much in many cases. But might be worth trying to see if it's unbearable! Maybe the general case is what we want.

Implicit names

Record wildcards?

x{... {- foo, bar, baz -}}

An explicit imports inlay hint is arguably an example of this!

Misc

Record names in positional record construction?

MyRec {- foo= -} a {- bar= -} b {- baz= -} c
drsooch commented 2 years ago

These are all really special cases of "put an inlay hint every time a variable is bound without a type signature", but I think that would probably be too much in many cases. But might be worth trying to see if it's unbearable! Maybe the general case is what we want.

I can see someone wanting to keep some of the inlay hints but not all (myself included). Is this something we want to allow to be configurable? Or should we aim for a minimum case first (i.e. just let bindings and lambdas for example) and go from there?

michaelpj commented 2 years ago

Ideally we don't configure things too much, but we might want a "noisy" version and a "quiet" version, perhaps.

I think the observation about the general case is more for design thinking: I'm not sure I have a good rationale for why some places that introduce a name without a type signature should get inlay hints and some shouldn't. So what's our heuristic?

July541 commented 2 years ago

Agree @michaelpj 's ideas, just one thought, I prefer to show function parameters' name instead of their type. (Although not beautiful to look at)

July541 commented 2 years ago

I still believe it's not bad to have more configure, it has little effect for most users(they won't touch these settings)

Here is some configuration(partial) for TypeScript.

image

Here is some configuration(partial) for Rust.

image
michaelpj commented 1 year ago

Also maybe holes: https://github.com/haskell/haskell-language-server/issues/3228

michaelpj commented 1 year ago

I think all our code lenses that display signatures should be inlay hints also: https://github.com/haskell/haskell-language-server/issues/3254

ozkutuk commented 1 year ago

Out of curiosity, what is the current status of the inlay hints support of lsp library?

michaelpj commented 1 year ago

It'll be there once I finish https://github.com/haskell/lsp/pull/458 :sweat_smile:

rockboynton commented 10 months ago

It'll be there once I finish haskell/lsp#458 😅

@michaelpj I noticed the linked issue was closed in favor of another one that is now merged. Do you know how long until that will land in a release?

michaelpj commented 10 months ago

Support in the library has been there for a while now, now someone just actually needs to implement using them in HLS.

michaelpj commented 5 months ago

Another idea: show inferred deriving strategies and allow clicking on them to make them explicit.

jetjinser commented 3 months ago

HI, guys. I think I've made some progress #4131. I successfully display fixity info via inlay hints, there's still a lot of work to do :)

Jashweii commented 3 months ago

If you're looking for ideas: Related to fixity - what about inserting parentheses? So a * b + c / d gains inlay hints (a * b) + (c / d) in accordance with fixity (I might be remembering this from some other IDE, not sure) Along the lines of https://github.com/haskell/haskell-language-server/issues/2938#issuecomment-1908241896 there's other implicit stuff that could be wrong, like type roles, defaulted instances e.g. in show . read, overloaded list/string syntax, defaulted method implementations. Some less clear ideas - with LinearTypes it might be useful to see info about usage (e.g. let %1 inference coming in 9.10), I also wonder if there's any useful information that could be shown for analysing performance like where allocations can occur or rules can fire or what is still lazy in O2 or something.

michaelpj commented 1 month ago

A kind of obvious one that I've mentioned to some people before but not written down: our import lenses. At the moment they are code lenses and they take up a whole extra line per-import. But since they are precisely suggesting extra changes to the import line, we could instead have them be inlay hints, which would mean they only take up one line.

i.e.

import Foo <hint begins>(Bar, Baz)<hint ends>

rather than

<lens> import Foo (Bar, Baz)
import Foo

(https://github.com/haskell/haskell-language-server/issues/4208)

michaelpj commented 1 month ago

(We're going to try and split out individual issues for the individual ideas)

divyaranjan1905 commented 1 month ago

Hello @michaelpj! Just found this on GSoC and would be willing to contribute. I have an intermediate experience with Haskell, as an independent learner. I use HLS on Emacs, so I'd like to give back in whatever way possible. I'm not a traditional university student though, hopefully that is not an issue.

As the project mentions you as the mentor, would you be willing to guide me in how to get started with this?

Regards,

Divya.

michaelpj commented 1 month ago

@jetjinser is the GSoC student for this, so I think the plan is for them to focus on it for now.

divyaranjan1905 commented 1 month ago

Oh, didn't know this was already being worked upon. Apologies.