From 5ef4ebff2017d7bdfa03f0eccb9960a86c9b94ca Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 22 May 2020 00:28:49 +0200 Subject: Use WorkspaceEdit for ssr --- crates/rust-analyzer/src/caps.rs | 1 + crates/rust-analyzer/src/lsp_ext.rs | 4 +-- crates/rust-analyzer/src/main_loop/handlers.rs | 4 +-- docs/dev/lsp-extensions.md | 35 ++++++++++++++++++++++++++ editors/code/src/commands/ssr.ts | 6 ++--- editors/code/src/rust-analyzer-api.ts | 2 +- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index 4c417c270..13af75469 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs @@ -94,6 +94,7 @@ pub fn server_capabilities() -> ServerCapabilities { ), experimental: Some(json!({ "joinLines": true, + "ssr": true, })), } } diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 1bb1b02ab..0fd60caf4 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -173,8 +173,8 @@ pub enum Ssr {} impl Request for Ssr { type Params = SsrParams; - type Result = SourceChange; - const METHOD: &'static str = "rust-analyzer/ssr"; + type Result = lsp_types::WorkspaceEdit; + const METHOD: &'static str = "experimental/ssr"; } #[derive(Debug, Deserialize, Serialize)] diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 121964718..25e660bd5 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -986,11 +986,11 @@ pub fn handle_document_highlight( pub fn handle_ssr( world: WorldSnapshot, params: lsp_ext::SsrParams, -) -> Result { +) -> Result { let _p = profile("handle_ssr"); let source_change = world.analysis().structural_search_replace(¶ms.query, params.parse_only)??; - to_proto::source_change(&world, source_change) + to_proto::workspace_edit(&world, source_change) } pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result { diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 0e3a0af1c..7c45aef4c 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -84,3 +84,38 @@ fn main() { * 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. + +## Structural Search Replace (SSR) + +**Server Capability:** `{ "ssr": boolean }` + +This request is send 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: bool, +} +``` + +**Response:** + +```typescript +WorkspaceEdit +``` + +### Example + +SSR with query `foo($a:expr, $b:expr) ==>> ($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. diff --git a/editors/code/src/commands/ssr.ts b/editors/code/src/commands/ssr.ts index 4ef8cdf04..5d40a64d2 100644 --- a/editors/code/src/commands/ssr.ts +++ b/editors/code/src/commands/ssr.ts @@ -2,7 +2,6 @@ import * as vscode from 'vscode'; import * as ra from "../rust-analyzer-api"; import { Ctx, Cmd } from '../ctx'; -import { applySourceChange } from '../source_change'; export function ssr(ctx: Ctx): Cmd { return async () => { @@ -22,11 +21,10 @@ export function ssr(ctx: Ctx): Cmd { } }; const request = await vscode.window.showInputBox(options); - if (!request) return; - const change = await client.sendRequest(ra.ssr, { query: request, parseOnly: false }); + const edit = await client.sendRequest(ra.ssr, { query: request, parseOnly: false }); - await applySourceChange(ctx, change); + await vscode.workspace.applyEdit(client.protocol2CodeConverter.asWorkspaceEdit(edit)); }; } diff --git a/editors/code/src/rust-analyzer-api.ts b/editors/code/src/rust-analyzer-api.ts index 8ed56c173..73f36432f 100644 --- a/editors/code/src/rust-analyzer-api.ts +++ b/editors/code/src/rust-analyzer-api.ts @@ -112,7 +112,7 @@ export interface SsrParams { query: string; parseOnly: boolean; } -export const ssr = request("ssr"); +export const ssr = new lc.RequestType('experimental/ssr'); export const publishDecorations = notification("publishDecorations"); -- cgit v1.2.3