Skip to content

Conversation

@siggsy
Copy link

@siggsy siggsy commented Oct 17, 2025

Haskell is not configured with lspconfig, but rather with haskell-tools.nvim. This commit fixes "conversion" made in 39efdc7.

Without this, users are met with nvim errors about invalid vim.g options

Sanity Checking

  • I have updated the changelog as per my changes
  • I have tested, and self-reviewed my code
  • My changes fit guidelines found in hacking nvf
  • Style and consistency
    • I ran Alejandra to format my code (nix fmt)
    • My code conforms to the editorconfig configuration of the project
    • My changes are consistent with the rest of the codebase
  • If new changes are particularly complex:
    • My code includes comments in particularly complex areas
    • I have added a section in the manual
    • (For breaking changes) I have included a migration guide
  • Package(s) built:
    • .#nix (default package)
    • .#maximal
    • .#docs-html (manual, must build)
    • .#docs-linkcheck (optional, please build if adding links)
  • Tested on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin

Add a 👍 reaction to pull requests you find important.

@github-actions
Copy link

github-actions bot commented Oct 17, 2025

🚀 Live preview deployed from da5c914

View it here:

Debug Information

Triggered by: siggsy

HEAD at: v0.8

Reruns: 1558

servers = {
hls = {
enable = false;
cmd = [(getExe' pkgs.haskellPackages.haskell-language-server "haskell-language-server-wrapper") "--lsp"];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also odd. As far as I understand haskell-language-server-wrapper only searches for hls and starts it. So we still have to provide haskell-language-server in our projects. Is this then really necessary? Should I remove this aswell? If anything, this adds 6.73GB to the nixos configuration
image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested it. Without the cmd option, nvim behaves the same

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that we should still reference in manually, like the rest of the packages.

      cmd = [(getExe' pkgs.haskellPackages.haskell-language-server "haskell-language-server") "--lsp"];

so that we are explicit

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that the hls is compiled for specific ghc version. If we do specify it like you suggested, then you would be stuck on a specific ghc, and would prevent haskell-tools choosing appropriate hls for haskell projects.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point and a little bit of a weak suit for HLS imo haha.

Perhaps we could make it a string instead to allow the user to change it if need be.

e.g.

cmd = "haskell-language-server --lsp"

and then the plugin can throw an error if necessary.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do specify it like you suggested, then you would be stuck on a specific ghc, and would prevent haskell-tools choosing appropriate hls for haskell projects.

I'm pretty sure haskell-tools looks for a usable hls in PATH regardless of whether cmd is set. Or I could be misremembering.

Either way, the purpose of the language modules are to provide plug-and-play defaults. In this case the closest we can get is having a default hls so that there is at least some chance of it working ootb for someone.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since haskell-tools supports it, the hls configuration was moved to vim.lsp.servers to allow users to override cmd, and avoid unnecessary dependencies

@siggsy
Copy link
Author

siggsy commented Oct 18, 2025

Is this here only to have consistent interface with languages? This option is not used, and if it was, we would have to differentiate between configuration with custom plugin (like haskell-tools.nvim) and lspconfig

I have two proposals:

  1. Have separate "haskell-tools" server name, which uses the plugin configuration, and hls which uses lspconfig. This makes it confusing, because the referenced "haskell-tools" wont show up on vim.lsp.server.
  2. Have a CLEAR distinction between lspconfig and plugin. I'm not sure if plugin options should lie in vim.languages.haskell or somewhere else.

How is this handled in other languages with similar issues?

@sjcobb2022
Copy link

@siggsy yes it was purely for consistent interface when I made the changes.

At the moment we do not have any tools type interface, such as for rust (with rustaceanvim) or anything else.

Both rustaceanvim and haskell-tools.nvim support importing the config from vim.lsp.config (mrcjkb/haskell-tools.nvim@53d9888, mrcjkb/rustaceanvim#660), so I think that keeping it (but leaving it disabled) is probably the best wait to handle these. Would want a second from @horriblename or @NotAShelf for this though.

Perhaps an API such as what we have with the crates.nvim support would be good for this type of setup (for rust as well perhaps)

Where we have

{
     vim.languages.haskell.enable = true; # just enables HLS as a purely with `vim.lsp.config`
     vim.languages.haskell.extensions = {
         haskell-tools-nvim.enable = true; # disables the vim.lsp.enable of hls and uses haskell-tools.
     };
     
     # and for rust if we go this route
     
     vim.languages.rust.enable = true; # enables just rust-analyzer via `vim.lsp.config`
     vim.languages.rust.extensions = {
         rustaceanvim.enable = true; # disable `vim.lsp.enable` of rust-analyzer
         crates-nvim.enable = true;
     };

}

I think that having the command in explicitly is better than not having the command, as this is what we have done for every other language module, and we should keep consistency in that regard.

@horriblename
Copy link
Collaborator

Is this here only to have consistent interface with languages?

We can take it back out for now, if it didn't exist before v0.8.

Perhaps an API such as what we have with the crates.nvim support would be good for this type of setup (for rust as well perhaps)

I vaguely recall @NotAShelf wanting to remove the hard dependency we have on some language plugins (rustaceanvim etc.), perhaps this is an opportunity for that?

@sjcobb2022
Copy link

I vaguely recall @NotAShelf wanting to remove the hard dependency we have on some language plugins (rustaceanvim etc.), perhaps this is an opportunity for that?

Yeh I think that was on the initial language overhaul branch. Want me to make an issue?

@sjcobb2022
Copy link

#1195

@siggsy
Copy link
Author

siggsy commented Nov 7, 2025

This configuration now works when users have GHC in path (otherwise hls crashes).

siggsy and others added 8 commits November 8, 2025 06:58
Haskell is not configured with lspconfig, but rather
with haskell-tools.nvim. This commit fixes "conversion"
made in 39efdc7.

Without this, users are met with nvim errors about invalid
vim.g options
Theses are already provided by `haskell-language-server`.
We also do not prvoide any packages to complement the
specified settings, so it seems unecessary.
`haskell-language-server-wrapper` only selects the correct
`haskell-language-server`. Snippet from hls documentation:

> HLS is a binary that must be compiled with the same version of
> GHC as the project you are using it on. For this reason it is
> usually distributed as a collection of binaries, along with a
> haskell-language-server-wrapper executable that selects the correct
> one based on which version of GHC it thinks you are using.

By providing `hls-wrapper` we pull A LOT of dependencies,
but do not use them (around 6.7GB). This is unecessary since
we then have to provide `haskell-language-server` in haskell
projects bundled with compatable GHC.
hls-wrapper is a simple script to start the correct language server
based on the currently oppened project. From nvf perspective, this makes
it effectively useless. To allow haskell to work on nvf OOTB, we specify
cmd with hls (not wrapper).

NOTE: this pins the language server to specific GHC version.
To circumvent this, users must override (lib.mkForce)
vim.lsp.servers.haskell-tools.cmd with their own, or just specify it as
[ "haskell-language-server-wrapper" "--lsp" ].
github-actions bot pushed a commit that referenced this pull request Nov 8, 2025
haskell-tools already starts the server with ftplugin.
If server.enable is set, haskell-tools starts even on non haskell files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants