Description
Hi!
Setting the stage, Haskell Language Server's support for stack projects is currently lacking.
There are many reasons why using HLS with stack is a subpar experience.
I am trying to list the most important issues here, in the hope of better collaboration, so we can improve the developer experience with both HLS and stack.
Finding the compilation options of a filepath
Essentially, HLS is a compiler. As the compiler, it needs to know how to compile a component / file. Stack knows how to compile a file part of a stack project, and we want to extract that information.
The status quo is that we call a variation of stack repl
with a special GHC shim that intercepts the ghc options when stack repl
tries to invoke ghc --interactive
. Then we use these options to compile the project ourselves.
This works reasonably well, but has some shortcomings. Most notably, the issues:
- "stack repl <test suite>" fails if "stack test --no-run-tests" is not run in advance for test suite containing errors #5380
- Internal library component not available for REPL #4564
- False positive: Main.hs (executable) does not recognise function defined in Lib.hs (library) haskell/haskell-language-server#1822
- Allow setting the working-dir to absolute directories #6135
Some of these are full-blown blockers and stack users have suffered in the past.
You can work around this using implicit-hie, which is its own can of worms, and not a proper solution for the needs of HLS.
What does HLS need
It is not a requirement for us to keep using this ugly hack of stack repl
.
What we fundamentally need is this:
Given a filepath, we need to be able to find the exact compilation options for it (preferably for the whole component it belongs to) in the quickest way possible, with as little work as possible. Additionally, the compilation options must be enough to actually compile the file. Potential configure hooks must have been run before HLS tries to compile the file.
In the light of multiple home units coming to cabal and ghc, we would like even a bit more, but I can't specify right now what exactly.
Going forward
To get this stuff sorted out, there are multiple ways. In Cabal, we've added a couple of months/years ago the --enable-build-info
flag with writes out build-info.json
files containing the build information required to compile a component.
If someone wants to collaborate on this, I'd be happy to give more information, maybe even in a sync call.