-
-
Notifications
You must be signed in to change notification settings - Fork 369
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
Rework "Configuration" and "Manually testing HLS" documentations #3772
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,83 +90,97 @@ Settings like this are typically be provided by the language-specific LSP client | |
## Configuring your project build | ||
|
||
`haskell-language-server` has to compile your project in order to give you diagnostics, which means that it needs to know how to do so. | ||
This is handled by the [hie-bios](https://github.com/mpickering/hie-bios) project. | ||
This is handled under the hood by the [hie-bios](https://github.com/mpickering/hie-bios) application. | ||
In turn, `hie-bios` needs some configuration to identify all files, GHC options, etc., needed to compile a project. | ||
|
||
**For a full explanation of how `hie-bios` determines the project build configuration, and how to configure it manually, refer to the [hie-bios README](https://github.com/mpickering/hie-bios/blob/master/README.md).** | ||
There are several ways to provide this configuration to `hie-bios`, detailed below. | ||
|
||
At the moment, `haskell-language-server` has support to automatically detect your project build configuration to handle most use cases. | ||
### Implicit configuration | ||
If no `hie.yaml` file is present, `haskell-language-server` automatically detects your `hie-bios` configuration. | ||
**For most cases, this works just fine, and is the recommended way.** | ||
|
||
*So using a explicit `hie.yaml` file will not likely fix your ide setup*. It will do it almost only if you see an error like `Multi Cradle: No prefixes matched` | ||
See [the hie-bios documentation](https://github.com/haskell/hie-bios#implicit-configuration) for more information on implicit configuration. | ||
|
||
### Explicit, generated configuration | ||
Maybe using the implicit configuration does not suit you. | ||
E.g., it does not work, or you prefer to have explicit configuration in your project. | ||
In that case, you can automatically generate a `hie.yaml` file, using [implicit-hie](https://github.com/Avi-D-coder/implicit-hie): | ||
|
||
```shell | ||
gen-hie > hie.yaml # In the root directory of your project | ||
``` | ||
|
||
### Explicit, manual configuration | ||
Maybe using the generated `hie.yaml` file does not suit you. | ||
E.g., it still does not work, or you want to fine-tune the configuration. | ||
We recommend to start from the `hie.yaml` file generated by `implicit-hie` (see previous section) and modify it to suit your needs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this recommendation is no longer quite right for cabal projects at least. For cabal projects you can often use the "empty" cabal cradle, which often even works better than the one generated by This situation is a mess, unfortunately. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I reworked and simplified a bit this section in 63ba56a Basically rather than trying to re-explain the hie-bios documentation, we directly link to the relevant documentation |
||
|
||
If the automatic detection fails with that error you can configure `hie-bios` using a `hie.yaml` file in the root of the workspace. | ||
A `hie.yaml` file **explicitly** describes how to setup the environment to compile the various parts of your project. | ||
For that you need to know what *components* your project has, and the path associated with each one. | ||
So you will need some knowledge about | ||
[stack](https://docs.haskellstack.org/en/stable/build_command/#components) or [cabal](https://cabal.readthedocs.io/en/latest/cabal-commands.html?#cabal-v2-build) components. | ||
|
||
You also can use [implicit-hie](https://github.com/Avi-D-coder/implicit-hie) to automatically generate `hie.yaml` files for | ||
the most common stack and cabal configurations | ||
**For a full explanation of how to configure it manually, refer to the [hie-bios documentation](https://github.com/mpickering/hie-bios/blob/master/README.md).** | ||
|
||
#### Examples of explicit `hie-yaml` configurations | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should include the "empty cabal cradle" which mostly works for everything now:
(you might ask "why doesn't implicit-hie generate this?" which is a good question...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, I added it in 63ba56a |
||
|
||
For example, to state that you want to use `stack` then the configuration file | ||
would look like: | ||
##### Single Stack component | ||
|
||
```yaml | ||
cradle: | ||
stack: | ||
component: "haskell-language-server:lib" | ||
``` | ||
|
||
If you use `cabal` then you probably need to specify which component you want | ||
to use. | ||
##### Single Cabal component | ||
|
||
```yaml | ||
cradle: | ||
cabal: | ||
component: "lib:haskell-language-server" | ||
``` | ||
|
||
If you have a project with multiple components, you can use a cabal-multi | ||
cradle: | ||
##### Multiple Stack components | ||
|
||
```yaml | ||
cradle: | ||
cabal: | ||
stack: | ||
- path: "./test/functional/" | ||
component: "haskell-language-server:func-test" | ||
- path: "./test/utils/" | ||
component: "haskell-language-server:hls-test-utils" | ||
- path: "./exe/Main.hs" | ||
component: "haskell-language-server:exe:haskell-language-server" | ||
- path: "./exe/Wrapper.hs" | ||
component: "haskell-language-server:exe:haskell-language-server-wrapper" | ||
- path: "./src" | ||
component: "lib:haskell-language-server" | ||
component: "haskell-language-server:lib" | ||
- path: "./ghcide/src" | ||
component: "ghcide:lib:ghcide" | ||
- path: "./ghcide/exe" | ||
component: "ghcide:exe:ghcide" | ||
``` | ||
|
||
Equivalently, you can use stack: | ||
##### Multiple Cabal components | ||
|
||
```yaml | ||
cradle: | ||
stack: | ||
cabal: | ||
- path: "./test/functional/" | ||
component: "haskell-language-server:func-test" | ||
- path: "./test/utils/" | ||
component: "haskell-language-server:hls-test-utils" | ||
- path: "./exe/Main.hs" | ||
component: "haskell-language-server:exe:haskell-language-server" | ||
- path: "./exe/Wrapper.hs" | ||
component: "haskell-language-server:exe:haskell-language-server-wrapper" | ||
- path: "./src" | ||
component: "haskell-language-server:lib" | ||
component: "lib:haskell-language-server" | ||
- path: "./ghcide/src" | ||
component: "ghcide:lib:ghcide" | ||
- path: "./ghcide/exe" | ||
component: "ghcide:exe:ghcide" | ||
``` | ||
|
||
Or you can explicitly state the program which should be used to collect | ||
##### Custom program | ||
You can explicitly state the program which should be used to collect | ||
the options by supplying the path to the program. It is interpreted | ||
relative to the current working directory if it is not an absolute path. | ||
|
||
|
@@ -196,6 +210,12 @@ dependencies: | |
- someDep | ||
``` | ||
|
||
### Common problems | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should go in the Troubleshooting page, perhaps? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, done in 386f87c |
||
|
||
#### Multi Cradle: No prefixes matched | ||
The error message `Multi Cradle: No prefixes matched` usually means that implicit configuration failed. | ||
In that case, you must use explicit configuration. | ||
|
||
### How to show local documentation on hover | ||
|
||
Haskell Language Server can display Haddock documentation on hover and completions if the project and | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,79 +108,73 @@ $ cabal run haskell-language-server:func-test -- -p "hlint enables" | |
|
||
## Using HLS on HLS code | ||
|
||
Project source code should load without `hie.yaml` setup. | ||
Refer to the [HLS project configuration guidelines](../configuration.md#configuring-your-project-build) as they also apply to the HLS project itself. | ||
|
||
In other cases: | ||
|
||
1. Check if `hie.yaml` (& `hie.yml`) files left from previous configurations. | ||
|
||
2. If the main project needs special configuration, note that other internal subprojects probably also would need configuration. | ||
|
||
To create an explicit configuration for all projects - use [implicit-hie](https://github.com/Avi-D-coder/implicit-hie) generator directly: | ||
|
||
```shell | ||
gen-hie > hie.yaml # into the main HLS directory | ||
``` | ||
|
||
that configuration should help. | ||
|
||
3. Inspect & tune configuration explicitly. | ||
|
||
[Configuring project build](../configuration.md#configuring-your-project-build) applies to HLS project source code loading just as to any other. | ||
|
||
Note: HLS may implicitly detect codebase as a Stack project (see [hie-bios implicit configuration documentation](https://github.com/haskell/hie-bios/blob/master/README.md#implicit-configuration)). To use Cabal, try creating an `hie.yaml` file: | ||
Note: HLS implicitly detects the HLS codebase as a Stack project (since there is a `stack.yaml` file). | ||
If you want HLS to use Cabal, create this `hie.yaml` file at the root of the project: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
```yaml | ||
cradle: | ||
cabal: | ||
``` | ||
|
||
### Manually testing your hacked HLS | ||
If you want to test HLS while hacking on it, follow the steps below. | ||
|
||
#### Using Cabal | ||
## Manually testing your hacked HLS | ||
If you want to test HLS while hacking on it (you can even test it on HLS codebase itself, see previous section), you need to: | ||
|
||
- Whenever you want to build HLS, call `cabal install exe:haskell-language-server --overwrite-policy=always`. | ||
At the end of the output you will find the path the HLS executable was installed to, i.e.: | ||
1. (Once) Find the path to the hacked HLS you build | ||
2. (Once) Configure your editor to use it | ||
3. (Every time you change the HLS code) Rebuild HLS | ||
4. (Every time you change the HLS code) Restart the LSP workspace | ||
|
||
``` | ||
... | ||
Resolving dependencies... | ||
Symlinking 'haskell-language-server' to | ||
'/home/user/.cabal/bin/haskell-language-server' | ||
Symlinking 'haskell-language-server-wrapper' to | ||
'/home/user/.cabal/bin/haskell-language-server-wrapper' | ||
``` | ||
### Find the path to the hacked HLS you build | ||
Note that unless you change the GHC version or the HLS version between builds, the path should remain the same, this is why you need to set it only once. | ||
|
||
In this example output, the path would be `/home/user/.cabal/bin/haskell-language-server`. | ||
#### Using Cabal | ||
Run: | ||
```shell | ||
$ cabal build exe:haskell-language-server && cabal list-bin exe:haskell-language-server | ||
[..] | ||
<some long path>/haskell-language-server | ||
``` | ||
Comment on lines
+133
to
+138
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know I am a little bit late to the party, but I feel like using the That's why we previously recommended using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Arguably the opposite argument is as inconvenient for others 😅
I guess different people have different priorities 😅 And it's completely ok by the way! In any case it might also be beneficial to add this caveat to the documentation, if you suspect many will get confused by it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough, the arguments are also convincing. Ideally, we'd have a command What do you think about instructions such as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW I use |
||
|
||
- Open some codebase on which you want to test your local HLS in your favorite editor (it can also be the HLS codebase itself: see previous section for configuration) | ||
- Configure this editor to use your custom HLS executable by using the path you obtained previously. | ||
- Restart HLS in your project: | ||
- With VS Code: Press `CTRL + Shift + P` and type `Haskell: Restart Haskell LSP Server` | ||
- With Emacs: `lsp-workspace-restart` | ||
#### Using Stack | ||
Run: | ||
```shell | ||
$ echo $(pwd)/$(stack path --dist-dir)/build/haskell-language-server/haskell-language-server | ||
[..] | ||
<some long path>/haskell-language-server | ||
``` | ||
|
||
##### VS Code | ||
### Configure your editor to use it | ||
|
||
When using VS Code you can set up a test project to use a specific HLS executable: | ||
#### VS Code | ||
When using VS Code you can set up each project to use a specific HLS executable: | ||
|
||
- If it doesn't already exist in your project directory, create a directory called `.vscode`. | ||
- In the `.vscode` directory create a file called `settings.json` with the below contents. The path used here is the one obtained by using the `cabal` install command. | ||
|
||
- In the `.vscode` directory create a file called `settings.json` with the below contents. | ||
```json | ||
{ | ||
"haskell.serverExecutablePath": "/home/user/.cabal/bin/haskell-language-server" | ||
"haskell.serverExecutablePath": "/path/to/your/hacked/haskell-language-server" | ||
} | ||
``` | ||
|
||
#### Using Stack | ||
#### Emacs | ||
There are several ways to configure the HLS server path: | ||
- `M-x customize-group<RET>lsp-haskell<RET>Lsp Haskell Server Path` | ||
- Evaluate `(setq lsp-haskell-server-path "/path/to/your/hacked/haskell-language-server")` | ||
- Create a file `.dir-locals.el` with the following content: | ||
```lisp | ||
((haskell-mode . ((lsp-haskell-server-path . "/path/to/your/hacked/haskell-language-server")))) | ||
``` | ||
|
||
### Rebuild HLS | ||
- With Stack: `stack build haskell-language-server:exe:haskell-language-server` | ||
- With Cabal: `cabal build exe:haskell-language-server` | ||
|
||
- Open some codebase on which you want to test your local HLS in your favorite editor (it can also be the HLS codebase itself: see previous section for configuration) | ||
- Configure this editor to use your custom HLS executable | ||
- To obtain the path to your local HLS executable: `$(stack path --dist-dir)/build/haskell-language-server/haskell-language-server` | ||
### Restart the LSP workspace | ||
|
||
- Build HLS | ||
- `stack build haskell-language-server:exe:haskell-language-server` | ||
- With VS Code: Press `Ctrl + Shift + p` and type `Haskell: Restart Haskell LSP Server` | ||
- With Emacs: `M-x lsp-workspace-restart` | ||
|
||
## Style guidelines | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is quite accurate. I believe we in fact will use
implicit-hie
in this instance, not thehie-bios
implicit auto-configuration...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 739e58f