# Dhall language support in VSCode/ium
The Dhall language integration consists of the following parts:
- The VSCode/ium plugin "Dhall Language Support" *([vscode-language-dhall](https://github.com/PanAeon/vscode-language-dhall))* adds syntax highlighting for Dhall files.
- The VSCode/ium plugin "Dhall LSP Server" *([vscode-dhall-lsp-server](https://github.com/PanAeon/vscode-dhall-lsp-server))* implements the LSP client – yes, there is a naming issue here – that communicates with the backend via the [LSP protocol](https://microsoft.github.io/language-server-protocol/specification) to provide advanced language features like error diagnostics or type information, etc.
- [*dhall-lsp-server*](https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-lsp-server), which is part of the [*dhall-haskell*](https://github.com/dhall-lang/dhall-haskell) project, implements the actual LSP server (i.e. the backend) that implements those language features in an editor agnostic way, though at the moment only a VSCode/ium frontend exists.
# Installation
The "official" releases can be installed as follows:
- **vscode-language-dhall** should be installed directly from VSCode/ium via the extensions marketplace.
- **vscode-dhall-lsp-server** can also be installed directly from the marketplace.
- **dhall-lsp-server** can be installed from hackage with `cabal install dhall-lsp-server`. See the
[`dhall-haskell` `README`](https://github.com/dhall-lang/dhall-haskell/blob/master/README.md) for pre-built binaries, as well as comprehensive installation and development instructions using *cabal*, *stack* or *nix*.
## Installing the latest development versions
**Note ** The versions of *vscode-dhall-lsp-server* and *dhall-lsp-server* need not necessarily match: an older client version will simply not expose all commands available in the backend, while an older server might not implement all commands exposed in the UI.
**vscode-dhall-lsp-server**
1. You need to have *npm* installed (e.g. using your favourite package manager).
2. Install the *typescript* compiler with `npm install -g typescript`. I recommend running `npm config set prefix '~/.local'` first to have npm install the executable in `~/.local/bin`; this avoids having to use *sudo* and polluting the rest of the system.
2. Check out a copy of the vscode-dhall-lsp-server repository into the VSCode/ium extensions folder
```
git clone git@github.com:PanAeon/vscode-dhall-lsp-server.git ~/.vscode-oss/extensions/vscode-dhall-lsp-server
```
(replace `~/.vscode-oss/` with `~/.vscode/` if you use VSCode instead of VSCodium).
3. Run the remaining commands in the checked-out directory
```
cd ~/.vscode-oss/extensions/vscode-dhall-lsp-server
```
4. Run `npm install` to fetch all library dependencies.
5. Run `npm run compile` to compile the typescript code to javascript.
6. Start (restart) VSCode/ium.
**dhall-lsp-server **
For detailed instructions as well as instructions using cabal or nix, see [`dhall-haskell` - `README`](https://github.com/dhall-lang/dhall-haskell/blob/master/README.md). To install dhall-lsp-server using *stack*:
1. Clone `git@github.com:dhall-lang/dhall-haskell.git`.
2. Inside the checked out repository run `stack install dhall-lsp-server`.
# Usage / Features
- **Diagnostics **
Every time you save a Dhall file it is parsed and typechecked, and any errors are marked. You can hover over the offending code to see the error message; to see a detailed explanation in the case of type errors, click the *Explain* link in the hover box.
- **Clickable imports **
As long as the file parses successfully, all (local file and remote) imports will be underlined and clickable.
- **Type on hover **
You can hover over any part of the code and it will tell you the type of the subexpression at that point – if you highlight an identifier you see its type; if you highlight the `->` in a function you will see the type of the entire function. This feature only works if the code passes the typechecker!
- **Code completion **
As you type you will be offered completions for:
- environment variables
- local imports
- identifiers in scope (as well as built-ins)
- record projections from 'easy-to-parse' records (of the form `ident1.ident2`[`.ident3...`])
- union constructors from 'easy-to-parse' unions
This is the only feature that works even when the file does not parse (or typecheck).
- **Formatting and Linting **
Right click and select "Format Document" to run the file through the Dhall formatter. The command "Lint and Format" can be selected via the *Command Palette* (Ctrl+Shift+P); this will run the linter over the file, removing unused let bindings and formatting the result.
- **Annotate lets **
Right-click the bound identifier in a `let` binding and select "Annotate Let binding with its type" to do exactly that.
- **Freeze imports **
Right-click an import statement and select "Freeze (refreeze) import" to add (or update) a semantic hash annotation to the import. You can also select "Freeze (refreeze) all imports" from the *Command Palette* to freeze all imports at once.
Note that this feature behaves slightly differently from the `dhall freeze` command in that the hash annotations are inserted without re-formatting the rest of the code!
# Developer notes
**dhall-lsp-server **
See [`dhall-haskell` - `README`](https://github.com/dhall-lang/dhall-haskell/blob/master/README.md) for general development instructions.
- You can also build using `stack build dhall-lsp-server` and point `vscode-dhall-lsp-server.executable` in the VSCode/ium settings to the stack build directory to avoid overriding the already installed version of the LSP server.
- You can use standard `Debug.Trace`/`putStrLn` debugging; the output will show up in the "Output" panel in VSCode/ium.
- To log all LSP communication set `vscode-dhall-lsp-server.trace.server` to `verbose` in VSCode/ium.
**vscode-dhall-lsp-server**
- Instead of working in `~/vscode-oss/extensions/...` directly, you can open a clone of the git repository in VSCode/ium and use the built-in debugging capabilities for extensions: press F5 (or click the green play button in the debugging tab) to launch a new VSCode/ium window with the modified extension (potentially shadowing the installed version).
- To package a release:
1. Make sure you have *npm* and *tsc* installed.
2. Use `npm install -g vsce` to install the *vsce* executable.
3. Run `vsce package` inside the git repo to package the extension, resulting in a file `vscode-dhall-lsp-server-x.x.x.vsix`.
4. You can install the packaged extension directly by opening the `.vsix` file from within VSCod/ium.