From 03c5a6690d943e48ac5b5464c2ac2fd054ea6251 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 27 Jun 2020 17:53:50 +0200 Subject: Add light-weight snapshot testing library with editor integration --- editors/code/src/lsp_ext.ts | 1 + editors/code/src/run.ts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index e16ea799c..fdb99956b 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -60,6 +60,7 @@ export interface Runnable { workspaceRoot?: string; cargoArgs: string[]; executableArgs: string[]; + expectTest?: boolean; }; } export const runnables = new lc.RequestType("experimental/runnables"); diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts index 766b05112..e1430e31f 100644 --- a/editors/code/src/run.ts +++ b/editors/code/src/run.ts @@ -108,12 +108,16 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise if (runnable.args.executableArgs.length > 0) { args.push('--', ...runnable.args.executableArgs); } + const env: { [key: string]: string } = { "RUST_BACKTRACE": "short" }; + if (runnable.args.expectTest) { + env["UPDATE_EXPECT"] = "1"; + } const definition: tasks.CargoTaskDefinition = { type: tasks.TASK_TYPE, command: args[0], // run, test, etc... args: args.slice(1), cwd: runnable.args.workspaceRoot, - env: Object.assign({}, process.env as { [key: string]: string }, { "RUST_BACKTRACE": "short" }), + env: Object.assign({}, process.env as { [key: string]: string }, env), }; const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate() -- cgit v1.2.3 From c9f878962a7c9d1c33d5834a1dce2106c9286699 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 1 Jul 2020 14:57:59 +0200 Subject: Add reload workspace command --- editors/code/src/commands.ts | 4 ++-- editors/code/src/lsp_ext.ts | 2 +- editors/code/src/main.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 0e78f5101..19a9c2a0d 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -330,8 +330,8 @@ export function expandMacro(ctx: Ctx): Cmd { }; } -export function collectGarbage(ctx: Ctx): Cmd { - return async () => ctx.client.sendRequest(ra.collectGarbage, null); +export function reloadWorkspace(ctx: Ctx): Cmd { + return async () => ctx.client.sendRequest(ra.reloadWorkspace, null); } export function showReferences(ctx: Ctx): Cmd { diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index fdb99956b..981b6f40e 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -6,7 +6,7 @@ import * as lc from "vscode-languageclient"; export const analyzerStatus = new lc.RequestType("rust-analyzer/analyzerStatus"); -export const collectGarbage = new lc.RequestType("rust-analyzer/collectGarbage"); +export const reloadWorkspace = new lc.RequestType("rust-analyzer/reloadWorkspace"); export interface SyntaxTreeParams { textDocument: lc.TextDocumentIdentifier; diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 5ceab8b44..2982b9cbf 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -88,7 +88,7 @@ export async function activate(context: vscode.ExtensionContext) { }); ctx.registerCommand('analyzerStatus', commands.analyzerStatus); - ctx.registerCommand('collectGarbage', commands.collectGarbage); + ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace); ctx.registerCommand('matchingBrace', commands.matchingBrace); ctx.registerCommand('joinLines', commands.joinLines); ctx.registerCommand('parentModule', commands.parentModule); -- cgit v1.2.3 From 69b6f6def525d33a60a3a992960d1085403d3b60 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Thu, 2 Jul 2020 04:56:50 +0300 Subject: Always install required nightly extension if current one is not nightly --- editors/code/src/main.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 5ceab8b44..1ad75a03c 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -152,13 +152,17 @@ async function bootstrapExtension(config: Config, state: PersistentState): Promi return; }; - const lastCheck = state.lastCheck; const now = Date.now(); + if (config.package.releaseTag === NIGHTLY_TAG) { + // Check if we should poll github api for the new nightly version + // if we haven't done it during the past hour + const lastCheck = state.lastCheck; - const anHour = 60 * 60 * 1000; - const shouldDownloadNightly = state.releaseId === undefined || (now - (lastCheck ?? 0)) > anHour; + const anHour = 60 * 60 * 1000; + const shouldCheckForNewNightly = state.releaseId === undefined || (now - (lastCheck ?? 0)) > anHour; - if (!shouldDownloadNightly) return; + if (!shouldCheckForNewNightly) return; + } const release = await fetchRelease("nightly").catch((e) => { log.error(e); -- cgit v1.2.3 From 6a6ce616aa8da460a145a8d535357adef9f51678 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Thu, 2 Jul 2020 05:19:02 +0300 Subject: Force showing extension activation error pop-up notification --- editors/code/src/main.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 5ceab8b44..ed26c887b 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -19,6 +19,16 @@ let ctx: Ctx | undefined; const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; export async function activate(context: vscode.ExtensionContext) { + // For some reason vscode not always shows pop-up error notifications + // when an extension fails to activate, so we do it explicitly by ourselves. + // FIXME: remove this bit of code once vscode fixes this issue: https://github.com/microsoft/vscode/issues/101242 + await tryActivate(context).catch(err => { + void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`); + throw err; + }); +} + +async function tryActivate(context: vscode.ExtensionContext) { // Register a "dumb" onEnter command for the case where server fails to // start. // @@ -58,9 +68,7 @@ export async function activate(context: vscode.ExtensionContext) { const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (workspaceFolder === undefined) { - const err = "Cannot activate rust-analyzer when no folder is opened"; - void vscode.window.showErrorMessage(err); - throw new Error(err); + throw new Error("no folder is opened"); } // Note: we try to start the server before we activate type hints so that it -- cgit v1.2.3 From 3ef76760761d17cef4ea4e8462d9ee2ca8395467 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 2 Jul 2020 12:37:04 +0200 Subject: Implement StatusBar --- editors/code/src/client.ts | 1 + editors/code/src/ctx.ts | 43 ++++++++++++++++++++++++++++++++++++++++++- editors/code/src/lsp_ext.ts | 3 +++ 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 65ad573d8..3e5915c28 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -161,6 +161,7 @@ class ExperimentalFeatures implements lc.StaticFeature { caps.codeActionGroup = true; caps.resolveCodeAction = true; caps.hoverActions = true; + caps.statusNotification = true; capabilities.experimental = caps; } initialize(_capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined): void { diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 41df11991..6e767babf 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -1,9 +1,11 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; +import * as ra from './lsp_ext'; import { Config } from './config'; import { createClient } from './client'; import { isRustEditor, RustEditor } from './util'; +import { Status } from './lsp_ext'; export class Ctx { private constructor( @@ -11,6 +13,7 @@ export class Ctx { private readonly extCtx: vscode.ExtensionContext, readonly client: lc.LanguageClient, readonly serverPath: string, + readonly statusBar: vscode.StatusBarItem, ) { } @@ -22,9 +25,18 @@ export class Ctx { cwd: string, ): Promise { const client = createClient(serverPath, cwd); - const res = new Ctx(config, extCtx, client, serverPath); + + const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); + extCtx.subscriptions.push(statusBar); + statusBar.text = "rust-analyzer"; + statusBar.tooltip = "ready"; + statusBar.show(); + + const res = new Ctx(config, extCtx, client, serverPath, statusBar); + res.pushCleanup(client.start()); await client.onReady(); + client.onNotification(ra.status, (status) => res.setStatus(status)); return res; } @@ -54,6 +66,35 @@ export class Ctx { return this.extCtx.subscriptions; } + setStatus(status: Status) { + switch (status) { + case "loading": + this.statusBar.text = "$(sync~spin) rust-analyzer"; + this.statusBar.tooltip = "Loading the project"; + this.statusBar.command = undefined; + this.statusBar.color = undefined; + break; + case "ready": + this.statusBar.text = "rust-analyzer"; + this.statusBar.tooltip = "Ready"; + this.statusBar.command = undefined; + this.statusBar.color = undefined; + break; + case "invalid": + this.statusBar.text = "$(error) rust-analyzer"; + this.statusBar.tooltip = "Failed to load the project"; + this.statusBar.command = undefined; + this.statusBar.color = new vscode.ThemeColor("notificationsErrorIcon.foreground"); + break; + case "needsReload": + this.statusBar.text = "$(warning) rust-analyzer"; + this.statusBar.tooltip = "Click to reload"; + this.statusBar.command = "rust-analyzer.reloadWorkspace"; + this.statusBar.color = new vscode.ThemeColor("notificationsWarningIcon.foreground"); + break; + } + } + pushCleanup(d: Disposable) { this.extCtx.subscriptions.push(d); } diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 981b6f40e..bf4703239 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -6,6 +6,9 @@ import * as lc from "vscode-languageclient"; export const analyzerStatus = new lc.RequestType("rust-analyzer/analyzerStatus"); +export type Status = "loading" | "ready" | "invalid" | "needsReload"; +export const status = new lc.NotificationType("rust-analyzer/status"); + export const reloadWorkspace = new lc.RequestType("rust-analyzer/reloadWorkspace"); export interface SyntaxTreeParams { -- cgit v1.2.3 From 5b9257561ff3bdf23ebcf3369f84283fb6c589a9 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 28 Jun 2020 19:59:39 -0400 Subject: Pass CodeActionKind through our middleware to populate menus --- editors/code/src/client.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 3e5915c28..41ffac7b3 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -66,7 +66,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient return Promise.resolve(null); }); }, - // Using custom handling of CodeActions where each code action is resloved lazily + // Using custom handling of CodeActions where each code action is resolved lazily // That's why we are not waiting for any command or edits async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) { const params: lc.CodeActionParams = { @@ -87,7 +87,8 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient continue; } assert(isCodeActionWithoutEditsAndCommands(item), "We don't expect edits or commands here"); - const action = new vscode.CodeAction(item.title); + const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind); + const action = new vscode.CodeAction(item.title, kind); const group = (item as any).group; const id = (item as any).id; const resolveParams: ra.ResolveCodeActionParams = { @@ -116,6 +117,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient result[index] = items[0]; } else { const action = new vscode.CodeAction(group); + action.kind = items[0].kind; action.command = { command: "rust-analyzer.applyActionGroup", title: "", -- cgit v1.2.3 From 7b79d24ad5b251c0806a07aa7769e824f3c37fec Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 2 Jul 2020 19:47:40 +0300 Subject: Add runnable env support. --- editors/code/src/config.ts | 6 ++++++ editors/code/src/debug.ts | 16 ++++++++++------ editors/code/src/run.ts | 29 ++++++++++++++++++++++++----- 3 files changed, 40 insertions(+), 11 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index fc95a7de6..a317aabcb 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -5,6 +5,8 @@ export type UpdatesChannel = "stable" | "nightly"; export const NIGHTLY_TAG = "nightly"; +export type RunnableEnvCfg = Record | [{ mask?: string, env: Record; }] + export class Config { readonly extensionId = "matklad.rust-analyzer"; @@ -114,6 +116,10 @@ export class Config { return this.get("cargoRunner"); } + get runnableEnv() { + return this.get("runnableEnv"); + } + get debug() { // "/rustc/" used by suggestions only. const { ["/rustc/"]: _, ...sourceFileMap } = this.get>("debug.sourceFileMap"); diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts index 61c12dbe0..525d26923 100644 --- a/editors/code/src/debug.ts +++ b/editors/code/src/debug.ts @@ -5,9 +5,10 @@ import * as ra from './lsp_ext'; import { Cargo } from './toolchain'; import { Ctx } from "./ctx"; +import { prepareEnv } from "./run"; const debugOutput = vscode.window.createOutputChannel("Debug"); -type DebugConfigProvider = (config: ra.Runnable, executable: string, sourceFileMap?: Record) => vscode.DebugConfiguration; +type DebugConfigProvider = (config: ra.Runnable, executable: string, env: Record, sourceFileMap?: Record) => vscode.DebugConfiguration; export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise { const scope = ctx.activeRustEditor?.document.uri; @@ -92,7 +93,8 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise { return executable; } -function getLldbDebugConfig(runnable: ra.Runnable, executable: string, sourceFileMap?: Record): vscode.DebugConfiguration { +function getLldbDebugConfig(runnable: ra.Runnable, executable: string, env: Record, sourceFileMap?: Record): vscode.DebugConfiguration { return { type: "lldb", request: "launch", @@ -130,11 +132,12 @@ function getLldbDebugConfig(runnable: ra.Runnable, executable: string, sourceFil args: runnable.args.executableArgs, cwd: runnable.args.workspaceRoot, sourceMap: sourceFileMap, - sourceLanguages: ["rust"] + sourceLanguages: ["rust"], + env }; } -function getCppvsDebugConfig(runnable: ra.Runnable, executable: string, sourceFileMap?: Record): vscode.DebugConfiguration { +function getCppvsDebugConfig(runnable: ra.Runnable, executable: string, env: Record, sourceFileMap?: Record): vscode.DebugConfiguration { return { type: (os.platform() === "win32") ? "cppvsdbg" : "cppdbg", request: "launch", @@ -142,6 +145,7 @@ function getCppvsDebugConfig(runnable: ra.Runnable, executable: string, sourceFi program: executable, args: runnable.args.executableArgs, cwd: runnable.args.workspaceRoot, - sourceFileMap: sourceFileMap, + sourceFileMap, + env, }; } diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts index e1430e31f..d7c7c489c 100644 --- a/editors/code/src/run.ts +++ b/editors/code/src/run.ts @@ -96,6 +96,28 @@ export class RunnableQuickPick implements vscode.QuickPickItem { } } +export function prepareEnv(runnable: ra.Runnable, config: Config): Record { + const env: Record = { "RUST_BACKTRACE": "short" }; + + if (runnable.args.expectTest) { + env["UPDATE_EXPECT"] = "1"; + } + + if (config.runnableEnv) { + if (Array.isArray(config.runnableEnv)) { + for (const it of config.runnableEnv) { + if (!it.mask || new RegExp(it.mask).test(runnable.label)) { + Object.assign(env, it.env); + } + } + } else { + Object.assign(env, config.runnableEnv as Record); + } + } + + return env; +} + export async function createTask(runnable: ra.Runnable, config: Config): Promise { if (runnable.kind !== "cargo") { // rust-analyzer supports only one kind, "cargo" @@ -108,16 +130,13 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise if (runnable.args.executableArgs.length > 0) { args.push('--', ...runnable.args.executableArgs); } - const env: { [key: string]: string } = { "RUST_BACKTRACE": "short" }; - if (runnable.args.expectTest) { - env["UPDATE_EXPECT"] = "1"; - } + const definition: tasks.CargoTaskDefinition = { type: tasks.TASK_TYPE, command: args[0], // run, test, etc... args: args.slice(1), cwd: runnable.args.workspaceRoot, - env: Object.assign({}, process.env as { [key: string]: string }, env), + env: prepareEnv(runnable, config), }; const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate() -- cgit v1.2.3 From 271abb7bc43f11c9b9e9c1353b162d9d267b1d21 Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 2 Jul 2020 21:33:26 +0300 Subject: Add tests --- editors/code/src/config.ts | 4 ++-- editors/code/src/debug.ts | 2 +- editors/code/src/run.ts | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index a317aabcb..3257275c5 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -5,7 +5,7 @@ export type UpdatesChannel = "stable" | "nightly"; export const NIGHTLY_TAG = "nightly"; -export type RunnableEnvCfg = Record | [{ mask?: string, env: Record; }] +export type RunnableEnvCfg = undefined | Record | { mask?: string, env: Record; }[]; export class Config { readonly extensionId = "matklad.rust-analyzer"; @@ -117,7 +117,7 @@ export class Config { } get runnableEnv() { - return this.get("runnableEnv"); + return this.get("runnableEnv"); } get debug() { diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts index 525d26923..bd92c5b6d 100644 --- a/editors/code/src/debug.ts +++ b/editors/code/src/debug.ts @@ -93,7 +93,7 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise { +export function prepareEnv(runnable: ra.Runnable, runnableEnvCfg: RunnableEnvCfg): Record { const env: Record = { "RUST_BACKTRACE": "short" }; if (runnable.args.expectTest) { env["UPDATE_EXPECT"] = "1"; } - if (config.runnableEnv) { - if (Array.isArray(config.runnableEnv)) { - for (const it of config.runnableEnv) { + if (runnableEnvCfg) { + if (Array.isArray(runnableEnvCfg)) { + for (const it of runnableEnvCfg) { if (!it.mask || new RegExp(it.mask).test(runnable.label)) { Object.assign(env, it.env); } } } else { - Object.assign(env, config.runnableEnv as Record); + Object.assign(env, runnableEnvCfg as Record); } } @@ -136,7 +136,7 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise command: args[0], // run, test, etc... args: args.slice(1), cwd: runnable.args.workspaceRoot, - env: prepareEnv(runnable, config), + env: prepareEnv(runnable, config.runnableEnv), }; const target = vscode.workspace.workspaceFolders![0]; // safe, see main activate() -- cgit v1.2.3 From 611fad275fb7f3c2ec018b5539444b6649285228 Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 2 Jul 2020 22:08:33 +0300 Subject: code linting --- editors/code/src/config.ts | 2 +- editors/code/src/run.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 3257275c5..23975c726 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -5,7 +5,7 @@ export type UpdatesChannel = "stable" | "nightly"; export const NIGHTLY_TAG = "nightly"; -export type RunnableEnvCfg = undefined | Record | { mask?: string, env: Record; }[]; +export type RunnableEnvCfg = undefined | Record | { mask?: string; env: Record }[]; export class Config { readonly extensionId = "matklad.rust-analyzer"; diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts index 4a5c6ad41..c09954614 100644 --- a/editors/code/src/run.ts +++ b/editors/code/src/run.ts @@ -111,7 +111,7 @@ export function prepareEnv(runnable: ra.Runnable, runnableEnvCfg: RunnableEnvCfg } } } else { - Object.assign(env, runnableEnvCfg as Record); + Object.assign(env, runnableEnvCfg); } } -- cgit v1.2.3 From bebbfa1a29062a3e9304c80080316d8c4937e5bc Mon Sep 17 00:00:00 2001 From: vsrs Date: Fri, 3 Jul 2020 14:56:30 +0300 Subject: Fix workspaceRoot --- editors/code/src/run.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts index c09954614..de68f27ae 100644 --- a/editors/code/src/run.ts +++ b/editors/code/src/run.ts @@ -103,6 +103,8 @@ export function prepareEnv(runnable: ra.Runnable, runnableEnvCfg: RunnableEnvCfg env["UPDATE_EXPECT"] = "1"; } + Object.assign(env, process.env as { [key: string]: string }); + if (runnableEnvCfg) { if (Array.isArray(runnableEnvCfg)) { for (const it of runnableEnvCfg) { @@ -135,7 +137,7 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise type: tasks.TASK_TYPE, command: args[0], // run, test, etc... args: args.slice(1), - cwd: runnable.args.workspaceRoot, + cwd: runnable.args.workspaceRoot || ".", env: prepareEnv(runnable, config.runnableEnv), }; -- cgit v1.2.3 From 3602f07bbee5b13dcd799cbc79381e9428808048 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 5 Jul 2020 17:42:52 +0300 Subject: Improve client logging (use output channel and more log levels) --- editors/code/src/config.ts | 8 +++--- editors/code/src/main.ts | 6 ++--- editors/code/src/persistent_state.ts | 2 +- editors/code/src/util.ts | 51 +++++++++++++++++++++++++++++------- 4 files changed, 49 insertions(+), 18 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 23975c726..033b04b60 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -39,10 +39,10 @@ export class Config { private refreshLogging() { log.setEnabled(this.traceExtension); - log.debug( - "Extension version:", this.package.version, - "using configuration:", this.cfg - ); + log.info("Extension version:", this.package.version); + + const cfg = Object.entries(this.cfg).filter(([_, val]) => !(val instanceof Function)); + log.info("Using configuration", Object.fromEntries(cfg)); } private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) { diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index a1521a93b..5877be8b2 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -59,8 +59,8 @@ async function tryActivate(context: vscode.ExtensionContext) { message += "you should close them and reload this window to retry. "; } - message += 'Open "Help > Toggle Developer Tools > Console" to see the logs '; - message += '(enable verbose logs with "rust-analyzer.trace.extension")'; + message += 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). '; + message += 'To enable verbose logs use { "rust-analyzer.trace.extension": true }'; log.error("Bootstrap error", err); throw new Error(message); @@ -214,7 +214,7 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< ); } - log.debug("Using server binary at", path); + log.info("Using server binary at", path); if (!isValidExecutable(path)) { throw new Error(`Failed to execute ${path} --version`); diff --git a/editors/code/src/persistent_state.ts b/editors/code/src/persistent_state.ts index 138d11b89..5705eed81 100644 --- a/editors/code/src/persistent_state.ts +++ b/editors/code/src/persistent_state.ts @@ -4,7 +4,7 @@ import { log } from './util'; export class PersistentState { constructor(private readonly globalState: vscode.Memento) { const { lastCheck, releaseId, serverVersion } = this; - log.debug("PersistentState: ", { lastCheck, releaseId, serverVersion }); + log.info("PersistentState:", { lastCheck, releaseId, serverVersion }); } /** diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index fec4c3295..78fe6f5da 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -1,7 +1,9 @@ import * as lc from "vscode-languageclient"; +import * as fs from "fs"; import * as vscode from "vscode"; import { strict as nativeAssert } from "assert"; import { spawnSync } from "child_process"; +import { inspect } from "util"; export function assert(condition: boolean, explanation: string): asserts condition { try { @@ -14,21 +16,46 @@ export function assert(condition: boolean, explanation: string): asserts conditi export const log = new class { private enabled = true; + private readonly output = vscode.window.createOutputChannel("Rust Analyzer Client"); setEnabled(yes: boolean): void { log.enabled = yes; } - debug(message?: any, ...optionalParams: any[]): void { + // Hint: the type [T, ...T[]] means a non-empty array + debug(...msg: [unknown, ...unknown[]]): void { if (!log.enabled) return; - // eslint-disable-next-line no-console - console.log(message, ...optionalParams); + log.write("DEBUG", ...msg); + log.output.toString(); } - error(message?: any, ...optionalParams: any[]): void { + info(...msg: [unknown, ...unknown[]]): void { + log.write("INFO", ...msg); + } + + warn(...msg: [unknown, ...unknown[]]): void { + debugger; + log.write("WARN", ...msg); + } + + error(...msg: [unknown, ...unknown[]]): void { debugger; - // eslint-disable-next-line no-console - console.error(message, ...optionalParams); + log.write("ERROR", ...msg); + log.output.show(true); + } + + private write(label: string, ...messageParts: unknown[]): void { + const message = messageParts.map(log.stringify).join(" "); + const dateTime = new Date().toLocaleString(); + log.output.appendLine(`${label} [${dateTime}]: ${message}`); + } + + private stringify(val: unknown): string { + if (typeof val === "string") return val; + return inspect(val, { + colors: false, + depth: 6, // heuristic + }); } }; @@ -46,7 +73,7 @@ export async function sendRequestWithRetry( ); } catch (error) { if (delay === null) { - log.error("LSP request timed out", { method: reqType.method, param, error }); + log.warn("LSP request timed out", { method: reqType.method, param, error }); throw error; } @@ -55,7 +82,7 @@ export async function sendRequestWithRetry( } if (error.code !== lc.ErrorCodes.ContentModified) { - log.error("LSP request failed", { method: reqType.method, param, error }); + log.warn("LSP request failed", { method: reqType.method, param, error }); throw error; } @@ -87,11 +114,15 @@ export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { export function isValidExecutable(path: string): boolean { log.debug("Checking availability of a binary at", path); + if (!fs.existsSync(path)) return false; + const res = spawnSync(path, ["--version"], { encoding: 'utf8' }); - log.debug(res, "--version output:", res.output); + const isSuccess = res.status === 0; + const printOutput = isSuccess ? log.debug : log.warn; + printOutput(path, "--version:", res); - return res.status === 0; + return isSuccess; } /** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */ -- cgit v1.2.3 From 13872543e074adc153b440660beda441fd562f53 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 5 Jul 2020 21:05:38 +0300 Subject: Dispose logger on extension deactivation --- editors/code/src/main.ts | 2 ++ editors/code/src/util.ts | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 5877be8b2..f22981930 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -49,6 +49,8 @@ async function tryActivate(context: vscode.ExtensionContext) { ); context.subscriptions.push(defaultOnEnter); + context.subscriptions.push(log); + const config = new Config(context); const state = new PersistentState(context.globalState); const serverPath = await bootstrap(config, state).catch(err => { diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 78fe6f5da..6b07d448b 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -18,6 +18,10 @@ export const log = new class { private enabled = true; private readonly output = vscode.window.createOutputChannel("Rust Analyzer Client"); + dispose() { + log.output.dispose(); + } + setEnabled(yes: boolean): void { log.enabled = yes; } -- cgit v1.2.3 From 46163acf62a94ec603be444294e119933c953a84 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 5 Jul 2020 21:10:31 +0300 Subject: Revert "Dispose logger on extension deactivation" This reverts commit 13872543e074adc153b440660beda441fd562f53. That commit was wrong because we use-after-free the logger --- editors/code/src/main.ts | 2 -- editors/code/src/util.ts | 4 ---- 2 files changed, 6 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index f22981930..5877be8b2 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -49,8 +49,6 @@ async function tryActivate(context: vscode.ExtensionContext) { ); context.subscriptions.push(defaultOnEnter); - context.subscriptions.push(log); - const config = new Config(context); const state = new PersistentState(context.globalState); const serverPath = await bootstrap(config, state).catch(err => { diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 6b07d448b..78fe6f5da 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -18,10 +18,6 @@ export const log = new class { private enabled = true; private readonly output = vscode.window.createOutputChannel("Rust Analyzer Client"); - dispose() { - log.output.dispose(); - } - setEnabled(yes: boolean): void { log.enabled = yes; } -- cgit v1.2.3 From ef223b9e6439c228e0be49861efd2067c0b22af4 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 6 Jul 2020 13:39:08 +0300 Subject: Fix: allow for binaries from $PATH to pass validity check --- editors/code/src/util.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 78fe6f5da..970fedb37 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -1,5 +1,4 @@ import * as lc from "vscode-languageclient"; -import * as fs from "fs"; import * as vscode from "vscode"; import { strict as nativeAssert } from "assert"; import { spawnSync } from "child_process"; @@ -114,15 +113,12 @@ export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { export function isValidExecutable(path: string): boolean { log.debug("Checking availability of a binary at", path); - if (!fs.existsSync(path)) return false; - const res = spawnSync(path, ["--version"], { encoding: 'utf8' }); - const isSuccess = res.status === 0; - const printOutput = isSuccess ? log.debug : log.warn; + const printOutput = res.error && (res.error as any).code !== 'ENOENT' ? log.warn : log.debug; printOutput(path, "--version:", res); - return isSuccess; + return res.status === 0; } /** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */ -- cgit v1.2.3 From fd1487db51dcbd3296e00e3e62a7e8414e1c48d9 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Tue, 7 Jul 2020 12:09:37 +0300 Subject: Consider EPERM error as other vscode processes using rust-analyzer --- editors/code/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 5877be8b2..4b990afa1 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -54,7 +54,7 @@ async function tryActivate(context: vscode.ExtensionContext) { const serverPath = await bootstrap(config, state).catch(err => { let message = "bootstrap error. "; - if (err.code === "EBUSY" || err.code === "ETXTBSY") { + if (err.code === "EBUSY" || err.code === "ETXTBSY" || err.code === "EPERM") { message += "Other vscode windows might be using rust-analyzer, "; message += "you should close them and reload this window to retry. "; } -- cgit v1.2.3 From f44c4b61e131284287b24dea6da6324cbe9cb252 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 7 Jul 2020 12:10:14 +0200 Subject: Add a command to compute memory usage statistics --- editors/code/src/commands.ts | 32 ++++++++++++++++++++++++++++++++ editors/code/src/lsp_ext.ts | 1 + editors/code/src/main.ts | 1 + 3 files changed, 34 insertions(+) (limited to 'editors/code/src') diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 19a9c2a0d..1f3a7cf7e 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -55,6 +55,38 @@ export function analyzerStatus(ctx: Ctx): Cmd { }; } +export function memoryUsage(ctx: Ctx): Cmd { + const tdcp = new class implements vscode.TextDocumentContentProvider { + readonly uri = vscode.Uri.parse('rust-analyzer-memory://memory'); + readonly eventEmitter = new vscode.EventEmitter(); + + provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult { + if (!vscode.window.activeTextEditor) return ''; + + return ctx.client.sendRequest(ra.memoryUsage, null).then((mem) => { + return 'Per-query memory usage:\n' + mem + '\n(note: database has been cleared)'; + }); + } + + get onDidChange(): vscode.Event { + return this.eventEmitter.event; + } + }(); + + ctx.pushCleanup( + vscode.workspace.registerTextDocumentContentProvider( + 'rust-analyzer-memory', + tdcp, + ), + ); + + return async () => { + tdcp.eventEmitter.fire(tdcp.uri); + const document = await vscode.workspace.openTextDocument(tdcp.uri); + return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true); + }; +} + export function matchingBrace(ctx: Ctx): Cmd { return async () => { const editor = ctx.activeRustEditor; diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index bf4703239..5f32cb40e 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -5,6 +5,7 @@ import * as lc from "vscode-languageclient"; export const analyzerStatus = new lc.RequestType("rust-analyzer/analyzerStatus"); +export const memoryUsage = new lc.RequestType("rust-analyzer/memoryUsage"); export type Status = "loading" | "ready" | "invalid" | "needsReload"; export const status = new lc.NotificationType("rust-analyzer/status"); diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 4b990afa1..eda95ae5c 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -96,6 +96,7 @@ async function tryActivate(context: vscode.ExtensionContext) { }); ctx.registerCommand('analyzerStatus', commands.analyzerStatus); + ctx.registerCommand('memoryUsage', commands.memoryUsage); ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace); ctx.registerCommand('matchingBrace', commands.matchingBrace); ctx.registerCommand('joinLines', commands.joinLines); -- cgit v1.2.3 From f92bfb580780cda02f9ba8a935538f984d8a4c0d Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 21 Jun 2020 15:58:34 +0300 Subject: Gzip artifacts Co-authored-by: bjorn3 Override miniz_oxide to build it with optimizations Building this crate with optimizations decreases the gzipping part of `cargo xtask dist` from `30-40s` down to `3s`, the overhead for `rustc` to apply optimizations is miserable on this background --- editors/code/src/main.ts | 17 +++++++++-------- editors/code/src/net.ts | 16 ++++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index eda95ae5c..bd99d696a 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -274,13 +274,13 @@ async function getServer(config: Config, state: PersistentState): Promise true, () => false); if (!exists) { await state.updateServerVersion(undefined); @@ -309,7 +309,7 @@ async function getServer(config: Config, state: PersistentState): Promise artifact.name === binaryName); + const artifact = release.assets.find(artifact => artifact.name === `rust-analyzer-${platform}.gz`); assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); // Unlinking the exe file before moving new one on its place should prevent ETXTBSY error. @@ -321,6 +321,7 @@ async function getServer(config: Config, state: PersistentState): Promise { let lastPercentage = 0; - await downloadFile(opts.url, tempFile, opts.mode, (readBytes, totalBytes) => { + await downloadFile(opts.url, tempFile, opts.mode, !!opts.gunzip, (readBytes, totalBytes) => { const newPercentage = (readBytes / totalBytes) * 100; progress.report({ message: newPercentage.toFixed(0) + "%", @@ -97,16 +99,11 @@ export async function download(opts: DownloadOpts) { await fs.promises.rename(tempFile, opts.dest); } -/** - * Downloads file from `url` and stores it at `destFilePath` with `mode` (unix permissions). - * `onProgress` callback is called on recieveing each chunk of bytes - * to track the progress of downloading, it gets the already read and total - * amount of bytes to read as its parameters. - */ async function downloadFile( url: string, destFilePath: fs.PathLike, mode: number | undefined, + gunzip: boolean, onProgress: (readBytes: number, totalBytes: number) => void ): Promise { const res = await fetch(url); @@ -130,7 +127,10 @@ async function downloadFile( }); const destFileStream = fs.createWriteStream(destFilePath, { mode }); - await pipeline(res.body, destFileStream); + const srcStream = gunzip ? res.body.pipe(zlib.createGunzip()) : res.body; + + await pipeline(srcStream, destFileStream); + await new Promise(resolve => { destFileStream.on("close", resolve); destFileStream.destroy(); -- cgit v1.2.3 From e2fec10dc17943cffde7dfc3bd94bb64b3f3c2a9 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 8 Jul 2020 14:47:34 +0300 Subject: Workaround rollup messing up default imports --- editors/code/src/net.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/net.ts b/editors/code/src/net.ts index 53c9e91cd..681eaa9c9 100644 --- a/editors/code/src/net.ts +++ b/editors/code/src/net.ts @@ -1,4 +1,7 @@ -import fetch from "node-fetch"; +// Replace with `import fetch from "node-fetch"` once this is fixed in rollup: +// https://github.com/rollup/plugins/issues/491 +const fetch = require("node-fetch") as typeof import("node-fetch")["default"]; + import * as vscode from "vscode"; import * as stream from "stream"; import * as crypto from "crypto"; -- cgit v1.2.3 From 1b5a74ef18389f7d1a90cb6945a17bc412f707b4 Mon Sep 17 00:00:00 2001 From: Timo Freiberg Date: Tue, 21 Jul 2020 19:47:27 +0200 Subject: Fix snippetTextEdits applying to other files vscode.window.visibleTextEditors only contains editors whose contents are being displayed at the moment, so the previous logic only worked if the other file for which a snippetTextEdit is being received was visible in a separate split. --- editors/code/src/snippets.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'editors/code/src') diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts index bcb3f2cc7..258b49982 100644 --- a/editors/code/src/snippets.ts +++ b/editors/code/src/snippets.ts @@ -6,6 +6,10 @@ export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) { assert(edit.entries().length === 1, `bad ws edit: ${JSON.stringify(edit)}`); const [uri, edits] = edit.entries()[0]; + if (vscode.window.activeTextEditor?.document.uri !== uri) { + // `vscode.window.visibleTextEditors` only contains editors whose contents are being displayed + await vscode.window.showTextDocument(uri, {}); + } const editor = vscode.window.visibleTextEditors.find((it) => it.document.uri.toString() === uri.toString()); if (!editor) return; await applySnippetTextEdits(editor, edits); -- cgit v1.2.3 From 995c624f57e91ed6c2ea4349d3a4d0d7a5e80b15 Mon Sep 17 00:00:00 2001 From: James Leitch Date: Wed, 22 Jul 2020 22:32:54 -0700 Subject: ProblemMatcher auto detects relative/absolute paths and matches VSCode LSP's owner and source. VSCode LSP updated to specify owner. --- editors/code/src/client.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 41ffac7b3..18948cb3c 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -41,6 +41,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient const clientOptions: lc.LanguageClientOptions = { documentSelector: [{ scheme: 'file', language: 'rust' }], initializationOptions: vscode.workspace.getConfiguration("rust-analyzer"), + diagnosticCollectionName: "rustc", traceOutputChannel, middleware: { // Workaround for https://github.com/microsoft/vscode-languageserver-node/issues/576 -- cgit v1.2.3 From 3975952601888d9f77e466c12e8e389748984b33 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Wed, 22 Jul 2020 15:00:28 +1000 Subject: SSR: Pass current file position through to SSR code. In a subsequent commit, it will be used for resolving paths. --- editors/code/src/commands.ts | 14 +++++++++++--- editors/code/src/lsp_ext.ts | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 1f3a7cf7e..3ae995705 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -185,15 +185,21 @@ export function parentModule(ctx: Ctx): Cmd { export function ssr(ctx: Ctx): Cmd { return async () => { + const editor = vscode.window.activeTextEditor; const client = ctx.client; - if (!client) return; + if (!editor || !client) return; + + const position = editor.selection.active; + let textDocument = { uri: editor.document.uri.toString() }; const options: vscode.InputBoxOptions = { value: "() ==>> ()", prompt: "Enter request, for example 'Foo($a) ==> Foo::new($a)' ", validateInput: async (x: string) => { try { - await client.sendRequest(ra.ssr, { query: x, parseOnly: true }); + await client.sendRequest(ra.ssr, { + query: x, parseOnly: true, textDocument, position, + }); } catch (e) { return e.toString(); } @@ -208,7 +214,9 @@ export function ssr(ctx: Ctx): Cmd { title: "Structured search replace in progress...", cancellable: false, }, async (_progress, _token) => { - const edit = await client.sendRequest(ra.ssr, { query: request, parseOnly: false }); + const edit = await client.sendRequest(ra.ssr, { + query: request, parseOnly: false, textDocument, position + }); await vscode.workspace.applyEdit(client.protocol2CodeConverter.asWorkspaceEdit(edit)); }); diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 5f32cb40e..149f9a0d6 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -93,6 +93,8 @@ export const inlayHints = new lc.RequestType('experimental/ssr'); -- cgit v1.2.3 From 58680cb08ea535e1fb567416fa3466a744a01b99 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Fri, 24 Jul 2020 22:23:14 +1000 Subject: SSR: Fix a typescript lint warning --- editors/code/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 3ae995705..c21e5597c 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -190,7 +190,7 @@ export function ssr(ctx: Ctx): Cmd { if (!editor || !client) return; const position = editor.selection.active; - let textDocument = { uri: editor.document.uri.toString() }; + const textDocument = { uri: editor.document.uri.toString() }; const options: vscode.InputBoxOptions = { value: "() ==>> ()", -- cgit v1.2.3 From cf55806257776baf7db6b02d260bdaa9e851c7d4 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Wed, 29 Jul 2020 11:44:01 +1000 Subject: SSR: Restrict to current selection if any The selection is also used to avoid unnecessary work, but only to the file level. Further restricting unnecessary work is left for later. --- editors/code/src/commands.ts | 5 +++-- editors/code/src/lsp_ext.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index c21e5597c..d0faf4745 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -190,6 +190,7 @@ export function ssr(ctx: Ctx): Cmd { if (!editor || !client) return; const position = editor.selection.active; + const selections = editor.selections; const textDocument = { uri: editor.document.uri.toString() }; const options: vscode.InputBoxOptions = { @@ -198,7 +199,7 @@ export function ssr(ctx: Ctx): Cmd { validateInput: async (x: string) => { try { await client.sendRequest(ra.ssr, { - query: x, parseOnly: true, textDocument, position, + query: x, parseOnly: true, textDocument, position, selections, }); } catch (e) { return e.toString(); @@ -215,7 +216,7 @@ export function ssr(ctx: Ctx): Cmd { cancellable: false, }, async (_progress, _token) => { const edit = await client.sendRequest(ra.ssr, { - query: request, parseOnly: false, textDocument, position + query: request, parseOnly: false, textDocument, position, selections, }); await vscode.workspace.applyEdit(client.protocol2CodeConverter.asWorkspaceEdit(edit)); diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 149f9a0d6..494d51c83 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -95,6 +95,7 @@ export interface SsrParams { parseOnly: boolean; textDocument: lc.TextDocumentIdentifier; position: lc.Position; + selections: lc.Range[]; } export const ssr = new lc.RequestType('experimental/ssr'); -- cgit v1.2.3