about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/docs/dev/lsp-extensions.md')
-rw-r--r--src/tools/rust-analyzer/docs/dev/lsp-extensions.md1088
1 files changed, 1088 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
new file mode 100644
index 00000000000..f1815082e2e
--- /dev/null
+++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
@@ -0,0 +1,1088 @@
+<!---
+lsp/ext.rs hash: dd51139b0530147e
+
+If you need to change the above hash to make the test pass, please check if you
+need to adjust this doc as well and ping this issue:
+
+  https://github.com/rust-lang/rust-analyzer/issues/4604
+
+--->
+
+# LSP Extensions
+
+This document describes LSP extensions used by rust-analyzer.
+It's a best effort document, when in doubt, consult the source (and send a PR with clarification ;-) ).
+We aim to upstream all non Rust-specific extensions to the protocol, but this is not a top priority.
+All capabilities are enabled via the `experimental` field of `ClientCapabilities` or `ServerCapabilities`.
+Requests which we hope to upstream live under `experimental/` namespace.
+Requests, which are likely to always remain specific to `rust-analyzer` are under `rust-analyzer/` namespace.
+
+If you want to be notified about the changes to this document, subscribe to [#4604](https://github.com/rust-lang/rust-analyzer/issues/4604).
+
+## Configuration in `initializationOptions`
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/567
+
+The `initializationOptions` field of the `InitializeParams` of the initialization request should contain the `"rust-analyzer"` section of the configuration.
+
+`rust-analyzer` normally sends a `"workspace/configuration"` request with `{ "items": ["rust-analyzer"] }` payload.
+However, the server can't do this during initialization.
+At the same time some essential configuration parameters are needed early on, before servicing requests.
+For this reason, we ask that `initializationOptions` contains the configuration, as if the server did make a `"workspace/configuration"` request.
+
+If a language client does not know about `rust-analyzer`'s configuration options it can get sensible defaults by doing any of the following:
+ * Not sending `initializationOptions`
+ * Sending `"initializationOptions": null`
+ * Sending `"initializationOptions": {}`
+
+## Snippet `TextEdit`
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/724
+
+**Experimental Client Capability:** `{ "snippetTextEdit": boolean }`
+
+If this capability is set, `WorkspaceEdit`s returned from `codeAction` requests and `TextEdit`s returned from `textDocument/onTypeFormatting` requests might contain `SnippetTextEdit`s instead of usual `TextEdit`s:
+
+```typescript
+interface SnippetTextEdit extends TextEdit {
+    insertTextFormat?: InsertTextFormat;
+    annotationId?: ChangeAnnotationIdentifier;
+}
+```
+
+```typescript
+export interface TextDocumentEdit {
+    textDocument: OptionalVersionedTextDocumentIdentifier;
+    edits: (TextEdit | SnippetTextEdit)[];
+}
+```
+
+When applying such code action or text edit, the editor should insert snippet, with tab stops and placeholders.
+At the moment, rust-analyzer guarantees that only a single `TextDocumentEdit` will have edits which can be `InsertTextFormat.Snippet`.
+Any additional `TextDocumentEdit`s will only have edits which are `InsertTextFormat.PlainText`.
+
+### Example
+
+"Add `derive`" code action transforms `struct S;` into `#[derive($0)] struct S;`
+
+### Unresolved Questions
+
+* Where exactly are `SnippetTextEdit`s allowed (only in code actions at the moment)?
+* Can snippets span multiple files (so far, no)?
+
+## `CodeAction` Groups
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/994
+
+**Experimental Client Capability:** `{ "codeActionGroup": boolean }`
+
+If this capability is set, `CodeAction`s returned from the server contain an additional field, `group`:
+
+```typescript
+interface CodeAction {
+    title: string;
+    group?: string;
+    ...
+}
+```
+
+All code-actions with the same `group` should be grouped under single (extendable) entry in lightbulb menu.
+The set of actions `[ { title: "foo" }, { group: "frobnicate", title: "bar" }, { group: "frobnicate", title: "baz" }]` should be rendered as
+
+```
+💡
+  +-------------+
+  | foo         |
+  +-------------+-----+
+  | frobnicate >| bar |
+  +-------------+-----+
+                | baz |
+                +-----+
+```
+
+Alternatively, selecting `frobnicate` could present a user with an additional menu to choose between `bar` and `baz`.
+
+### Example
+
+```rust
+fn main() {
+    let x: Entry/*cursor here*/ = todo!();
+}
+```
+
+Invoking code action at this position will yield two code actions for importing `Entry` from either `collections::HashMap` or `collection::BTreeMap`, grouped under a single "import" group.
+
+### Unresolved Questions
+
+* Is a fixed two-level structure enough?
+* Should we devise a general way to encode custom interaction protocols for GUI refactorings?
+
+## Parent Module
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/1002
+
+**Experimental Server Capability:** `{ "parentModule": boolean }`
+
+This request is sent from client to server to handle "Goto Parent Module" editor action.
+
+**Method:** `experimental/parentModule`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:** `Location | Location[] | LocationLink[] | null`
+
+
+### Example
+
+```rust
+// src/main.rs
+mod foo;
+// src/foo.rs
+
+/* cursor here*/
+```
+
+`experimental/parentModule` returns a single `Link` to the `mod foo;` declaration.
+
+### Unresolved Question
+
+* An alternative would be to use a more general "gotoSuper" request, which would work for super methods, super classes and super modules.
+  This is the approach IntelliJ Rust is taking.
+  However, experience shows that super module (which generally has a feeling of navigation between files) should be separate.
+  If you want super module, but the cursor happens to be inside an overridden function, the behavior with single "gotoSuper" request is surprising.
+
+## Join Lines
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/992
+
+**Experimental Server Capability:** `{ "joinLines": boolean }`
+
+This request is sent from client to server to handle "Join Lines" editor action.
+
+**Method:** `experimental/joinLines`
+
+**Request:**
+
+```typescript
+interface JoinLinesParams {
+    textDocument: TextDocumentIdentifier,
+    /// Currently active selections/cursor offsets.
+    /// This is an array to support multiple cursors.
+    ranges: Range[],
+}
+```
+
+**Response:** `TextEdit[]`
+
+### Example
+
+```rust
+fn main() {
+    /*cursor here*/let x = {
+        92
+    };
+}
+```
+
+`experimental/joinLines` yields (curly braces are automagically removed)
+
+```rust
+fn main() {
+    let x = 92;
+}
+```
+
+### Unresolved Question
+
+* What is the position of the cursor after `joinLines`?
+  Currently, this is left to editor's discretion, but it might be useful to specify on the server via snippets.
+  However, it then becomes unclear how it works with multi cursor.
+
+## On Enter
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/1001
+
+**Experimental Server Capability:** `{ "onEnter": boolean }`
+
+This request is sent from client to server to handle the <kbd>Enter</kbd> key press.
+
+**Method:** `experimental/onEnter`
+
+**Request:**: `TextDocumentPositionParams`
+
+**Response:**
+
+```typescript
+SnippetTextEdit[]
+```
+
+### Example
+
+```rust
+fn main() {
+    // Some /*cursor here*/ docs
+    let x = 92;
+}
+```
+
+`experimental/onEnter` returns the following snippet
+
+```rust
+fn main() {
+    // Some
+    // $0 docs
+    let x = 92;
+}
+```
+
+The primary goal of `onEnter` is to handle automatic indentation when opening a new line.
+This is not yet implemented.
+The secondary goal is to handle fixing up syntax, like continuing doc strings and comments, and escaping `\n` in string literals.
+
+As proper cursor positioning is raison d'être for `onEnter`, it uses `SnippetTextEdit`.
+
+### Unresolved Question
+
+* How to deal with synchronicity of the request?
+  One option is to require the client to block until the server returns the response.
+  Another option is to do a operational transforms style merging of edits from client and server.
+  A third option is to do a record-replay: client applies heuristic on enter immediately, then applies all user's keypresses.
+  When the server is ready with the response, the client rollbacks all the changes and applies the recorded actions on top of the correct response.
+* How to deal with multiple carets?
+* Should we extend this to arbitrary typed events and not just `onEnter`?
+
+## Structural Search Replace (SSR)
+
+**Experimental Server Capability:** `{ "ssr": boolean }`
+
+This request is sent from client to server to handle structural search replace -- automated syntax tree based transformation of the source.
+
+**Method:** `experimental/ssr`
+
+**Request:**
+
+```typescript
+interface SsrParams {
+    /// Search query.
+    /// The specific syntax is specified outside of the protocol.
+    query: string,
+    /// If true, only check the syntax of the query and don't compute the actual edit.
+    parseOnly: boolean,
+    /// The current text document. This and `position` will be used to determine in what scope
+    /// paths in `query` should be resolved.
+    textDocument: TextDocumentIdentifier;
+    /// Position where SSR was invoked.
+    position: Position;
+    /// Current selections. Search/replace will be restricted to these if non-empty.
+    selections: Range[];
+}
+```
+
+**Response:**
+
+```typescript
+WorkspaceEdit
+```
+
+### Example
+
+SSR with query `foo($a, $b) ==>> ($a).foo($b)` will transform, eg `foo(y + 5, z)` into `(y + 5).foo(z)`.
+
+### Unresolved Question
+
+* Probably needs search without replace mode
+* Needs a way to limit the scope to certain files.
+
+## Matching Brace
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/999
+
+**Experimental Server Capability:** `{ "matchingBrace": boolean }`
+
+This request is sent from client to server to handle "Matching Brace" editor action.
+
+**Method:** `experimental/matchingBrace`
+
+**Request:**
+
+```typescript
+interface MatchingBraceParams {
+    textDocument: TextDocumentIdentifier,
+    /// Position for each cursor
+    positions: Position[],
+}
+```
+
+**Response:**
+
+```typescript
+Position[]
+```
+
+### Example
+
+```rust
+fn main() {
+    let x: Vec<()>/*cursor here*/ = vec![];
+}
+```
+
+`experimental/matchingBrace` yields the position of `<`.
+In many cases, matching braces can be handled by the editor.
+However, some cases (like disambiguating between generics and comparison operations) need a real parser.
+Moreover, it would be cool if editors didn't need to implement even basic language parsing
+
+### Unresolved Question
+
+* Should we return a nested brace structure, to allow [paredit](https://paredit.org/)-like actions of jump *out* of the current brace pair?
+  This is how `SelectionRange` request works.
+* Alternatively, should we perhaps flag certain `SelectionRange`s as being brace pairs?
+
+## Runnables
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/944
+
+**Experimental Server Capability:** `{ "runnables": { "kinds": string[] } }`
+
+This request is sent from client to server to get the list of things that can be run (tests, binaries, `cargo check -p`).
+
+**Method:** `experimental/runnables`
+
+**Request:**
+
+```typescript
+interface RunnablesParams {
+    textDocument: TextDocumentIdentifier;
+    /// If null, compute runnables for the whole file.
+    position?: Position;
+}
+```
+
+**Response:** `Runnable[]`
+
+```typescript
+interface Runnable {
+    label: string;
+    /// If this Runnable is associated with a specific function/module, etc., the location of this item
+    location?: LocationLink;
+    /// Running things is necessary technology specific, `kind` needs to be advertised via server capabilities,
+    // the type of `args` is specific to `kind`. The actual running is handled by the client.
+    kind: string;
+    args: any;
+}
+```
+
+rust-analyzer supports only one `kind`, `"cargo"`. The `args` for `"cargo"` look like this:
+
+```typescript
+{
+    workspaceRoot?: string;
+    cargoArgs: string[];
+    cargoExtraArgs: string[];
+    executableArgs: string[];
+    expectTest?: boolean;
+    overrideCargo?: string;
+}
+```
+
+## Test explorer
+
+**Experimental Client Capability:** `{ "testExplorer": boolean }`
+
+If this capability is set, the `experimental/discoveredTests` notification will be sent from the
+server to the client.
+
+**Method:** `experimental/discoverTest`
+
+**Request:** `DiscoverTestParams`
+
+```typescript
+interface DiscoverTestParams {
+    // The test that we need to resolve its children. If not present,
+    // the response should return top level tests.
+    testId?: string | undefined;
+}
+```
+
+**Response:** `DiscoverTestResults`
+
+```typescript
+interface TestItem {
+    // A unique identifier for the test
+    id: string;
+    // The file containing this test
+    textDocument?: lc.TextDocumentIdentifier | undefined;
+    // The range in the file containing this test
+    range?: lc.Range | undefined;
+    // A human readable name for this test
+    label: string;
+    // The kind of this test item. Based on the kind,
+	// an icon is chosen by the editor.
+    kind: "package" | "module" | "test";
+    // True if this test may have children not available eagerly
+    canResolveChildren: boolean;
+    // The id of the parent test in the test tree. If not present, this test
+    // is a top level test.
+    parent?: string | undefined;
+    // The information useful for running the test. The client can use `runTest`
+    // request for simple execution, but for more complex execution forms
+    // like debugging, this field is useful.
+    // Note that this field includes some information about label and location as well, but
+    // those exist just for keeping things in sync with other methods of running runnables
+    // (for example using one consistent name in the vscode's launch.json) so for any propose
+    // other than running tests this field should not be used.
+    runnable?: Runnable | undefined;
+};
+
+interface DiscoverTestResults {
+    // The discovered tests.
+    tests: TestItem[];
+    // For each test which its id is in this list, the response
+    // contains all tests that are children of this test, and
+    // client should remove old tests not included in the response.
+    scope: string[] | undefined;
+    // For each file which its uri is in this list, the response
+    // contains all tests that are located in this file, and
+    // client should remove old tests not included in the response.
+    scopeFile: lc.TextDocumentIdentifier[] | undefined;
+}
+```
+
+**Method:** `experimental/discoveredTests`
+
+**Notification:** `DiscoverTestResults`
+
+This notification is sent from the server to the client when the
+server detect changes in the existing tests. The `DiscoverTestResults` is
+the same as the one in `experimental/discoverTest` response.
+
+**Method:** `experimental/runTest`
+
+**Request:** `RunTestParams`
+
+```typescript
+interface RunTestParams {
+    // Id of the tests to be run. If a test is included, all of its children are included implicitly. If
+    // this property is undefined, then the server should simply run all tests.
+    include?: string[] | undefined;
+    // An array of test ids the user has marked as excluded from the test included in this run; exclusions
+    // should apply after inclusions.
+    // May be omitted if no exclusions were requested. Server should not run excluded tests or
+    // any children of excluded tests.
+    exclude?: string[] | undefined;
+}
+```
+
+**Response:** `void`
+
+**Method:** `experimental/endRunTest`
+
+**Notification:**
+
+This notification is sent from the server to the client when the current running
+session is finished. The server should not send any run notification
+after this.
+
+**Method:** `experimental/abortRunTest`
+
+**Notification:**
+
+This notification is sent from the client to the server when the user is no longer
+interested in the test results. The server should clean up its resources and send
+a `experimental/endRunTest` when is done.
+
+**Method:** `experimental/changeTestState`
+
+**Notification:** `ChangeTestStateParams`
+
+```typescript
+type TestState = { tag: "passed" }
+    | {
+        tag: "failed";
+        // The standard error of the test, containing the panic message. Clients should
+        // render it similar to a terminal, and e.g. handle ansi colors.
+        message: string;
+    }
+    | { tag: "started" }
+    | { tag: "enqueued" }
+    | { tag: "skipped" };
+
+interface ChangeTestStateParams {
+    testId: string;
+    state: TestState;
+}
+```
+
+**Method:** `experimental/appendOutputToRunTest`
+
+**Notification:** `string`
+
+This notification is used for reporting messages independent of any single test and related to the run session
+in general, e.g. cargo compiling progress messages or warnings.
+
+## Open External Documentation
+
+This request is sent from the client to the server to obtain web and local URL(s) for documentation related to the symbol under the cursor, if available.
+
+**Method:** `experimental/externalDocs`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:** `string | null`
+
+## Local Documentation
+
+**Experimental Client Capability:** `{ "localDocs": boolean }`
+
+If this capability is set, the `Open External Documentation` request returned from the server will have the following structure:
+
+```typescript
+interface ExternalDocsResponse {
+    web?: string;
+    local?: string;
+}
+```
+
+## Analyzer Status
+
+**Method:** `rust-analyzer/analyzerStatus`
+
+**Request:**
+
+```typescript
+interface AnalyzerStatusParams {
+    /// If specified, show dependencies of the current file.
+    textDocument?: TextDocumentIdentifier;
+}
+```
+
+**Response:** `string`
+
+Returns internal status message, mostly for debugging purposes.
+
+## Reload Workspace
+
+**Method:** `rust-analyzer/reloadWorkspace`
+
+**Request:** `null`
+
+**Response:** `null`
+
+Reloads project information (that is, re-executes `cargo metadata`).
+
+## Rebuild proc-macros
+
+**Method:** `rust-analyzer/rebuildProcMacros`
+
+**Request:** `null`
+
+**Response:** `null`
+
+Rebuilds build scripts and proc-macros, and runs the build scripts to reseed the build data.
+
+## Unindexed Project
+
+**Experimental Client Capability:** `{ "unindexedProject": boolean }`
+
+**Method:** `rust-analyzer/unindexedProject`
+
+**Notification:**
+
+```typescript
+interface UnindexedProjectParams {
+    /// A list of documents that rust-analyzer has determined are not indexed.
+    textDocuments: lc.TextDocumentIdentifier[]
+}
+```
+
+This notification is sent from the server to the client. The client is expected
+to determine the appropriate owners of `textDocuments` and update `linkedProjects`
+if an owner can be determined successfully.
+
+## Server Status
+
+**Experimental Client Capability:** `{ "serverStatusNotification": boolean }`
+
+**Method:** `experimental/serverStatus`
+
+**Notification:**
+
+```typescript
+interface ServerStatusParams {
+    /// `ok` means that the server is completely functional.
+    ///
+    /// `warning` means that the server is partially functional.
+    /// It can answer correctly to most requests, but some results
+    /// might be wrong due to, for example, some missing dependencies.
+    ///
+    /// `error` means that the server is not functional. For example,
+    /// there's a fatal build configuration problem. The server might
+    /// still give correct answers to simple requests, but most results
+    /// will be incomplete or wrong.
+    health: "ok" | "warning" | "error",
+    /// Is there any pending background work which might change the status?
+    /// For example, are dependencies being downloaded?
+    quiescent: boolean,
+    /// Explanatory message to show on hover.
+    message?: string,
+}
+```
+
+This notification is sent from server to client.
+The client can use it to display *persistent* status to the user (in modline).
+It is similar to the `showMessage`, but is intended for stares rather than point-in-time events.
+
+Note that this functionality is intended primarily to inform the end user about the state of the server.
+In particular, it's valid for the client to completely ignore this extension.
+Clients are discouraged from but are allowed to use the `health` status to decide if it's worth sending a request to the server.
+
+### Controlling Flycheck
+
+The flycheck/checkOnSave feature can be controlled via notifications sent by the client to the server.
+
+**Method:** `rust-analyzer/runFlycheck`
+
+**Notification:**
+
+```typescript
+interface RunFlycheckParams {
+    /// The text document whose cargo workspace flycheck process should be started.
+    /// If the document is null or does not belong to a cargo workspace all flycheck processes will be started.
+    textDocument: lc.TextDocumentIdentifier | null;
+}
+```
+
+Triggers the flycheck processes.
+
+
+**Method:** `rust-analyzer/clearFlycheck`
+
+**Notification:**
+
+```typescript
+interface ClearFlycheckParams {}
+```
+
+Clears the flycheck diagnostics.
+
+**Method:** `rust-analyzer/cancelFlycheck`
+
+**Notification:**
+
+```typescript
+interface CancelFlycheckParams {}
+```
+
+Cancels all running flycheck processes.
+
+## Syntax Tree
+
+**Method:** `rust-analyzer/syntaxTree`
+
+**Request:**
+
+```typescript
+interface SyntaxTreeParams {
+    textDocument: TextDocumentIdentifier,
+    range?: Range,
+}
+```
+
+**Response:** `string`
+
+Returns textual representation of a parse tree for the file/selected region.
+Primarily for debugging, but very useful for all people working on rust-analyzer itself.
+
+## View Hir
+
+**Method:** `rust-analyzer/viewHir`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:** `string`
+
+Returns a textual representation of the HIR of the function containing the cursor.
+For debugging or when working on rust-analyzer itself.
+
+## View Mir
+
+**Method:** `rust-analyzer/viewMir`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:** `string`
+
+Returns a textual representation of the MIR of the function containing the cursor.
+For debugging or when working on rust-analyzer itself.
+
+## Interpret Function
+
+**Method:** `rust-analyzer/interpretFunction`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:** `string`
+
+Tries to evaluate the function using internal rust analyzer knowledge, without compiling
+the code. Currently evaluates the function under cursor, but will give a runnable in
+future. Highly experimental.
+
+## View File Text
+
+**Method:** `rust-analyzer/viewFileText`
+
+**Request:** `TextDocumentIdentifier`
+
+**Response:** `string`
+
+Returns the text of a file as seen by the server.
+This is for debugging file sync problems.
+
+## View ItemTree
+
+**Method:** `rust-analyzer/viewItemTree`
+
+**Request:**
+
+```typescript
+interface ViewItemTreeParams {
+    textDocument: TextDocumentIdentifier,
+}
+```
+
+**Response:** `string`
+
+Returns a textual representation of the `ItemTree` of the currently open file, for debugging.
+
+## View Crate Graph
+
+**Method:** `rust-analyzer/viewCrateGraph`
+
+**Request:**
+
+```typescript
+interface ViewCrateGraphParams {
+    full: boolean,
+}
+```
+
+**Response:** `string`
+
+Renders rust-analyzer's crate graph as an SVG image.
+
+If `full` is `true`, the graph includes non-workspace crates (crates.io dependencies as well as sysroot crates).
+
+## Shuffle Crate Graph
+
+**Method:** `rust-analyzer/shuffleCrateGraph`
+
+**Request:** `null`
+
+Shuffles the crate IDs in the crate graph, for debugging purposes.
+
+## Expand Macro
+
+**Method:** `rust-analyzer/expandMacro`
+
+**Request:**
+
+```typescript
+interface ExpandMacroParams {
+    textDocument: TextDocumentIdentifier,
+    position: Position,
+}
+```
+
+**Response:**
+
+```typescript
+interface ExpandedMacro {
+    name: string,
+    expansion: string,
+}
+```
+
+Expands macro call at a given position.
+
+## Hover Actions
+
+**Experimental Client Capability:** `{ "hoverActions": boolean }`
+
+If this capability is set, `Hover` request returned from the server might contain an additional field, `actions`:
+
+```typescript
+interface Hover {
+    ...
+    actions?: CommandLinkGroup[];
+}
+
+interface CommandLink extends Command {
+    /**
+     * A tooltip for the command, when represented in the UI.
+     */
+    tooltip?: string;
+}
+
+interface CommandLinkGroup {
+    title?: string;
+    commands: CommandLink[];
+}
+```
+
+Such actions on the client side are appended to a hover bottom as command links:
+```
+  +-----------------------------+
+  | Hover content               |
+  |                             |
+  +-----------------------------+
+  | _Action1_ | _Action2_       |  <- first group, no TITLE
+  +-----------------------------+
+  | TITLE _Action1_ | _Action2_ |  <- second group
+  +-----------------------------+
+  ...
+```
+
+## Open Cargo.toml
+
+**Upstream Issue:** https://github.com/rust-lang/rust-analyzer/issues/6462
+
+**Experimental Server Capability:** `{ "openCargoToml": boolean }`
+
+This request is sent from client to server to open the current project's Cargo.toml
+
+**Method:** `experimental/openCargoToml`
+
+**Request:** `OpenCargoTomlParams`
+
+**Response:** `Location | null`
+
+
+### Example
+
+```rust
+// Cargo.toml
+[package]
+// src/main.rs
+
+/* cursor here*/
+```
+
+`experimental/openCargoToml` returns a single `Link` to the start of the `[package]` keyword.
+
+## Related tests
+
+This request is sent from client to server to get the list of tests for the specified position.
+
+**Method:** `rust-analyzer/relatedTests`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:** `TestInfo[]`
+
+```typescript
+interface TestInfo {
+    runnable: Runnable;
+}
+```
+
+## Hover Range
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/377
+
+**Experimental Server Capability:** { "hoverRange": boolean }
+
+This extension allows passing a `Range` as a `position` field of `HoverParams`.
+The primary use-case is to use the hover request to show the type of the expression currently selected.
+
+```typescript
+interface HoverParams extends WorkDoneProgressParams {
+    textDocument: TextDocumentIdentifier;
+    position: Range | Position;
+}
+```
+Whenever the client sends a `Range`, it is understood as the current selection and any hover included in the range will show the type of the expression if possible.
+
+### Example
+
+```rust
+fn main() {
+    let expression = $01 + 2 * 3$0;
+}
+```
+
+Triggering a hover inside the selection above will show a result of `i32`.
+
+## Move Item
+
+**Upstream Issue:** https://github.com/rust-lang/rust-analyzer/issues/6823
+
+This request is sent from client to server to move item under cursor or selection in some direction.
+
+**Method:** `experimental/moveItem`
+
+**Request:** `MoveItemParams`
+
+**Response:** `SnippetTextEdit[]`
+
+```typescript
+export interface MoveItemParams {
+    textDocument: TextDocumentIdentifier,
+    range: Range,
+    direction: Direction
+}
+
+export const enum Direction {
+    Up = "Up",
+    Down = "Down"
+}
+```
+
+## Workspace Symbols Filtering
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/941
+
+**Experimental Server Capability:** `{ "workspaceSymbolScopeKindFiltering": boolean }`
+
+Extends the existing `workspace/symbol` request with ability to filter symbols by broad scope and kind of symbol.
+If this capability is set, `workspace/symbol` parameter gains two new optional fields:
+
+
+```typescript
+interface WorkspaceSymbolParams {
+    /**
+     * Return only the symbols defined in the specified scope.
+     */
+    searchScope?: WorkspaceSymbolSearchScope;
+    /**
+     * Return only the symbols of specified kinds.
+     */
+    searchKind?: WorkspaceSymbolSearchKind;
+    ...
+}
+
+const enum WorkspaceSymbolSearchScope {
+    Workspace = "workspace",
+    WorkspaceAndDependencies = "workspaceAndDependencies"
+}
+
+const enum WorkspaceSymbolSearchKind {
+    OnlyTypes = "onlyTypes",
+    AllSymbols = "allSymbols"
+}
+```
+
+## Client Commands
+
+**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/642
+
+**Experimental Client Capability:** `{ "commands?": ClientCommandOptions }`
+
+Certain LSP types originating on the server, notably code lenses, embed commands.
+Commands can be serviced either by the server or by the client.
+However, the server doesn't know which commands are available on the client.
+
+This extensions allows the client to communicate this info.
+
+
+```typescript
+export interface ClientCommandOptions {
+    /**
+     * The commands to be executed on the client
+     */
+    commands: string[];
+}
+```
+
+## Colored Diagnostic Output
+
+**Experimental Client Capability:** `{ "colorDiagnosticOutput": boolean }`
+
+If this capability is set, the "full compiler diagnostics" provided by `checkOnSave`
+will include ANSI color and style codes to render the diagnostic in a similar manner
+as `cargo`. This is translated into `--message-format=json-diagnostic-rendered-ansi`
+when flycheck is run, instead of the default `--message-format=json`.
+
+The full compiler rendered diagnostics are included in the server response
+regardless of this capability:
+
+```typescript
+// https://microsoft.github.io/language-server-protocol/specifications/specification-current#diagnostic
+export interface Diagnostic {
+    ...
+    data?: {
+        /**
+         * The human-readable compiler output as it would be printed to a terminal.
+         * Includes ANSI color and style codes if the client has set the experimental
+         * `colorDiagnosticOutput` capability.
+         */
+        rendered?: string;
+    };
+}
+```
+
+## Dependency Tree
+
+**Method:** `rust-analyzer/fetchDependencyList`
+
+**Request:**
+
+```typescript
+export interface FetchDependencyListParams {}
+```
+
+**Response:**
+```typescript
+export interface FetchDependencyListResult {
+    crates: {
+        name: string;
+        version: string;
+        path: string;
+    }[];
+}
+```
+Returns all crates from this workspace, so it can be used create a viewTree to help navigate the dependency tree.
+
+## View Recursive Memory Layout
+
+**Method:** `rust-analyzer/viewRecursiveMemoryLayout`
+
+**Request:** `TextDocumentPositionParams`
+
+**Response:**
+
+```typescript
+export interface RecursiveMemoryLayoutNode = {
+    /// Name of the item, or [ROOT], `.n` for tuples
+    item_name: string;
+    /// Full name of the type (type aliases are ignored)
+    typename: string;
+    /// Size of the type in bytes
+    size: number;
+    /// Alignment of the type in bytes
+    alignment: number;
+    /// Offset of the type relative to its parent (or 0 if its the root)
+    offset: number;
+    /// Index of the node's parent (or -1 if its the root)
+    parent_idx: number;
+    /// Index of the node's children (or -1 if it does not have children)
+    children_start: number;
+    /// Number of child nodes (unspecified it does not have children)
+    children_len: number;
+};
+
+export interface RecursiveMemoryLayout = {
+    nodes: RecursiveMemoryLayoutNode[];
+};
+```
+
+Returns a vector of nodes representing items in the datatype as a tree, `RecursiveMemoryLayout::nodes[0]` is the root node.
+
+If `RecursiveMemoryLayout::nodes::length == 0` we could not find a suitable type.
+
+Generic Types do not give anything because they are incomplete. Fully specified generic types do not give anything if they are selected directly but do work when a child of other types [this is consistent with other behavior](https://github.com/rust-lang/rust-analyzer/issues/15010).
+
+### Unresolved questions:
+
+- How should enums/unions be represented? currently they do not produce any children because they have multiple distinct sets of children.
+- Should niches be represented? currently they are not reported.
+- A visual representation of the memory layout is not specified, see the provided implementation for an example, however it may not translate well to terminal based editors or other such things.