Spacemacs is an Emacs (configuration) distribution. It mainly consists of pre-configured sets of packages that are organized in layers (e.g. there is a haskell layer). With Spacemacs you can relatively quickly get an "IDE experience" for GHC development.
Topics regarding Emacs configuration in general can be found here: Emacs
The other parameters are optional and only provided as examples that you can configure much more with ghc.nix.
You can save a lot of compilation time by using a pre-built ("cached") ghcide.
To enable the cachix cache for ghcide:
nix-env -iA cachix -f https://cachix.org/api/v1/installcachix use ghcide-nix
Of course, you only need the first line if cachix isn't already installed.
Configure Spacemacs to use ghcide with nix-shell
Configure two layers, lsp and haskell, to use ghcide in a nix-shell environment:
...;; List of configuration layers to load.dotspacemacs-configuration-layers'((lsp:variablesdefault-nix-wrapper(lambda(args)(append(append(list"nix-shell""-I"".""--pure""--command")(list(mapconcat'identityargs" ")))(list(nix-current-sandbox))))lsp-haskell-process-wrapper-functiondefault-nix-wrapperlsp-haskell-process-path-hie"ghcide"lsp-haskell-process-args-hie'())(haskell:variableshaskell-enable-hindentthaskell-completion-backend'lsphaskell-process-type'cabal-new-repl)...
And load the nix-sandbox package on statup:
...;; List of additional packages that will be installed without being;; wrapped in a layer. If you need some configuration for these;; packages, then consider creating a layer. You can also put the;; configuration in `dotspacemacs/user-config'.;; To use a local version of a package, use the `:location' property:;; '(your-package :location "~/path/to/your-package/");; Also include the dependencies as they will not be resolved automatically.dotspacemacs-additional-packages'(nix-sandbox)...
compiler/ and hadrian/ are two distinct projects
Unfortunately projectile recognizes GHC and hadrian as one project.
To make calls to ghcide with different parameters, the distinction between GHC and hadrian is important.
Add an empty hadrian/.projectile file:
Configure different ghcide command line arguments
To test if ghcide works, you can call it directly.
nix-shell --command"ghcide compiler"
You should see a lot of output and finally a success message:
...Files that worked: 469Files that failed: 0Done
nix-shell --command"ghcide --cwd hadrian ."
Files that worked: 96Files that failed: 0Done
To configure different ghcide parameters per source folder, we can use .dir-locals.el files.
Please make sure that you open first a Haskell file under hadrian/ and then a file under compiler/. Otherwise Spacemacs will automatically assume, that files under hadrian/ belong to the same workspace as compiler/.
This setup is pretty complicated. To find errors, you can check several layers.
I would propose this order:
Nix - Can I correctly instantiate the nix-environment?Does it contain ghcide?
ghcide - Can ghcide be run on the command line?
lsp-mode (Emacs) - Are there any error messages in the lsp buffers?
Menu entry: Lsp Server Trace
Increase response timeout
Menu entry: Lsp Response Timeout
Shows how ghcide is called.
Command "nix-shell -I . --pure --command ghcide --lsp --cwd /home/sven/src/ghc compiler /home/sven/src/ghc/shell.nix" is present on the path.Found the following clients for /home/sven/src/ghc/compiler/simplCore/CoreMonad.hs: (server-id hie, priority 0)The following clients were selected based on priority: (server-id hie, priority 0)Command "nix-shell -I . --pure --command ghcide --lsp --cwd /home/sven/src/ghc/hadrian . /home/sven/src/ghc/hadrian/shell.nix" is present on the path.Found the following clients for /home/sven/src/ghc/hadrian/UserSettings.hs: (server-id hie, priority 0)The following clients were selected based on priority: (server-id hie, priority 0)Buffer switched - ignoring response. Method textDocument/hover
**lsp-log*: hie: [SESSION_NUMBER]
If you've enabled message tracing (see above), these buffers contain all requests and responses of the Language Server Protocol regarding one session.
There are three LSP backends for C to choose from: clangd (default in Spacemacs), ccls and cquery.
The cquery project seems to be abandoned.
Both, clangd and ccls (can) use a compile_commands.json (JSON Compilation Database) file as configuration.
Because I (@supersven) got the best results with ccls (it was able to handle header files better), we'll continue with it. But configuring clangd should be very simple, too.