emacs-lsp / lsp-haskell

lsp-mode :heart: haskell
https://emacs-lsp.github.io/lsp-haskell
GNU General Public License v3.0
227 stars 56 forks source link

`lsp-haskell-server-wrapper-function` not being used? #85

Closed thalesmg closed 3 years ago

thalesmg commented 3 years ago

Hello!

First, thanks for putting up this library! :beers:

I'm trying to use this with haskell-language-server inside a nix sandbox. I tried to set some wrappers (following along the lines of this gist). But, according to *lsp-haskell::stderr*, I was always getting the haskell-language-server-wrapper that is in my path, not inside my sandbox. Which fails due to GHC version mismatch.

Searching lsp-haskell.el, I could not find any places that are using lsp-haskell-server-wrapper-function, which is supposedly the key piece here.

The only way I got it working was to alter the :new-connection from lsp-register-client:

(lsp-register-client
  (make-lsp--client
   :new-connection (lsp-stdio-connection (lambda ()
                                           (apply
                                            lsp-haskell-server-wrapper-function ;; <--- had to add this
                                            (list (lsp-haskell--server-command)))))
    ...
    ))

... and then it correctly used the executable from inside my sandbox.

Is there something I'm missing? Or does this patch make sense?

Anton-Latukha commented 3 years ago

Making HLS work in NixOS is a doozy. It took me a long time, (a day) to troubleshoot through all parts and understand this one.

Because in current code nix-shell wrapper is not respected - build of the project starts in the default global NixOS environemt, where cabal v2-build can not build the projects (global NixOS default env and expectations of the ability of linkage (most frequently zlib) of build tools (cabal) - do not align, it is essentially impossible to build projects with OS package deps by cabal in default global NixOS env):

Log is in this wrapper:

``` Module "/home/pyro/src/haskell/hnix/a" is loaded by Cradle: Cradle {cradleRootDir = "/home/pyro/src/haskell/hnix", cradleOptsProg = CradleAction: Cabal} Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 0.5.0.0 x86_64 ghc-8.8.4 Current directory: /home/pyro/src/haskell/hnix Operating system: linux Arguments: ["--lsp","-d","-l","/tmp/hls.log"] Cradle directory: /home/pyro/src/haskell/hnix Cradle type: Cabal Tool versions found on the $PATH cabal: 3.2.0.0 stack: Not found ghc: 8.8.4 Consulting the cradle to get project GHC version... Project GHC version: 8.8.4 haskell-language-server exe candidates: ["haskell-language-server-8.8.4","haskell-language-server-8.8","haskell-language-server"] Launching haskell-language-server exe at:/run/current-system/sw/bin/haskell-language-server-8.8.4 haskell-language-server version: 0.5.0.0 (GHC: 8.8.4) (PATH: /nix/store/k0m1b19yhmhp5invixvka89rnyf81gwm-haskell-language-server-0.5.0.0/bin/haskell-language-server) Starting (haskell-language-server)LSP server... with arguments: LspArguments {argLSP = True, argsCwd = Nothing, argFiles = [], argsShakeProfiling = Nothing, argsTesting = False, argsExamplePlugin = False, argsDebugOn = True, argsLogFile = Just "/tmp/hls.log", argsThreads = 0, argsProjectGhcVersion = False} with plugins: [PluginId "brittany",PluginId "eval",PluginId "floskell",PluginId "fourmolu",PluginId "ghcide",PluginId "importLens",PluginId "ormolu",PluginId "pragmas",PluginId "retrie",PluginId "stylish-haskell",PluginId "tactic"] in directory: /home/pyro/src/haskell/hnix If you are seeing this in a terminal, you probably should have run ghcide WITHOUT the --lsp option! Started LSP server in 10.17s Output from setting up the cradle Cradle {cradleRootDir = "/home/pyro/src/haskell/hnix", cradleOptsProg = CradleAction: Cabal} > Resolving dependencies... > Build profile: -w ghc-8.8.4 -O1 > In order, the following will be built (use -v for more details): > - pretty-show-1.10 (lib) (requires build) > - saltine-0.1.1.0 (lib) (requires build) > - zlib-0.6.2.2 (lib) (requires build) > - hnix-store-core-0.2.0.0 (lib) (requires build) > - streaming-commons-0.2.2.1 (lib) (requires build) > - http-client-0.7.2.1 (lib) (requires build) > - http-client-tls-0.3.5.3 (lib) (requires build) > - hnix-0.10.1 (lib) --enable-profiling (configuration changed) > Starting pretty-show-1.10 (lib) > Starting saltine-0.1.1.0 (lib) > Starting zlib-0.6.2.2 (lib) > Building pretty-show-1.10 (lib) > > Failed to build pretty-show-1.10. > Build log ( > /home/pyro/.cabal/logs/ghc-8.8.4/pretty-show-1.10-4d9ba9ec06e9b1bec02340ead0154b51df2a42259480b1a0f6fc0a5b532218ae.log > ): > Configuring library for pretty-show-1.10.. > Preprocessing library for pretty-show-1.10.. > /home/pyro/.cabal/store/ghc-8.8.4/happy-1.20.0-180a4d6d0b3be973afff3a18a4478fd4d534ab8827a23e2db364356f8062c334/bin/happy: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory) > > Failed to build saltine-0.1.1.0. The failure occurred during the configure > step. > Build log ( > /home/pyro/.cabal/logs/ghc-8.8.4/saltine-0.1.1.0-acf534226faa0b1a49a797d1099b8476bcd3e655b876e0f4567dd26b5e1abb56.log > ): > Configuring library for saltine-0.1.1.0.. > cabal: The program 'pkg-config' version >=0.9.0 is required but it could not > be found. > > > Failed to build zlib-0.6.2.2. The failure occurred during the configure step. > Build log ( > /home/pyro/.cabal/logs/ghc-8.8.4/zlib-0.6.2.2-181ae4c687cbeef85d5e457ee5dba870bf55db774636484e4d2c583b13ba1aaf.log > ): > Configuring library for zlib-0.6.2.2.. > cabal: Missing dependency on a foreign library: > * Missing (or bad) header file: zlib.h > * Missing (or bad) C library: z > This problem can usually be solved by installing the system package that > provides this library (you may need the "-dev" version). If the library is > already installed but in a non-standard location then you can use the flags > --extra-include-dirs= and --extra-lib-dirs= to specify where it is.If the > library file does exist, it may contain errors that are caught by the C > compiler at the preprocessing stage. In this case you can re-run configure > with the verbosity flag -v3 to see the error messages. > If the header file does exist, it may contain errors that are caught by the C > compiler at the preprocessing stage. In this case you can re-run configure > cabal: Failed to build pretty-show-1.10 (which is required by hnix-0.10.1). > with the verbosity flag -v3 to see the error messages. > See the build log above for details. > > Failed to build saltine-0.1.1.0 (which is required by hnix-0.10.1). See the > build log above for details. > Failed to build zlib-0.6.2.2 (which is required by hnix-0.10.1). See the build > log above for details. > ```

