haskell-language-server icon indicating copy to clipboard operation
haskell-language-server copied to clipboard

Inlay hints for package imports

Open wczyz opened this issue 10 months ago • 5 comments

Hey! I sometimes find myself trying to figure out which package certain imports come from, so when I saw #4485, I thought a good first contribution would be to implement inlay hints for package imports.

This PR isn’t finished yet, but I’d appreciate any feedback on whether I’m headed in the right direction. I’m uncertain about where exactly this functionality should live. Do you think there's a plugin to which it could be added or would a new plugin be more appropriate? For now, I put it in a somewhat related plugin as a proof of concept.

TODO:

  • [x] Decide where to put it (add to existing plugin / create a new one)
  • [x] ~~Add configurability, disabled by default~~
  • [x] Tests

This change would close #4485.

After implementing I have mixed feelings about it because it messes with the layout when imports are neatly aligned with whitespace (as it is in hls repo). Here's what it looks like: Screenshot from 2025-02-19 03-33-02

wczyz avatar Feb 19 '25 03:02 wczyz

Hi, thank you for the pull request! This looks quite cool!

The location for the feature looks good to me. The layout is indeed a bit unfortunate, perhaps it would be better if the inlay hint was immediately after the import (or qualified in the case of import qualified)? In theory, we could also display it after the module name, but that doesn't feel as nicely.

Regarding configurability, usually we try to have as little configuration as possible as it requires twice the amount of tests, so I think we should just decide on a way to display the package imports.

I haven't read the code, yet, but is the inlay hint displayed also when the user already added some PackageImport? I imagine this feature works best, if the user doesn't align imports and maybe used ImportQualifiedPost?

fendor avatar Feb 20 '25 19:02 fendor

Thanks @fendor

I'm fine with not configuring it, but while I would leave it enabled by default, I can imagine many people wouldn't like it.

Played around a bit with positioning and IMO it looks best after import / import qualified As you mentioned, ideally the user doesn't align imports and doesn't qualify them or pushes them to the end with ImportQualifiedPost

Screenshot from 2025-02-23 22-04-00

Good point about the case when the user already added some PackageImport, I'll handle it. Once we agree on how it should be displayed I'll also add some tests

In an ideal world, it would be nice if inlay hints could replace appropriate amount of spaces, but I don't think that's possible :)

wczyz avatar Feb 23 '25 21:02 wczyz

Added

  • Displaying after import or import qualified with 1-space padding on the left
  • Handling cases when the user already specified some PackageImport
  • When using ImportQualifiedPost, displaying hint after import
  • Tests

I'm still worried that without any configuration options, this change won't be as welcome, but otherwise, it's ready for review.

wczyz avatar Mar 02 '25 21:03 wczyz

This seems great! I think the big challenge is just "where to put it?". I think the main constraint is that Inlay hints are supposed to look the same as the text that they would insert when triggered. So I don't think we can put it at the end of the line.

Given that we're showing them in the right place syntactically, I don't see how we can avoid messing up people's formatting. We generally don't try to match this (see also the inlay hints for imports, which can't easily match people's preferred formatting either).

So overall I don't see much alternative to what you're doing. I do think this is likely to be a bit of a "love-it-or-hate-it" feature, so we probably will need the ability to turn it off!

michaelpj avatar Mar 09 '25 21:03 michaelpj

Sorry for taking so long to come back to you!

In addition to the above (configuration option), I think it would make sense to hide the implementation in a Rule, similarly to how inlayHintProvider does it. At last, it may also make sense to piggyback off the rule ImportActions to avoid work duplication, as ImportActions already traverses the Imports.

The code itself looks good to me, I have no comments right now. My only question is regarding the use of GetParsedModule, why did you decide to only use the parsed module?

fendor avatar Apr 17 '25 16:04 fendor