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 --- crates/rust-analyzer/src/lsp_ext.rs | 12 +++---- crates/rust-analyzer/src/main_loop.rs | 4 +-- crates/rust-analyzer/src/main_loop/handlers.rs | 8 ++--- docs/dev/lsp-extensions.md | 47 +++++++++++++++++++++++++- editors/code/src/commands/matching_brace.ts | 4 +-- editors/code/src/rust-analyzer-api.ts | 7 ++-- 6 files changed, 63 insertions(+), 19 deletions(-) diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index c25d90a50..b8b9e65ed 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -60,19 +60,19 @@ pub struct ExpandMacroParams { pub position: Option, } -pub enum FindMatchingBrace {} +pub enum MatchingBrace {} -impl Request for FindMatchingBrace { - type Params = FindMatchingBraceParams; +impl Request for MatchingBrace { + type Params = MatchingBraceParams; type Result = Vec; - const METHOD: &'static str = "rust-analyzer/findMatchingBrace"; + const METHOD: &'static str = "experimental/matchingBrace"; } #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] -pub struct FindMatchingBraceParams { +pub struct MatchingBraceParams { pub text_document: TextDocumentIdentifier, - pub offsets: Vec, + pub positions: Vec, } pub enum ParentModule {} diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 87795fffb..e28a32c26 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -509,8 +509,8 @@ fn on_request( .on_sync::(|s, p| { handlers::handle_selection_range(s.snapshot(), p) })? - .on_sync::(|s, p| { - handlers::handle_find_matching_brace(s.snapshot(), p) + .on_sync::(|s, p| { + handlers::handle_matching_brace(s.snapshot(), p) })? .on::(handlers::handle_analyzer_status)? .on::(handlers::handle_syntax_tree)? diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 2aaff3ea4..d73107968 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -126,15 +126,15 @@ pub fn handle_selection_range( Ok(Some(res?)) } -pub fn handle_find_matching_brace( +pub fn handle_matching_brace( world: WorldSnapshot, - params: lsp_ext::FindMatchingBraceParams, + params: lsp_ext::MatchingBraceParams, ) -> Result> { - let _p = profile("handle_find_matching_brace"); + let _p = profile("handle_matching_brace"); let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; let line_index = world.analysis().file_line_index(file_id)?; let res = params - .offsets + .positions .into_iter() .map(|position| { let offset = from_proto::offset(&line_index, position); 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? diff --git a/editors/code/src/commands/matching_brace.ts b/editors/code/src/commands/matching_brace.ts index a60776e2d..9c418b887 100644 --- a/editors/code/src/commands/matching_brace.ts +++ b/editors/code/src/commands/matching_brace.ts @@ -9,9 +9,9 @@ export function matchingBrace(ctx: Ctx): Cmd { const client = ctx.client; if (!editor || !client) return; - const response = await client.sendRequest(ra.findMatchingBrace, { + const response = await client.sendRequest(ra.matchingBrace, { textDocument: { uri: editor.document.uri.toString() }, - offsets: editor.selections.map(s => + positions: editor.selections.map(s => client.code2ProtocolConverter.asPosition(s.active), ), }); diff --git a/editors/code/src/rust-analyzer-api.ts b/editors/code/src/rust-analyzer-api.ts index 73f36432f..900c5cd5b 100644 --- a/editors/code/src/rust-analyzer-api.ts +++ b/editors/code/src/rust-analyzer-api.ts @@ -40,12 +40,11 @@ export interface ExpandedMacro { export const expandMacro = request>("expandMacro"); -export interface FindMatchingBraceParams { +export interface MatchingBraceParams { textDocument: lc.TextDocumentIdentifier; - offsets: Vec; + positions: lc.Position[]; } -export const findMatchingBrace = request>("findMatchingBrace"); - +export const matchingBrace = new lc.RequestType('experimental/matchingBrace'); export interface PublishDecorationsParams { uri: string; -- cgit v1.2.3