Anton-Latukha commented 3 years ago

Wrapper was deleted in: 63baa1a30bc0ac734dffbda56451bc7df9c8b9ab.

When the:

(defun lsp-haskell--hie-command ()
  (funcall lsp-haskell-process-wrapper-function (lsp--haskell-hie-command)))

Become:

(defun lsp-haskell--server-command ()
  "Command and arguments for launching the inferior language server process.
These are assembled from the customizable variables `lsp-haskell-server-path'
and `lsp-haskell-server-args'."
  (append (list lsp-haskell-server-path "--lsp") lsp-haskell-server-args) )
Anton-Latukha commented 3 years ago

And as we see, the HLS 0.5.0 haskell-language-server-wrapper does not support automatic loading of the Nix environments, (NOR it probably would ever do that by default - HLS would probably opt-out from autoloading Nix env by default, if only for NixOS), so currently reintroducing wrapper, for future and backward compatibility seems most proper.

Anton-Latukha commented 3 years ago

Submitted a PR with fix :arrow_up:.

michaelpj commented 3 years ago

Fixed now, thanks.

If you want to load something from the Nix environment, I would suggest using direnv with lorri and direnv-mode in Emacs. In my experience this works well.

Anton-Latukha commented 3 years ago

To reduce effort of IDEs, currently, I started work on optional Nix env loading support diretly by HLS wraper, so HLS Nix env support would be standartized for all IDEs and to reduce wraping of HLS wrapper into wrapper for IDEs.

It is reasonable case, it person/configuration requests loading of the Nix env - and start HLS wrapper there anew in a classical way, essentially as lsp-haskell does it.

But lsp-haskell recommends it in a partial way, currently, since - there is an option of shell.nix not being available - then nix-shell simply loads default.nix (which is always possible) - that is default behaviour. And shell.nix can be in ../ or further up the tree, that is solved by using a library function.

michaelpj commented 3 years ago

I think the wrapper function we have is a bit of a hack. I'd rather suggest that people use direnv-mode!