Setting up Haskell Language Server with VSCode is cursed
Haskell setup is pain
I’ve been enjoying writing Haskell a lot lately, but my god has the tooling been a mixed experience. I recently bought a new laptop, which I’ve installed Arch Linux on, and wanted to set up the Haskell language server (HLS) to work with Visual Studio Code on it. Every time I’ve attempted this in the past, it has been extraordinarily painful. Here is a cheatsheet to my future self as well as anyone who may find it useful.
The project I am working on uses template Haskell fairly heavily. Unfortunately, most easy ways to install HLS default to static linking, which doesn’t play well with with template Haskell. In fact, it plays so badly that the language server will routinely segfault on my project on several machines I’ve tried to do this on.
GHCUP to the rescue
By far the least painful way I have found to get this all working is using
ghcup. I recommend installing every piece of tooling needed with it (
If you have Haskell installed in any other way, uninstall it, and follow the steps on https://www.haskell.org/ghcup/. Concretely, run:
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
You will prompted to install a few different tools. Only install
stack, but decline to install the language server. Make to sure to allow the tool to add the tools to your
If your project needs as specific version of
ghc, you can easily install and switch to it using the
ghcup tui interface. My project used GHC 9.0.2.
For the language server, we need to build it from source to support template haskell properly. There are some steps here https://haskell-language-server.readthedocs.io/en/latest/troubleshooting.html#static-binaries. Since we are using GHCUP, run something like:
ghcup compile hls -v 18.104.22.168 --ghc 8.10.7
With your appropriate version. Some versions apparently need a specific
cabal.project, so I ran:
ghcup compile hls -v 22.214.171.124 --ghc 9.0.2 --cabal-project cabal-ghc90.project
That will compile HLS, which might take a little while.
Making VSCode aware of binaries from GHCUP
GHCUP will place a line into your
.bashrc that looks like so:
[ -f "/home/pema99/.ghcup/env" ] && source "/home/pema99/.ghcup/env" # ghcup-env
Which works fine when using the installed binaries via a shell. Unfortunately, under normal circumstances, the
$PATH VSCode uses will not be affected by this. (More info here https://github.com/haskell/haskell-language-server/issues/236). We have a few options to fix that:
- Add this same line from above, to the bottom of your
/etc/profilefile. This is a bit of a hack, but it is what I did.
- Start VSCode from the terminal with the flag
--force-user-env. Super tedious.
- Use the
haskell.serverEnvironmentsetting in your VSCode
settings.jsonto manually make the Haskell extension aware of where the binaries installed by GHCUP are (info here https://github.com/haskell/haskell-language-server/issues/236#issuecomment-987174473)
Setting up the Haskell extension
For whatever reason, the VSCode Haskell extension doesn’t seem to play nicely with projects that have never been built, so I suggest doing the following:
- If you don’t already have the Haskell extension installed, open a fresh VSCode instance and install it from the marketplace. https://marketplace.visualstudio.com/items?itemName=haskell.haskell
- Optionally make the edit to your
settings.jsonif you opted for that in the previous step.
- Close VSCode
- Navigate to your Haskell project in a shell
- Assuming you are using
stackto build, do
- Now, open VSCode in your project directory.
If you followed every step correctly, VSCode should now automatically figure out your setup, start compiling your code, and hook up the language server. Or maybe not, if I made some stupid blunder while writing this. Let’s hope not, future me will surely be annoyed.