haskell / haskell/haskell-language-server

Smarter import suggestion with defaults

Open
#605 3 comments 0 reactions 0 assignees View on GitHub
component: ghcide type: enhancement
Dominant language
Haskell
Stars
3k
Forks
455
Avg merge
2d 19h
Merged PRs (30d)
11

Description

The code action to add imports is great and I use it all the time, but my interactions with it can sometimes be a little repetitive.

For example, if I use the type `Int32` HLS suggests a litany of potential imports, but every time I use this name I want to import `Data.Int` from `base`. There are a host of these "defaults" and it would be great to inform HLS of these to avoid cluttering the code actions with options I'm never going to choose.

![image](https://user-images.githubusercontent.com/857308/99494831-a5efc500-29ac-11eb-8020-04ae6b8df161.png)

The defaults could be specified either as:

- A name and the corresponding import statement, in the above example: `('Int32, "import Data.Int")`
- Just a module name `Data.Int` with the meaning of, if this exists at all in the suggestions, don't suggest anything else

On a similar topic, it would be nice to specify "canonical" imports for types, for example I'm sure that despite `Int32` being reexported from `Foreign`, `Foreign.Safe`, `GHC.Int` and `UnliftIO.Foreign`, nobody ever imports it from those modules (specifically, i.e. not with an open import). Does HLS have information at code-action generation time on the provenance of the symbols in the imports it's suggesting? In the above example this would present the import options from `Data.Int` and the `Vulkan` imports (assuming the user hasn't specified a canonical import for `Vulkan.Core10.CommandBufferBuilding.ClearColorValue.Int32`, in which case that canonical module would be returned).

I'm not sure that having a built in list of these default would be sensible, especially when alternative preludes get involved, but it would be nice to have some configuration that users could opt into easily to avoid people duplicating large amounts of the specifications in their configs.

Other motivating examples:

- Anything from `Data.Traversable`, `Data.Foldable`, `Data.Maybe`. Basically any import from base which doesn't gobble up common names.
- I quite often like: `import Data.Text (Text); import Data.Text qualified as T` (would have to present the options for `Data.Text.Lazy` too for when the user wants that)
- Similarly for `import Data.Vector(Vector); import Data.Vector qualified as V`

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.