about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-05-22 00:28:49 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-05-22 00:28:49 +0200
commit5ef4ebff2017d7bdfa03f0eccb9960a86c9b94ca (patch)
tree6458549d833ba628fd86d050cb5dd1238c590fc3
parent59732df8d40dfadc6dcf5951265416576399712a (diff)
downloadrust-5ef4ebff2017d7bdfa03f0eccb9960a86c9b94ca.tar.gz
rust-5ef4ebff2017d7bdfa03f0eccb9960a86c9b94ca.zip
Use WorkspaceEdit for ssr
-rw-r--r--crates/rust-analyzer/src/caps.rs1
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs4
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs4
-rw-r--r--docs/dev/lsp-extensions.md35
-rw-r--r--editors/code/src/commands/ssr.ts6
-rw-r--r--editors/code/src/rust-analyzer-api.ts2
6 files changed, 43 insertions, 9 deletions
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 4c417c27045..13af75469d6 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 1bb1b02ab49..0fd60caf4d2 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 12196471880..25e660bd570 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<lsp_ext::SourceChange> {
+) -> Result<lsp_types::WorkspaceEdit> {
     let _p = profile("handle_ssr");
     let source_change =
         world.analysis().structural_search_replace(&params.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<DiagnosticTask> {
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 0e3a0af1cbb..7c45aef4c1a 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 4ef8cdf04f7..5d40a64d28e 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 8ed56c173ee..73f36432f64 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<SsrParams, SourceChange>("ssr");
+export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, unknown>('experimental/ssr');
 
 
 export const publishDecorations = notification<PublishDecorationsParams>("publishDecorations");