Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide haskell-language-server-wrapper to help direnv #1776

Closed
peterbecich opened this issue Nov 11, 2022 · 11 comments
Closed

Provide haskell-language-server-wrapper to help direnv #1776

peterbecich opened this issue Nov 11, 2022 · 11 comments
Labels
enhancement New feature or request wontfix

Comments

@peterbecich
Copy link
Contributor

peterbecich commented Nov 11, 2022

Is your feature request related to a problem? Please describe.

I am using a haskell.nix Flake, Haskell Language Server, direnv, Emacs, and envrc for Emacs.

I am trying to make the haskell.nix Flake provide HLS to Emacs. I don't want Emacs to use /home/peterbecich/.ghcup/bin/haskell-language-server-9.2.4.

lsp-haskell for Emacs launches HLS. By default it looks for haskell-language-server-wrapper; not haskell-language-server, haskell-language-server-9.2.4, etc. :
https://github.com/emacs-lsp/lsp-haskell/blob/485c1148ce4d27030bb95b21c7289809294e7d31/lsp-haskell.el#L220-L225

Here is an example project which uses a haskell.nix Flake to provide Haskell Language Server in the nix develop shell: https://github.com/peterbecich/halogen-chess
and the relevant configuration for that:

          devShells.default = pkgs.hixProject.shellFor {
            tools =
              { cabal = "latest";
                hlint = "latest";
                haskell-language-server = "latest";
              };
           ...

https://github.com/peterbecich/halogen-chess/blob/7b295327f9503fe7db09b6f7c2bbc50539c601a5/flake.nix#L195-L200

If I open nix develop and look for HLS, here is the binary provided by haskell.nix:

$ which haskell-language-server 
/nix/store/50l8pg2qmi4g3mlp9xbjhxgd1i6hkgp0-haskell-language-server-exe-haskell-language-server-1.8.0.0/bin/haskell-language-server

Here is the binary haskell-language-server-wrapper which will be found by lsp-haskell:

$ which haskell-language-server-wrapper 
/home/peterbecich/.ghcup/bin/haskell-language-server-wrapper

The critical error is that haskell-language-server-wrapper then fails to point back to the Nix HLS binary; instead it points to /home/peterbecich/.ghcup/bin/haskell-language-server-9.2.4.

$ haskell-language-server-wrapper --example 
....
haskell-language-server exe candidates: ["haskell-language-server-9.2.4","haskell-language-server"]
Launching haskell-language-server exe at:/home/peterbecich/.ghcup/bin/haskell-language-server-9.2.4
GHC ABIs don't match!
...

Looking at the HLS code, if these two strings in candidates' were reversed, perhaps it would work correctly, I'm not sure:

        hlsBin = "haskell-language-server-" ++ ghcVersion
        candidates' = [hlsBin, "haskell-language-server"]
        candidates = map (++ exeExtension) candidates'

https://github.com/haskell/haskell-language-server/blob/85f788135175a007d3db4ac911c4115b30ab9d87/exe/Wrapper.hs#L150-L153

Describe the solution you'd like

When haskell.nix is configured to provide haskell-language-server in the nix develop shell, it should also provide the haskell-language-server-wrapper binary. The result would be something like:

$ which haskell-language-server 
/nix/store/12345-haskell-language-server-exe-haskell-language-server-1.8.0.0/bin/haskell-language-server

$ which haskell-language-server-wrapper 
/nix/store/12345-haskell-language-server-exe-haskell-language-server-wrapper-1.8.0.0/bin/haskell-language-server-wrapper

I am assuming the Nix haskell-language-server-wrapper would then point to the Nix haskell-language-server.

Describe alternatives you've considered
lsp-haskell has a configuration option to point to a different HLS binary:

 '(lsp-haskell-server-path "haskell-language-server")

This actually fixes the issue. My preference is this would be solved in haskell.nix and not in the LSP clients for Emacs and other editors.

Thank you!

Additional context

@peterbecich peterbecich added the enhancement New feature or request label Nov 11, 2022
@peterbecich
Copy link
Contributor Author

I have tried to adapt this: #1012 (comment)

          devShells.default = pkgs.hixProject.shellFor {
            tools =
              { cabal = "latest";
                hlint = "latest";
                haskell-language-server = "latest";
                haskell-language-server-wrapper = "latest";
              };

It does not work; the difference being this project uses Hix.

error: attribute 'haskell-language-server-wrapper' missing

       at /nix/store/4jfx2fqmlfsaqmky9zyzrzpf0g7p08jk-source/modules/hackage-project.nix:17:33:

           16|             (a: b: builtins.compareVersions a b > 0)
           17|             (builtins.attrNames pkgs.haskell-nix.hackage.${config.name}))
             |                                 ^
           18|         else v;
(use '--show-trace' to show detailed location information)

Is there a way to make this work? Thank you

@michaelpj
Copy link
Collaborator

lsp-haskell has a configuration option to point to a different HLS binary

I think this is my preferred solution, and I'm not sure why you don't like it. You're already using direnv - in my mind the normal direnv workflow is that you set it up so that you get exactly the right tools in each directory shell. So I have my lsp-haskell set to always call haskell-language-server rather than haskell-language-server-wrapper, and direnv puts the right one in each shell, problem solved.

You can also use emacs' support for directory-local variables to change the value of lsp-haskell-server-path

My preference is this would be solved in haskell.nix and not in the LSP clients for Emacs and other editors.

haskell-language-server is just a package from Hackage, and we install it just like any other. I'd rather not accumulate more packaging specific workarounds for specific packages in haskell.nix if we can.

@peterbecich
Copy link
Contributor Author

peterbecich commented Nov 11, 2022

Thanks for the quick response.

If this workaround were included in haskell.nix, it would slightly reduce the difficulty of setting up a nix develop shell and direnv from the scaffold (https://input-output-hk.github.io/haskell.nix/tutorials/getting-started-flakes.html#scaffolding). I believe both Emacs and VS Code (https://github.com/haskell/vscode-haskell/blob/4b16126fc0e94516fe7d7f3d79fed33a6f832b01/src/hlsBinaries.ts#L149-L153) look for haskell-language-server-wrapper by default. It looks like Vim points to haskell-language-server-wrapper, as well: https://haskell-language-server.readthedocs.io/en/latest/configuration.html#minimal-example

Instead of having haskell.nix provide the haskell-language-server-wrapper binary, how about an alias from haskell-language-server-wrapper to haskell-language-server? We don't need any of the features of haskell-language-server-wrapper.

This could reduce the barrier for multiple editors to have full HLS support using only the haskell.nix Flake scaffold and a minimal .envrc.

@stale
Copy link

stale bot commented Mar 11, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Mar 11, 2023
@domenkozar
Copy link
Contributor

HLS is such a necessity that supporting a simple setup is crucial for making a toolset have decent DX.

Here's what we're using with plain shell.nix:

    (pkgs.haskell-nix.tool "ghc927" "haskell-language-server" "latest")
    (pkgs.writeScriptBin "haskell-language-server-wrapper" ''
      #!${pkgs.stdenv.shell}
      ${pkgs.haskell-nix.tool "ghc927" "haskell-language-server" "latest"}/bin/haskell-language-server "$@"
    '')

@stale stale bot removed the wontfix label Mar 30, 2023
@michaelpj
Copy link
Collaborator

I think this can/should be fixed on the client side. I opened haskell/vscode-haskell#845 for the vscode extension.

@michaelpj
Copy link
Collaborator

vscode-haskell already looks for both so shouldn't need the wrapper. I guess we should worry about other tools, e.g. I think lsp-haskell needs a tweak here also.

@michaelpj
Copy link
Collaborator

emacs-lsp/lsp-haskell#169

@stale
Copy link

stale bot commented Jul 28, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 28, 2023
@purefn
Copy link
Contributor

purefn commented Aug 8, 2023

haskell-tools.nvim has a similar issue. It seems odd to try and fix all the tools that have an expectation of the wrapper being available when that's what has been the standard. It would be so easy to fix this in haskell.nix and lower the barrier to entry for people trying out haskell.nix and/or HLS for the first time.

Update: raised mrcjkb/haskell-tools.nvim#233

Copy link

stale bot commented Dec 6, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Dec 6, 2023
@stale stale bot closed this as completed Feb 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request wontfix
Projects
None yet
Development

No branches or pull requests

4 participants