From e4af9f6d8a4587fc66d13db4c10ad9260d813ed3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 May 2020 15:49:32 +0200 Subject: Reorgonise extensions docs --- docs/dev/lsp-extensions.md | 98 +++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 48 deletions(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 158d3c599..1cc51410b 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -3,7 +3,9 @@ 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 `experimental` field of `ClientCapabilities`. +All capabilities are enabled via `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. ## Snippet `TextEdit` @@ -38,6 +40,53 @@ At the moment, rust-analyzer guarantees that only a single edit will have `Inser * Where exactly are `SnippetTextEdit`s allowed (only in code actions at the moment)? * Can snippets span multiple files (so far, no)? +## `CodeAction` Groups + +**Issue:** https://github.com/microsoft/language-server-protocol/issues/994 + +**Client Capability:** `{ "codeActionGroup": boolean }` + +If this capability is set, `CodeAction` 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? + ## Join Lines **Issue:** https://github.com/microsoft/language-server-protocol/issues/992 @@ -123,50 +172,3 @@ SSR with query `foo($a:expr, $b:expr) ==>> ($a).foo($b)` will transform, eg `foo * Probably needs search without replace mode * Needs a way to limit the scope to certain files. - -## `CodeAction` Groups - -**Issue:** https://github.com/microsoft/language-server-protocol/issues/994 - -**Client Capability:** `{ "codeActionGroup": boolean }` - -If this capability is set, `CodeAction` 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? -- cgit v1.2.3 From 934227361623b258d833be20e464e1509cb432ad Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 May 2020 16:18:46 +0200 Subject: Document matchingBrace LSP request --- docs/dev/lsp-extensions.md | 47 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 1cc51410b..9fa1c5fc2 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -95,7 +95,7 @@ Invoking code action at this position will yield two code actions for importing This request is send from client to server to handle "Join Lines" editor action. -**Method:** `experimental/JoinLines` +**Method:** `experimental/joinLines` **Request:** @@ -172,3 +172,48 @@ SSR with query `foo($a:expr, $b:expr) ==>> ($a).foo($b)` will transform, eg `foo * Probably needs search without replace mode * Needs a way to limit the scope to certain files. + +## Matching Brace + +**Issue:** https://github.com/microsoft/language-server-protocol/issues/999 + +**Server Capability:** `{ "matchingBrace": boolean }` + +This request is send 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 a nested brace structure, to allow paredit-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? -- cgit v1.2.3 From dec4ba80236e1be15f011fd6b2f7f0ecb151fd31 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 May 2020 17:01:40 +0200 Subject: Document some rust-analyzer specific protocol extensions --- docs/dev/lsp-extensions.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 9fa1c5fc2..55035cfae 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -217,3 +217,65 @@ Moreover, it would be cool if editors didn't need to implement even basic langua * Should we return a a nested brace structure, to allow paredit-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? + +## Analyzer Status + +**Method:** `rust-analyzer/analyzerStatus` + +**Request:** `null` + +**Response:** `string` + +Returns internal status message, mostly for debugging purposes. + +## Collect Garbage + +**Method:** `rust-analyzer/collectGarbage` + +**Request:** `null` + +**Response:** `null` + +Frees some caches. For internal use, and is mostly broken at the moment. + +## Syntax Tree + +**Method:** `rust-analyzer/syntaxTree` + +**Request:** + +```typescript +interface SyntaxTeeParams { + 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. + +## 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. -- cgit v1.2.3 From 76e170c3d0d0784c0e612c5849798c65a2034f29 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 May 2020 14:12:53 +0200 Subject: Less rust-analyzer specific onEnter --- docs/dev/lsp-extensions.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 55035cfae..e4b9fb2c2 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -138,6 +138,59 @@ fn main() { 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 + +**Issue:** https://github.com/microsoft/language-server-protocol/issues/1001 + +**Server Capability:** `{ "onEnter": boolean }` + +This request is send from client to server to handle Enter keypress. + +**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'etat 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 OT-style merging of edits from client and server. + A third option is to do a record-replay: client applies heuristic on enter immediatelly, 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) **Server Capability:** `{ "ssr": boolean }` -- cgit v1.2.3 From a30bdd9795770329e4562d8bfca60ebe2e52dea1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 May 2020 14:56:26 +0200 Subject: Cleanup lsp extensions on the client side --- docs/dev/lsp-extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index e4b9fb2c2..48147b173 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -318,7 +318,7 @@ Primarily for debugging, but very useful for all people working on rust-analyzer ```typescript interface ExpandMacroParams { textDocument: TextDocumentIdentifier, - position?: Position, + position: Position, } ``` -- cgit v1.2.3 From 0ebb25b29b0988be89f42091fd373ea58d7ff9fb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 May 2020 15:55:25 +0200 Subject: Document `parentModule` experimental LSP request --- docs/dev/lsp-extensions.md | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 48147b173..209f470eb 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -87,6 +87,40 @@ Invoking code action at this position will yield two code actions for importing * Is a fixed two-level structure enough? * Should we devise a general way to encode custom interaction protocols for GUI refactorings? +## Parent Module + +**Issue:** https://github.com/microsoft/language-server-protocol/issues/1002 + +**Server Capability:** `{ "parentModule": boolean }` + +This request is send 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 takeing. + 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 overriden function, the behavior with single "gotoSuper" request is surprising. + ## Join Lines **Issue:** https://github.com/microsoft/language-server-protocol/issues/992 @@ -108,11 +142,7 @@ interface JoinLinesParams { } ``` -**Response:** - -```typescript -TextEdit[] -``` +**Response:** `TextEdit[]` ### Example -- cgit v1.2.3 From bb415c1818fe75badbd70a87a4ae23923a3d3984 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 May 2020 12:20:47 +0200 Subject: Document inlay hints and runnables We want to change those, but let's document what we have in meantime --- docs/dev/lsp-extensions.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 209f470eb..c898f3e93 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -362,3 +362,66 @@ interface ExpandedMacro { ``` Expands macro call at a given position. + +## Inlay Hints + +**Method:** `rust-analyzer/inlayHints` + +This request is send from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types. +Generally, the client should re-query inlay hints after every modification. +Note that we plan to move this request to `experimental/inlayHints`, as it is not really Rust-specific, but the current API is not necessary the right one. +Upstream issue: https://github.com/microsoft/language-server-protocol/issues/956 + +**Request:** + +```typescript +interface InlayHintsParams { + textDocument: TextDocumentIdentifier, +} +``` + +**Response:** `InlayHint[]` + +```typescript +interface InlayHint { + kind: "TypeHint" | "ParameterHint" | "ChainingHints", + range: Range, + label: string, +} +``` + +## Runnables + +**Method:** `rust-analyzer/runnables` + +This request is send from client to server to get the list of things that can be run (tests, binaries, `cargo check -p`). +Note that we plan to move this request to `experimental/runnables`, as it is not really Rust-specific, but the current API is not necessary the right one. +Upstream issue: https://github.com/microsoft/language-server-protocol/issues/944 + +**Request:** + +```typescript +interface RunnablesParams { + textDocument: TextDocumentIdentifier; + /// If null, compute runnables for the whole file. + position?: Position; +} +``` + +**Response:** `Runnable[]` + +```typescript +interface Runnable { + /// The range this runnable is applicable for. + range: lc.Range; + /// The label to show in the UI. + label: string; + /// The following fields describe a process to spawn. + bin: string; + args: string[]; + /// Args for cargo after `--`. + extraArgs: string[]; + env: { [key: string]: string }; + cwd: string | null; +} +``` -- cgit v1.2.3 From bfdcf73b9b0297b916d1c982ca95a005ceec7e86 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 27 May 2020 14:04:57 +0300 Subject: typo --- docs/dev/lsp-extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index c898f3e93..68a5df27e 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -384,7 +384,7 @@ interface InlayHintsParams { ```typescript interface InlayHint { - kind: "TypeHint" | "ParameterHint" | "ChainingHints", + kind: "TypeHint" | "ParameterHint" | "ChainingHint", range: Range, label: string, } -- cgit v1.2.3 From 49f674480a54823c81390c15e37eddfdab5ea7ec Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 29 May 2020 23:41:04 +0200 Subject: Fix typo in docs/dev/lsp-extensions.md: automagiacally -> automagically --- docs/dev/lsp-extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 68a5df27e..dbc95be38 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -154,7 +154,7 @@ fn main() { } ``` -`experimental/joinLines` yields (curly braces are automagiacally removed) +`experimental/joinLines` yields (curly braces are automagically removed) ```rust fn main() { -- cgit v1.2.3 From d605ec9c321392d9c7ee4b440c560e1e405d92e6 Mon Sep 17 00:00:00 2001 From: veetaha Date: Sun, 31 May 2020 05:13:08 +0300 Subject: Change Runnable.bin -> Runnable.kind As per matklad, we now pass the responsibility for finding the binary to the frontend. Also, added caching for finding the binary path to reduce the amount of filesystem interactions. --- docs/dev/lsp-extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index dbc95be38..d06da355d 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -417,7 +417,7 @@ interface Runnable { /// The label to show in the UI. label: string; /// The following fields describe a process to spawn. - bin: string; + kind: "cargo" | "rustc" | "rustup"; args: string[]; /// Args for cargo after `--`. extraArgs: string[]; -- cgit v1.2.3 From d23814bf3dd3429b35690ba0f57e0b0bb0913d7d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 1 Jun 2020 17:29:24 +0200 Subject: Drop unused document --- docs/dev/lsp-features.md | 72 ------------------------------------------------ 1 file changed, 72 deletions(-) delete mode 100644 docs/dev/lsp-features.md (limited to 'docs/dev') diff --git a/docs/dev/lsp-features.md b/docs/dev/lsp-features.md deleted file mode 100644 index 00b0867d7..000000000 --- a/docs/dev/lsp-features.md +++ /dev/null @@ -1,72 +0,0 @@ -# Supported LSP features - -This list documents LSP features, supported by rust-analyzer. - -## General -- [x] [initialize](https://microsoft.github.io/language-server-protocol/specification#initialize) -- [x] [initialized](https://microsoft.github.io/language-server-protocol/specification#initialized) -- [x] [shutdown](https://microsoft.github.io/language-server-protocol/specification#shutdown) -- [ ] [exit](https://microsoft.github.io/language-server-protocol/specification#exit) -- [x] [$/cancelRequest](https://microsoft.github.io/language-server-protocol/specification#cancelRequest) - -## Workspace -- [ ] [workspace/workspaceFolders](https://microsoft.github.io/language-server-protocol/specification#workspace_workspaceFolders) -- [ ] [workspace/didChangeWorkspaceFolders](https://microsoft.github.io/language-server-protocol/specification#workspace_didChangeWorkspaceFolders) -- [x] [workspace/didChangeConfiguration](https://microsoft.github.io/language-server-protocol/specification#workspace_didChangeConfiguration) -- [ ] [workspace/configuration](https://microsoft.github.io/language-server-protocol/specification#workspace_configuration) -- [x] [workspace/didChangeWatchedFiles](https://microsoft.github.io/language-server-protocol/specification#workspace_didChangeWatchedFiles) -- [x] [workspace/symbol](https://microsoft.github.io/language-server-protocol/specification#workspace_symbol) -- [ ] [workspace/applyEdit](https://microsoft.github.io/language-server-protocol/specification#workspace_applyEdit) - -## Text Synchronization -- [x] [textDocument/didOpen](https://microsoft.github.io/language-server-protocol/specification#textDocument_didOpen) -- [x] [textDocument/didChange](https://microsoft.github.io/language-server-protocol/specification#textDocument_didChange) -- [ ] [textDocument/willSave](https://microsoft.github.io/language-server-protocol/specification#textDocument_willSave) -- [ ] [textDocument/willSaveWaitUntil](https://microsoft.github.io/language-server-protocol/specification#textDocument_willSaveWaitUntil) -- [x] [textDocument/didSave](https://microsoft.github.io/language-server-protocol/specification#textDocument_didSave) -- [x] [textDocument/didClose](https://microsoft.github.io/language-server-protocol/specification#textDocument_didClose) - -## Diagnostics -- [x] [textDocument/publishDiagnostics](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics) - -## Lanuguage Features -- [x] [textDocument/completion](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) - - open close: false - - change: Full - - will save: false - - will save wait until: false - - save: false -- [x] [completionItem/resolve](https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve) - - resolve provider: none - - trigger characters: `:`, `.` -- [x] [textDocument/hover](https://microsoft.github.io/language-server-protocol/specification#textDocument_hover) -- [x] [textDocument/signatureHelp](https://microsoft.github.io/language-server-protocol/specification#textDocument_signatureHelp) - - trigger characters: `(`, `,` -- [ ] [textDocument/declaration](https://microsoft.github.io/language-server-protocol/specification#textDocument_declaration) -- [x] [textDocument/definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) -- [x] [textDocument/typeDefinition](https://microsoft.github.io/language-server-protocol/specification#textDocument_typeDefinition) -- [x] [textDocument/implementation](https://microsoft.github.io/language-server-protocol/specification#textDocument_implementation) -- [x] [textDocument/references](https://microsoft.github.io/language-server-protocol/specification#textDocument_references) -- [x] [textDocument/documentHighlight](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight) -- [x] [textDocument/documentSymbol](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol) -- [x] [textDocument/codeAction](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeAction) -- [x] [textDocument/selectionRange](https://github.com/Microsoft/language-server-protocol/issues/613) - - rust-analyzer.syntaxTree - - rust-analyzer.matchingBrace - - rust-analyzer.parentModule - - rust-analyzer.joinLines - - rust-analyzer.run - - rust-analyzer.analyzerStatus -- [x] [textDocument/codeLens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens) -- [x] [codeLens/resolve](https://microsoft.github.io/language-server-protocol/specification#codeLens_resolve) -- [ ] [documentLink/resolve](https://microsoft.github.io/language-server-protocol/specification#documentLink_resolve) -- [ ] [textDocument/documentColor](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentColor) -- [ ] [textDocument/colorPresentation](https://microsoft.github.io/language-server-protocol/specification#textDocument_colorPresentation) -- [x] [textDocument/formatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting) -- [ ] [textDocument/rangeFormatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_rangeFormatting) -- [x] [textDocument/onTypeFormatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_onTypeFormatting) - - first trigger character: `=` - - more trigger character `.` -- [x] [textDocument/rename](https://microsoft.github.io/language-server-protocol/specification#textDocument_rename) -- [x] [textDocument/prepareRename](https://microsoft.github.io/language-server-protocol/specification#textDocument_prepareRename) -- [x] [textDocument/foldingRange](https://microsoft.github.io/language-server-protocol/specification#textDocument_foldingRange) -- cgit v1.2.3 From aaa288126bd27f7b4d3d87827d1b8d3adf01d584 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 1 Jun 2020 17:42:46 +0200 Subject: Document initilizationOptions used by rust-analyzer --- docs/dev/lsp-extensions.md | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index dbc95be38..6b2d385fc 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -7,6 +7,14 @@ All capabilities are enabled via `experimental` field of `ClientCapabilities` or 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. +## `initializationOptions` + +As `initializationOptions`, `rust-analyzer` expects `"rust-analyzer"` section of the configuration. +That is, `rust-analyzer` usually sends `"workspace/configuration"` request with `{ "items": ["rust-analyzer"] }` payload. +`initializationOptions` should contain the same data that would be in the first item of the result. +It's OK to not send anything, then all the settings would take their default values. +However, some settings can not be changed after startup at the moment. + ## Snippet `TextEdit` **Issue:** https://github.com/microsoft/language-server-protocol/issues/724 -- cgit v1.2.3 From 6370de444de0c4739d14000c0123b34c422a946a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 1 Jun 2020 17:51:15 +0200 Subject: Subscribe to protocol changes --- docs/dev/lsp-extensions.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 6b2d385fc..c57a93f12 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -7,6 +7,8 @@ All capabilities are enabled via `experimental` field of `ClientCapabilities` or 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-analyzer/rust-analyzer/issues/4604). + ## `initializationOptions` As `initializationOptions`, `rust-analyzer` expects `"rust-analyzer"` section of the configuration. -- cgit v1.2.3 From a83ab820a4633bac718ee0fd11f06d1b3142be6b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Jun 2020 17:34:18 +0200 Subject: Spec better runnables --- docs/dev/lsp-extensions.md | 80 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 36 deletions(-) (limited to 'docs/dev') diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index b7237ee90..647cf6107 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -311,6 +311,50 @@ Moreover, it would be cool if editors didn't need to implement even basic langua This is how `SelectionRange` request works. * Alternatively, should we perhaps flag certain `SelectionRange`s as being brace pairs? +## Runnables + +**Issue:** https://github.com/microsoft/language-server-protocol/issues/944 + +**Server Capability:** `{ "runnables": { "kinds": string[] } }` + +This request is send 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[]; + executableArgs: string[]; +} +``` + ## Analyzer Status **Method:** `rust-analyzer/analyzerStatus` @@ -399,39 +443,3 @@ interface InlayHint { label: string, } ``` - -## Runnables - -**Method:** `rust-analyzer/runnables` - -This request is send from client to server to get the list of things that can be run (tests, binaries, `cargo check -p`). -Note that we plan to move this request to `experimental/runnables`, as it is not really Rust-specific, but the current API is not necessary the right one. -Upstream issue: https://github.com/microsoft/language-server-protocol/issues/944 - -**Request:** - -```typescript -interface RunnablesParams { - textDocument: TextDocumentIdentifier; - /// If null, compute runnables for the whole file. - position?: Position; -} -``` - -**Response:** `Runnable[]` - -```typescript -interface Runnable { - /// The range this runnable is applicable for. - range: lc.Range; - /// The label to show in the UI. - label: string; - /// The following fields describe a process to spawn. - kind: "cargo" | "rustc" | "rustup"; - args: string[]; - /// Args for cargo after `--`. - extraArgs: string[]; - env: { [key: string]: string }; - cwd: string | null; -} -``` -- cgit v1.2.3 From 994006585be6850b250b21aac76a58f1324cad5d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Jun 2020 11:16:49 +0200 Subject: Start documenting review process --- docs/dev/README.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'docs/dev') diff --git a/docs/dev/README.md b/docs/dev/README.md index 65cc9fc12..1de5a2aab 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md @@ -30,7 +30,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0 * [good-first-issue](https://github.com/rust-analyzer/rust-analyzer/labels/good%20first%20issue) are good issues to get into the project. -* [E-mentor](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-mentor) +* [E-has-instructions](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-has-instructions) issues have links to the code in question and tests. * [E-easy](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy), [E-medium](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-medium), @@ -117,6 +117,109 @@ Additionally, I use `cargo run --release -p rust-analyzer -- analysis-stats path/to/some/rust/crate` to run a batch analysis. This is primarily useful for performance optimizations, or for bug minimization. +# Code Style & Review Process + +Our approach to "clean code" is two fold: + +* We generally don't block PRs on style changes. +* At the same time, all code in rust-analyzer is constantly refactored. + +It is explicitly OK for reviewer to flag only some nits in the PR, and than send a follow up cleanup PR for things which are easier to explain by example, cc-ing the original author. +Sending small cleanup PRs (like rename a single local variable) is encouraged. + +## Scale of Changes + +Everyone knows that it's better to send small & focused pull requests. +The problem is, sometimes you *have* to, eg, rewrite the whole compiler, and that just doesn't fit into a set of isolated PRs. + +The main thing too keep an eye on is the boundaries between various components. +There are three kinds of changes: + +1. Internals of a single component are changed. + Specifically, you don't change any `pub` items. + A good example here would be an addition of a new assist. + +2. API of a component is expanded. + Specifically, you add a new `pub` function which wasn't there before. + A good example here would be expansion of assist API, for example, to implement lazy assists or assists groups. + +3. A new dependency between components is introduced. + Specifically, you add a `pub use` reexport from another crate or you add a new line to `[dependencies]` section of `Cargo.toml`. + A good example here would be adding reference search capability to the assists crates. + +For the first group, the change is generally merged as long as: + +* it works for the happy case, +* it has tests, +* it doesn't panic for unhappy case. + +For the second group, the change would be subjected to quite a bit of scrutiny and iteration. +The new API needs to be right (or at least easy to change later). +The actual implementation doesn't matter that much. +It's very important to minimize the amount of changed lines of code for changes of the second kind. +Often, you start doing change of the first kind, only to realise that you need to elevate to a change of the second kind. +In this case, we'll probably ask you to split API changes into a separate PR. + +Changes of the third group should be pretty rare, so we don't specify any specific process for them. +That said, adding an innocent-looking `pub use` is a very simple way to break encapsulation, keep an eye on it! + +Note: if you enjoyed this abstract hand-waving about boundaries, you might appreciate +https://www.tedinski.com/2018/02/06/system-boundaries.html + +## Order of Imports + +We separate import groups with blank lines + +``` +mod x; +mod y; + +use std::{ ... } + +use crate_foo::{ ... } +use crate_bar::{ ... } + +use crate::{} + +use super::{} // but prefer `use crate::` +``` + +## Order of Items + +Optimize for the reader who sees the file for the first time, and wants to get the general idea about what's going on. +People read things from top to bottom, so place most important things first. + +Specifically, if all items except one are private, always put the non-private item on top. + +Put `struct`s and `enum`s first, functions and impls last. + +Do + +``` +// Good +struct Foo { + bars: Vec +} + +struct Bar; +``` + +rather than + +``` +// Not as good +struct Bar; + +struct Foo { + bars: Vec +} +``` + +## Documentation + +For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. +If the line is too long, you want to split the sentence in two :-) + # Logging Logging is done by both rust-analyzer and VS Code, so it might be tricky to -- cgit v1.2.3