diff --git a/README.md b/README.md
index 7604b5446..e65c71ca5 100644
--- a/README.md
+++ b/README.md
@@ -57,8 +57,26 @@ For an example of usage of the server in a VS Code extension, see OCaml
Platform Extension implementation
[here](https://github.com/ocamllabs/vscode-ocaml-platform/blob/master/src/vscode_ocaml_platform.ml).
+### Merlin configuration (advanced)
+
+If you would like OCaml-LSP to respect your `.merlin` files, OCaml-LSP needs to
+be invoked with `--fallback-read-dot-merlin` argument passed to it.
+
## Features
+
+
The server supports the following LSP requests:
- [x] `textDocument/completion`
@@ -85,14 +103,125 @@ The server supports the following LSP requests:
Note that degrees of support for each LSP request are varying.
+### Semantic highlighting
+
+OCaml-LSP implements experimental semantic highlighting support (also known as
+semantic tokens support). The support can be activated by passing an evironment
+variable to OCaml-LSP:
+
+- To enable non-incremental (expectedly slower but more stable) version, pass
+ `OCAMLLSP_SEMANTIC_HIGHLIGHTING=full` environment variable to OCaml-LSP.
+
+- To enable incremental (potentially faster but more error-prone, at least on VS
+ Code) version, pass `OCAMLLSP_SEMANTIC_HIGHLIGHTING=full/delta` to OCaml-LSP.
+
+Tip (for VS Code OCaml Platform users): You can use `ocaml.server.extraEnv`
+setting in VS Code to pass various environment variables to OCaml-LSP.
+
+```json
+{
+ "ocaml.server.extraEnv": {
+ "OCAMLLSP_SEMANTIC_HIGHLIGHTING": "full"
+ },
+}
+```
+
+### LSP Extensions
+
The server also supports a number of OCaml specific extensions to the protocol:
-- [Infer interface](ocaml-lsp-server/docs/ocamllsp/inferIntf-spec.md)
- [Switch to implementation/interface](ocaml-lsp-server/docs/ocamllsp/switchImplIntf-spec.md)
+- [Infer interface](ocaml-lsp-server/docs/ocamllsp/inferIntf-spec.md)
- [Locate typed holes](ocaml-lsp-server/docs/ocamllsp/typedHoles-spec.md)
- [Find wrapping AST node](ocaml-lsp-server/docs/ocamllsp/wrappingAstNode-spec.md)
Note that editor support for these extensions varies. In general, the OCaml Platform extension for Visual Studio Code will have the best support.
+### Unorthodox features
+
+#### Destructing a value
+
+OCaml-LSP has a code action that allows to generate an exhaustive pattern
+matching for values. For example, placing a cursor near a value `(Some 10)|`
+where `|` is your cursor, OCaml-LSP will offer a code action "Destruct", which
+replaces `(Some 10)` with `(match Some with | None -> _ | Some _ -> _)`.
+Importantly, one can only destruct a value if OCaml-LSP can infer the value's
+precise type. The value can be type-annotated, e.g., if it's a function argument
+with polymorphic (or yet unknown) type in this context. In the code snippet
+below, we type-annotate the function parameter `v` because when we type `let f v
+= v|`, the type of `v` is polymorphic, so we can't destruct it.
+
+You can also usually destruct the value by placing the cursor on the wildcard
+(`_`) pattern in a pattern-match. For example,
+
+```ocaml
+type t = A | B of string option
+
+let f (v : t) = match v with | A -> _ | B _| -> _
+```
+
+invoking destruct near the cursor (`|`) in the snippet above, you get
+
+```ocaml
+type t = A | B of string option
+
+let f (v : t) = match v with | A -> _ | B (None) | B (Some _) -> _
+```
+
+Importantly, note the undescores in place of expressions in each branch of the
+pattern match above. The underscores that occur in place of expressions are
+called "typed holes" - a concept explained below.
+
+Tip (formatting): generated code may not be greatly formatted. If your project
+uses a formatter such as OCamlFormat, you can run formatting and get a
+well-formatted document (OCamlFormat supports typed holes formatting).
+
+Tip (for VS Code OCaml Platform users): You can destruct a value using a keybinding
+Alt+D or on MacOS Option+D
+
+#### Typed holes
+
+OCaml-LSP has a concept of a "typed hole" syntactically represented as `_`
+(underscore). A typed hole represents a well-typed "substitute" for an
+expression. OCaml-LSP considers these underscores that occur in place of
+expressions as a valid well-typed OCaml program: `let foo : int = _` (the typed
+hole has type `int` here) or `let bar = _ 10` (the hole has type `int -> 'a`).
+One can use such holes during development as temporary substitutes for
+expressions and "plug" the holes later with appropriate expressions.
+
+Note, files that incorporate typed holes are *not* considered valid OCaml by the
+OCaml compiler and, hence, cannot be compiled.
+
+Also, an underscore occurring in place of a pattern (for example `let _ = 10`)
+should not be confused with a typed hole that occurs in place of an expression,
+e.g., `let a = _`.
+
+#### Constructing values by type (experimental)
+
+OCaml-LSP can "construct" expressions based on the type required and offer them
+during auto-completion. For example, typing `_` (typed hole) in the snippet
+below will trigger auto-completion (`|` is your cursor):
+
+```ocaml
+(* file foo.ml *)
+type t = A | B of string option
+
+(* file bar.ml *)
+let v : Foo.t = _|
+```
+
+The auto-completion offers completions `Foo.A` and `Foo.B _`. You can further
+construct values by placing the cursor as such: `Foo.B _|` and triggering code
+action "Construct an expression" which offers completions `None` and `Some _`.
+Trigger the same code action in `Some _|` will offer `""` - one of the possible
+expressions to replace the typed hole with.
+
+Constructing a value is thus triggered either by typing `_` in place of an
+expression or trigger the code action "Construct an Expression". Also, the type
+of the value needs to be non-polymorphic to construct a meaningful value.
+
+Tip (for VS Code OCaml Platform users): You can construct a value using a keybinding
+Alt+C or on MacOS Option+C
+
## Integration with other tools
### Source file formatting: OCamlFormat & Refmt
@@ -104,7 +233,7 @@ formatting support. Note, however, that OCaml-LSP requires presence of
OCamlFormat configuration file, called `.ocamlformat`, in the project root to
be able to format source files in your project.
-### Formatting code on hover
+### Formatting code on hover
When you hover the cursor over OCaml code, the extension shows you the type of
the symbol. To get nicely formatted types, install
@@ -174,8 +303,9 @@ the lsp protocol covers a wider scope than merlin.
## Comparison to other LSP Servers for OCaml
-Note that the comparisons below makes no claims of being objective and may be
-entirely out of date:
+Note that the comparisons below make no claims of being objective and may be
+entirely out of
+date. Also, both servers seem deprecated.
- [reason-language-server](https://github.com/jaredly/reason-language-server)
This server supports
diff --git a/ocaml-lsp-server/docs/ocamllsp/inferIntf-spec.md b/ocaml-lsp-server/docs/ocamllsp/inferIntf-spec.md
index ae88f2415..1da302e65 100644
--- a/ocaml-lsp-server/docs/ocamllsp/inferIntf-spec.md
+++ b/ocaml-lsp-server/docs/ocamllsp/inferIntf-spec.md
@@ -1,4 +1,4 @@
-#### Infer Interface Request
+# Infer Interface Request
Infer Interface Request is sent from the client to the server to get the infered
interface for a given module implementation.
@@ -10,21 +10,21 @@ If the file cannot be found in the document store, an error will be returned.
Warning: this custom request is meant to be consumed by `ocaml-vscode-platform` exclusively,
it can be removed any time and should not be relied on.
-##### Client capability
+## Client capability
nothing that should be noted
-##### Server capability
+## Server capability
property name: `handleInferIntf`
property type: `boolean`
-##### Request
+## Request
- method: `ocamllsp/inferIntf`
- params: `DocumentUri` (see [`DocumentUri`](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#uri) in LSP specification)
-##### Response
+## Response
- result: String
- error: code and message set in case an exception happens during the processing of the request.
diff --git a/ocaml-lsp-server/docs/ocamllsp/switchImplIntf-spec.md b/ocaml-lsp-server/docs/ocamllsp/switchImplIntf-spec.md
index 819b885ac..9eef06f95 100644
--- a/ocaml-lsp-server/docs/ocamllsp/switchImplIntf-spec.md
+++ b/ocaml-lsp-server/docs/ocamllsp/switchImplIntf-spec.md
@@ -1,4 +1,4 @@
-#### Switch Implementation/Interface Request
+# Switch Implementation/Interface Request
Switch Implementation/Interface Request is sent from client to server to get
URI(s) of the file(s) that the current file can switch to, e.g., if the user
@@ -12,22 +12,22 @@ for creation is returned, e.g., if a user wants to switch from "foo.ml", but no
files already exist in the project that could be returned, a URI for "foo.mli"
is returned.
-##### Client capability
+## Client capability
nothing that should be noted
-##### Server capability
+## Server capability
property name: `handleSwitchImplIntf`
property type: `boolean`
-##### Request
+## Request
- method: `ocamllsp/switchImplIntf`
- params: `DocumentUri` (see [`DocumentUri`](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#uri) in LSP specification)
-##### Response
+## Response
- result: DocumentUri[] (non-empty)
- error: code and message set in case an exception happens during the `ocamllsp/switchImplIntf` request.
diff --git a/ocaml-lsp-server/docs/ocamllsp/wrappingAstNode-spec.md b/ocaml-lsp-server/docs/ocamllsp/wrappingAstNode-spec.md
index cbb562ed1..3a3525d7c 100644
--- a/ocaml-lsp-server/docs/ocamllsp/wrappingAstNode-spec.md
+++ b/ocaml-lsp-server/docs/ocamllsp/wrappingAstNode-spec.md
@@ -1,4 +1,6 @@
-#### Wrapping AST Node
+# Wrapping AST Node
+
+## Description
(Could also be named `Enclosing AST Node`)
@@ -30,16 +32,16 @@ The document URI in the request has to be open before sending a the request. If
Note: stability of this custom request is not guaranteed. Talk to the maintainers if you want to depend on it.
-##### Client capability
+## Client capability
nothing that should be noted
-##### Server capability
+## Server capability
property name: `handleWrappingAstNode`
property type: `boolean`
-##### Request
+## Request
- method: `ocamllsp/wrappingAstNode`
- params:
@@ -51,7 +53,7 @@ property type: `boolean`
}
```
-##### Response
+## Response
- result: `Range | null`
- error: code and message set in case an exception happens during the processing of the request.