1# Contributing guidelines 2 3The Haskell tooling dream is near, we need your help! 4 5- Join [our IRC channel](https://web.libera.chat/?channels=#haskell-language-server) at `#haskell-language-server` on [`libera`](https://libera.chat/). 6- Follow the [Haskell IDE team twitter account](https://twitter.com/IdeHaskell) for updates and help. 7- Join the [#haskell-tooling channel](https://discord.com/channels/280033776820813825/505370075402862594/808027763868827659) in the Functional Programming discord server. You can join the server via [this invitation](https://discord.gg/9spEdTNGrD). 8 9## Building haskell-language-server 10 11The project can be built with both `cabal build` and `stack build`. 12 13haskell-language-server can also be used with itself. We provide preset samples of `hie.yaml` for Cabal and Stack. 14 15Note: the `./install/` folder is not directly tied to the project so it has dedicated `./install/hie.yaml.[cbl|stack]` 16templates. 17 18### Using Cabal 19 20```shell 21$ cp hie-cabal.yaml hie.yaml 22$ cp install/hie-cabal.yaml install/hie.yaml 23``` 24 25### Using Stack 26 27```shell 28$ cp hie-stack.yaml hie.yaml 29$ cp install/hie-stack.yaml install/hie.yaml 30$ cp ghcide/hie-stack.yaml ghcide/hie.yaml 31$ stack build --test --no-run-tests 32$ cd install 33$ stack build 34``` 35 36### Using Nix 37 38The instructions below show how to set up a Cachix binary cache and open a nix shell for local development. 39 40```shell 41$ cachix use haskell-language-server 42$ nix-shell 43$ cabal update 44$ cabal build 45``` 46 47#### Flakes support 48 49If you are using nix 2.4 style command (enabled by `experimental-features = nix-command`), 50you can use `nix develop` instead of `nix-shell` to enter the development shell. To enter the shell with specific GHC versions: 51 52* `nix develop` or `nix develop .#haskell-language-server-dev` - default GHC version 53* `nix develop .#haskell-language-server-8104-dev` - GHC 8.10.4 54* `nix develop .#haskell-language-server-884-dev` - GHC 8.8.4 55* `nix develop .#haskell-language-server-901-dev` - GHC 9.0.1 56 57If you are looking for a Nix expression to create haskell-language-server binaries, see https://github.com/haskell/haskell-language-server/issues/122 58 59To create binaries: 60 61* `nix build` or `nix build .#haskell-language-server` - default GHC version 62* `nix build .#haskell-language-server-8104` - GHC 8.10.4 63* `nix build .#haskell-language-server-884` - GHC 8.8.4 64* `nix build .#haskell-language-server-901` - GHC 9.0.1 65 66GHC 8.6.5 is not supported here because `nixpkgs-unstable` no longer maintains the corresponding packages set. 67 68## Testing 69 70The tests make use of the [Tasty](https://github.com/feuerbach/tasty) test framework. 71 72There are two test suites in the main haskell-language-server package, functional tests, and wrapper tests. 73Other project packages, like the core library or plugins, can have their own test suite. 74 75### Testing with Cabal 76 77Running all the tests 78 79```bash 80$ cabal test 81``` 82 83Running just the functional tests 84 85```bash 86$ cabal test func-test 87``` 88 89Running just the wrapper tests 90 91```bash 92$ cabal test wrapper-test 93``` 94 95Running a subset of tests 96 97Tasty supports providing 98[Patterns](https://github.com/feuerbach/tasty#patterns) as command 99line arguments, to select the specific tests to run. 100 101```bash 102$ cabal test func-test --test-option "-p hlint" 103``` 104 105The above recompiles everything every time you use a different test option though. 106 107An alternative, which only recompiles when tests (or dependencies) change: 108 109```bash 110$ cabal run haskell-language-server:func-test -- -p "hlint enables" 111``` 112 113### Test your hacked HLS in your editor 114 115If you want to test HLS while hacking on it, follow the steps below. 116 117To do once: 118 119- Open some codebase on which you want to test your hacked HLS in your favorite editor 120- Configure this editor to use your custom HLS executable 121 - With Cabal: 122 - On Unix systems: `cabal exec which haskell-language-server` 123 - On Windows: `cabal exec where haskell-language-server` 124 - With Stack: `$(stack path --dist-dir)/build/haskell-language-server/haskell-language-server` 125 126To do every time you changed code and want to test it: 127 128- Build HLS 129 - With Cabal: `cabal build exe:haskell-language-server` 130 - With Stack: `stack build haskell-language-server:exe:haskell-language-server` 131- Restart HLS 132 - With VS Code: `Haskell: Restart Haskell LSP Server` 133 134## Style guidelines 135 136The project includes a [`.editorconfig`](https://editorconfig.org) [file](https://github.com/haskell/haskell-language-server/blob/master/.editorconfig) with the editor basic settings used by the project. 137However, most editors will need some action to honour those settings automatically. 138For example vscode needs to have installed a specific [extension](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig). 139Please, try to follow those basic settings to keep the codebase as uniform as possible. 140 141### Formatter pre-commit hook 142 143We are using [pre-commit-hook.nix](https://github.com/cachix/pre-commit-hooks.nix) to configure git pre-commit hook for formatting. Although it is possible to run formatting manually, we recommend you to use it to set pre-commit hook as our CI checks pre-commit hook is applied or not. 144 145You can configure the pre-commit-hook by running 146 147``` bash 148nix-shell 149``` 150 151If you don't want to use [nix](https://nixos.org/guides/install-nix.html), you can instead use [pre-commit](https://pre-commit.com) with the following config. 152 153```json 154{ 155 "repos": [ 156 { 157 "hooks": [ 158 { 159 "entry": "stylish-haskell --inplace", 160 "exclude": "(^Setup.hs$|test/testdata/.*$|test/data/.*$|^hie-compat/.*$|^plugins/hls-tactics-plugin/.*$)", 161 "files": "\\.l?hs$", 162 "id": "stylish-haskell", 163 "language": "system", 164 "name": "stylish-haskell", 165 "pass_filenames": true, 166 "types": [ 167 "file" 168 ] 169 } 170 ], 171 "repo": "local" 172 } 173 ] 174} 175``` 176 177#### Why some components are excluded from automatic formatting? 178 179- `test/testdata` and `test/data` are there as we want to test formatting plugins. 180- `hie-compat` is there as we want to keep its code as close to GHC as possible. 181- `hls-tactics-plugin` is there as the main contributor of the plugin (@isovector) does not want auto-formatting. 182 183## Introduction tutorial 184 185See the [tutorial](./plugin-tutorial.md) on writing a plugin in HLS. 186 187## Adding support for a new editor 188 189Adding support for new editors is fairly easy if the editor already has good support for generic LSP-based extensions. 190In that case, there will likely be an editor-specific support system for this (like `lsp-mode` for Emacs). 191This will typically provide instructions for how to support new languages. 192 193In some cases you may need to write a small bit of additional client support, or expose a way for the user to set the server's [configuration options](#configuring-haskell-language-server) and 194for them to configure how the server is started. 195 196## Building the docs 197 198The docs are built with [Sphinx](https://www.sphinx-doc.org/en/master/) and [ReadTheDocs](https://docs.readthedocs.io/en/stable/index.html), the documentation for both is helpful. 199 200To build the docs you need to install some Python prerequisites. You can either `pip install -r docs/requirements.txt`, or simply enter a `nix-shell`. 201 202Then to build and preview the docs: 203 204``` 205cd docs 206make html 207firefox _build/html/index.html 208``` 209 210Alternatively, you can build the entire thing as a Nix derivation from the flake with `nix build .#docs`. 211 212The docs are also built and previewed on every PR, so you can check them from the PR status. 213 214## Sponsorship 215 216If you want to contribute financially you can do so via [open-collective](https://opencollective.com/haskell-language-server). In the past the funding has been used to sponsor [summer student projects](https://mpickering.github.io/ide/posts/2021-07-22-summer-of-hls.html). 217