From dc217bdf90d555eaa1780041fc3a14e64173994d Mon Sep 17 00:00:00 2001 From: vsrs Date: Sun, 17 May 2020 19:51:44 +0300 Subject: CodeLens configuration options. --- editors/code/src/config.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 1652827c3..93d9aa160 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -16,6 +16,9 @@ export class Config { "files", "highlighting", "updates.channel", + "lens.run", + "lens.debug", + "lens.implementations", ] .map(opt => `${this.rootSection}.${opt}`); @@ -119,4 +122,12 @@ export class Config { sourceFileMap: sourceFileMap }; } + + get lens() { + return { + run: this.get("lens.run"), + debug: this.get("lens.debug"), + implementations: this.get("lens.implementations"), + }; + } } -- cgit v1.2.3 From dec2f3fa657a2700f9db1962891e7be71c299543 Mon Sep 17 00:00:00 2001 From: vsrs Date: Sun, 17 May 2020 20:29:59 +0300 Subject: Runnable QuickPick with debuggees only --- editors/code/src/commands/runnables.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index b1d93fc34..a408021e7 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -7,7 +7,7 @@ import { startDebugSession, getDebugConfiguration } from '../debug'; const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }]; -async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, showButtons: boolean = true): Promise { +async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise { const editor = ctx.activeRustEditor; const client = ctx.client; if (!editor || !client) return; @@ -33,9 +33,20 @@ async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, showBu ) { continue; } + + if (debuggeeOnly && (r.label.startsWith('doctest') || r.label.startsWith('cargo'))) { + continue; + } items.push(new RunnableQuickPick(r)); } + if( items.length === 0 ) { + // it is the debug case, run always has at least 'cargo check ...' + // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables + vscode.window.showErrorMessage("There's no debug target!"); + return; + } + return await new Promise((resolve) => { const disposables: vscode.Disposable[] = []; const close = (result?: RunnableQuickPick) => { @@ -107,7 +118,7 @@ export function debug(ctx: Ctx): Cmd { let prevDebuggee: RunnableQuickPick | undefined; return async () => { - const item = await selectRunnable(ctx, prevDebuggee); + const item = await selectRunnable(ctx, prevDebuggee, true); if (!item) return; item.detail = 'restart'; @@ -147,7 +158,7 @@ async function makeDebugConfig(ctx: Ctx, item: RunnableQuickPick): Promise export function newDebugConfig(ctx: Ctx): Cmd { return async () => { - const item = await selectRunnable(ctx, undefined, false); + const item = await selectRunnable(ctx, undefined, true, false); if (!item) return; await makeDebugConfig(ctx, item); -- cgit v1.2.3 From 3d445256fe56f4a7ead64514fb57b79079973d84 Mon Sep 17 00:00:00 2001 From: vsrs Date: Sun, 17 May 2020 20:38:50 +0300 Subject: code formatting --- editors/code/src/commands/runnables.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index a408021e7..0bd30fb07 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -40,7 +40,7 @@ async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debugg items.push(new RunnableQuickPick(r)); } - if( items.length === 0 ) { + if (items.length === 0) { // it is the debug case, run always has at least 'cargo check ...' // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables vscode.window.showErrorMessage("There's no debug target!"); -- cgit v1.2.3 From 78817a319476d8af40c4f78e8c47dc958781f88f Mon Sep 17 00:00:00 2001 From: vsrs Date: Mon, 18 May 2020 10:27:00 +0300 Subject: Add "rust-analyzer.lens.enable" --- editors/code/src/config.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 93d9aa160..ee294fbe3 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -16,6 +16,7 @@ export class Config { "files", "highlighting", "updates.channel", + "lens.enable", "lens.run", "lens.debug", "lens.implementations", @@ -125,6 +126,7 @@ export class Config { get lens() { return { + enable: this.get("lens.enable"), run: this.get("lens.run"), debug: this.get("lens.debug"), implementations: this.get("lens.implementations"), -- cgit v1.2.3 From a752853350639a915178ea900a51f3c45443795e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 17 May 2020 21:24:33 +0200 Subject: Add snippetTextEdit protocol extension --- editors/code/src/client.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index cffdcf11a..2067738ea 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -35,7 +35,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient } as any }; - const res = new lc.LanguageClient( + const client = new lc.LanguageClient( 'rust-analyzer', 'Rust Analyzer Language Server', serverOptions, @@ -47,8 +47,19 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient // since they are available on stable. // Note that while these features are stable in vscode their LSP protocol // implementations are still in the "proposed" category for 3.16. - res.registerFeature(new CallHierarchyFeature(res)); - res.registerFeature(new SemanticTokensFeature(res)); + client.registerFeature(new CallHierarchyFeature(client)); + client.registerFeature(new SemanticTokensFeature(client)); + client.registerFeature(new SnippetTextEditFeature()); - return res; + return client; +} + +class SnippetTextEditFeature implements lc.StaticFeature { + fillClientCapabilities(capabilities: lc.ClientCapabilities): void { + const caps: any = capabilities.experimental ?? {}; + caps.snippetTextEdit = true; + capabilities.experimental = caps + } + initialize(_capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined): void { + } } -- cgit v1.2.3 From 3dd68c1ba3e72a0959bcdaa46e730a7ae4d9ed4c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 18 May 2020 01:53:55 +0200 Subject: Implement client-side of SnippetTextEdit --- editors/code/src/client.ts | 48 ++++++++++++++++++++++++++++++++++++-- editors/code/src/commands/index.ts | 34 +++++++++++++++++++++++++++ editors/code/src/main.ts | 1 + 3 files changed, 81 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 2067738ea..fac1a0be3 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -31,7 +31,39 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient const res = await next(document, token); if (res === undefined) throw new Error('busy'); return res; + }, + async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) { + const params: lc.CodeActionParams = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + range: client.code2ProtocolConverter.asRange(range), + context: client.code2ProtocolConverter.asCodeActionContext(context) + }; + return client.sendRequest(lc.CodeActionRequest.type, params, token).then((values) => { + if (values === null) return undefined; + const result: (vscode.CodeAction | vscode.Command)[] = []; + for (const item of values) { + if (lc.CodeAction.is(item)) { + const action = client.protocol2CodeConverter.asCodeAction(item); + if (isSnippetEdit(item)) { + action.command = { + command: "rust-analyzer.applySnippetWorkspaceEdit", + title: "", + arguments: [action.edit], + }; + action.edit = undefined; + } + result.push(action); + } else { + const command = client.protocol2CodeConverter.asCommand(item); + result.push(command); + } + } + return result; + }, + (_error) => undefined + ); } + } as any }; @@ -42,7 +74,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient clientOptions, ); - // To turn on all proposed features use: res.registerProposedFeatures(); + // To turn on all proposed features use: client.registerProposedFeatures(); // Here we want to enable CallHierarchyFeature and SemanticTokensFeature // since they are available on stable. // Note that while these features are stable in vscode their LSP protocol @@ -58,8 +90,20 @@ class SnippetTextEditFeature implements lc.StaticFeature { fillClientCapabilities(capabilities: lc.ClientCapabilities): void { const caps: any = capabilities.experimental ?? {}; caps.snippetTextEdit = true; - capabilities.experimental = caps + capabilities.experimental = caps; } initialize(_capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined): void { } } + +function isSnippetEdit(action: lc.CodeAction): boolean { + const documentChanges = action.edit?.documentChanges ?? []; + for (const edit of documentChanges) { + if (lc.TextDocumentEdit.is(edit)) { + if (edit.edits.some((indel) => (indel as any).insertTextFormat === lc.InsertTextFormat.Snippet)) { + return true; + } + } + } + return false; +} diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index bdb7fc3b0..770d11bd3 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -4,6 +4,7 @@ import * as ra from '../rust-analyzer-api'; import { Ctx, Cmd } from '../ctx'; import * as sourceChange from '../source_change'; +import { assert } from '../util'; export * from './analyzer_status'; export * from './matching_brace'; @@ -51,3 +52,36 @@ export function selectAndApplySourceChange(ctx: Ctx): Cmd { } }; } + +export function applySnippetWorkspaceEdit(_ctx: Ctx): Cmd { + return async (edit: vscode.WorkspaceEdit) => { + assert(edit.entries().length === 1, `bad ws edit: ${JSON.stringify(edit)}`); + const [uri, edits] = edit.entries()[0]; + + const editor = vscode.window.visibleTextEditors.find((it) => it.document.uri.toString() === uri.toString()); + if (!editor) return; + + let editWithSnippet: vscode.TextEdit | undefined = undefined; + let lineDelta = 0; + await editor.edit((builder) => { + for (const indel of edits) { + if (indel.newText.indexOf('$0') !== -1) { + editWithSnippet = indel; + } else { + if (!editWithSnippet) { + lineDelta = (indel.newText.match(/\n/g) || []).length - (indel.range.end.line - indel.range.start.line); + } + builder.replace(indel.range, indel.newText); + } + } + }); + if (editWithSnippet) { + const snip = editWithSnippet as vscode.TextEdit; + const range = snip.range.with( + snip.range.start.with(snip.range.start.line + lineDelta), + snip.range.end.with(snip.range.end.line + lineDelta), + ); + await editor.insertSnippet(new vscode.SnippetString(snip.newText), range); + } + }; +} diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index c015460b8..ac3bb365e 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -91,6 +91,7 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('debugSingle', commands.debugSingle); ctx.registerCommand('showReferences', commands.showReferences); ctx.registerCommand('applySourceChange', commands.applySourceChange); + ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEdit); ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); ctx.pushCleanup(activateTaskProvider(workspaceFolder)); -- cgit v1.2.3 From 39ec581bf6e01cf2d7f33aacbe8879abf7ea3199 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 00:49:08 +0200 Subject: Fix client-side snippets --- editors/code/src/commands/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 770d11bd3..0937b495c 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -65,7 +65,8 @@ export function applySnippetWorkspaceEdit(_ctx: Ctx): Cmd { let lineDelta = 0; await editor.edit((builder) => { for (const indel of edits) { - if (indel.newText.indexOf('$0') !== -1) { + const isSnippet = indel.newText.indexOf('$0') !== -1 || indel.newText.indexOf('${') !== -1; + if (isSnippet) { editWithSnippet = indel; } else { if (!editWithSnippet) { -- cgit v1.2.3 From d264d7b9f264c31fe2b1ea7e623611a816979789 Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 20 May 2020 09:42:00 +0300 Subject: Debug lens fix for a binary. --- editors/code/src/cargo.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index 28c7de992..6a41873d0 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -51,10 +51,14 @@ export class Cargo { // arguments for a runnable from the quick pick should be updated. // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_code_lens - if (cargoArgs[0] === "run") { - cargoArgs[0] = "build"; - } else if (cargoArgs.indexOf("--no-run") === -1) { - cargoArgs.push("--no-run"); + switch (cargoArgs[0]) { + case "run": cargoArgs[0] = "build"; break; + case "test": { + if (cargoArgs.indexOf("--no-run") === -1) { + cargoArgs.push("--no-run"); + } + break; + } } let artifacts = await this.artifactsFromArgs(cargoArgs); -- cgit v1.2.3