Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'editors/code/src/main.ts')
| -rw-r--r-- | editors/code/src/main.ts | 198 |
1 files changed, 114 insertions, 84 deletions
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 39bd73c663..61824fae21 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -1,15 +1,15 @@ -import * as vscode from 'vscode'; -import * as lc from 'vscode-languageclient/node'; +import * as vscode from "vscode"; +import * as lc from "vscode-languageclient/node"; import * as os from "os"; -import * as commands from './commands'; -import { Ctx } from './ctx'; -import { Config } from './config'; -import { log, isValidExecutable, isRustDocument } from './util'; -import { PersistentState } from './persistent_state'; -import { activateTaskProvider } from './tasks'; -import { setContextValue } from './util'; -import { exec } from 'child_process'; +import * as commands from "./commands"; +import { Ctx } from "./ctx"; +import { Config } from "./config"; +import { log, isValidExecutable, isRustDocument } from "./util"; +import { PersistentState } from "./persistent_state"; +import { activateTaskProvider } from "./tasks"; +import { setContextValue } from "./util"; +import { exec } from "child_process"; let ctx: Ctx | undefined; @@ -19,10 +19,12 @@ export interface RustAnalyzerExtensionApi { client: lc.LanguageClient; } -export async function activate(context: vscode.ExtensionContext): Promise<RustAnalyzerExtensionApi> { +export async function activate( + context: vscode.ExtensionContext +): Promise<RustAnalyzerExtensionApi> { // VS Code doesn't show a notification when an extension fails to activate // so we do it ourselves. - return await tryActivate(context).catch(err => { + return await tryActivate(context).catch((err) => { void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`); throw err; }); @@ -31,7 +33,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<RustAn async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyzerExtensionApi> { const config = new Config(context); const state = new PersistentState(context.globalState); - const serverPath = await bootstrap(context, config, state).catch(err => { + const serverPath = await bootstrap(context, config, state).catch((err) => { let message = "bootstrap error. "; message += 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). '; @@ -42,9 +44,14 @@ async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyz }); if ((vscode.workspace.workspaceFolders || []).length === 0) { - const rustDocuments = vscode.workspace.textDocuments.filter(document => isRustDocument(document)); + const rustDocuments = vscode.workspace.textDocuments.filter((document) => + isRustDocument(document) + ); if (rustDocuments.length > 0) { - ctx = await Ctx.create(config, context, serverPath, { kind: 'Detached Files', files: rustDocuments }); + ctx = await Ctx.create(config, context, serverPath, { + kind: "Detached Files", + files: rustDocuments, + }); } else { throw new Error("no rust files are opened"); } @@ -63,13 +70,16 @@ async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyz ctx.pushCleanup(configureLanguage()); vscode.workspace.onDidChangeConfiguration( - _ => ctx?.client?.sendNotification('workspace/didChangeConfiguration', { settings: "" }).catch(log.error), + (_) => + ctx?.client + ?.sendNotification("workspace/didChangeConfiguration", { settings: "" }) + .catch(log.error), null, - ctx.subscriptions, + ctx.subscriptions ); return { - client: ctx.client + client: ctx.client, }; } @@ -88,9 +98,8 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) { // "rust-analyzer is not available" // ), // ) - const defaultOnEnter = vscode.commands.registerCommand( - 'rust-analyzer.onEnter', - () => vscode.commands.executeCommand('default:type', { text: '\n' }), + const defaultOnEnter = vscode.commands.registerCommand("rust-analyzer.onEnter", () => + vscode.commands.executeCommand("default:type", { text: "\n" }) ); context.subscriptions.push(defaultOnEnter); @@ -99,8 +108,8 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) { // Commands which invokes manually via command palette, shortcut, etc. // Reloading is inspired by @DanTup maneuver: https://github.com/microsoft/vscode/issues/45774#issuecomment-373423895 - ctx.registerCommand('reload', _ => async () => { - void vscode.window.showInformationMessage('Reloading rust-analyzer...'); + ctx.registerCommand("reload", (_) => async () => { + void vscode.window.showInformationMessage("Reloading rust-analyzer..."); await deactivate(); while (context.subscriptions.length > 0) { try { @@ -112,45 +121,45 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) { await activate(context).catch(log.error); }); - ctx.registerCommand('analyzerStatus', commands.analyzerStatus); - ctx.registerCommand('memoryUsage', commands.memoryUsage); - ctx.registerCommand('shuffleCrateGraph', commands.shuffleCrateGraph); - ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace); - ctx.registerCommand('matchingBrace', commands.matchingBrace); - ctx.registerCommand('joinLines', commands.joinLines); - ctx.registerCommand('parentModule', commands.parentModule); - ctx.registerCommand('syntaxTree', commands.syntaxTree); - ctx.registerCommand('viewHir', commands.viewHir); - ctx.registerCommand('viewFileText', commands.viewFileText); - ctx.registerCommand('viewItemTree', commands.viewItemTree); - ctx.registerCommand('viewCrateGraph', commands.viewCrateGraph); - ctx.registerCommand('viewFullCrateGraph', commands.viewFullCrateGraph); - ctx.registerCommand('expandMacro', commands.expandMacro); - ctx.registerCommand('run', commands.run); - ctx.registerCommand('copyRunCommandLine', commands.copyRunCommandLine); - ctx.registerCommand('debug', commands.debug); - ctx.registerCommand('newDebugConfig', commands.newDebugConfig); - ctx.registerCommand('openDocs', commands.openDocs); - ctx.registerCommand('openCargoToml', commands.openCargoToml); - ctx.registerCommand('peekTests', commands.peekTests); - ctx.registerCommand('moveItemUp', commands.moveItemUp); - ctx.registerCommand('moveItemDown', commands.moveItemDown); + ctx.registerCommand("analyzerStatus", commands.analyzerStatus); + ctx.registerCommand("memoryUsage", commands.memoryUsage); + ctx.registerCommand("shuffleCrateGraph", commands.shuffleCrateGraph); + ctx.registerCommand("reloadWorkspace", commands.reloadWorkspace); + ctx.registerCommand("matchingBrace", commands.matchingBrace); + ctx.registerCommand("joinLines", commands.joinLines); + ctx.registerCommand("parentModule", commands.parentModule); + ctx.registerCommand("syntaxTree", commands.syntaxTree); + ctx.registerCommand("viewHir", commands.viewHir); + ctx.registerCommand("viewFileText", commands.viewFileText); + ctx.registerCommand("viewItemTree", commands.viewItemTree); + ctx.registerCommand("viewCrateGraph", commands.viewCrateGraph); + ctx.registerCommand("viewFullCrateGraph", commands.viewFullCrateGraph); + ctx.registerCommand("expandMacro", commands.expandMacro); + ctx.registerCommand("run", commands.run); + ctx.registerCommand("copyRunCommandLine", commands.copyRunCommandLine); + ctx.registerCommand("debug", commands.debug); + ctx.registerCommand("newDebugConfig", commands.newDebugConfig); + ctx.registerCommand("openDocs", commands.openDocs); + ctx.registerCommand("openCargoToml", commands.openCargoToml); + ctx.registerCommand("peekTests", commands.peekTests); + ctx.registerCommand("moveItemUp", commands.moveItemUp); + ctx.registerCommand("moveItemDown", commands.moveItemDown); defaultOnEnter.dispose(); - ctx.registerCommand('onEnter', commands.onEnter); + ctx.registerCommand("onEnter", commands.onEnter); - ctx.registerCommand('ssr', commands.ssr); - ctx.registerCommand('serverVersion', commands.serverVersion); - ctx.registerCommand('toggleInlayHints', commands.toggleInlayHints); + ctx.registerCommand("ssr", commands.ssr); + ctx.registerCommand("serverVersion", commands.serverVersion); + ctx.registerCommand("toggleInlayHints", commands.toggleInlayHints); // Internal commands which are invoked by the server. - ctx.registerCommand('runSingle', commands.runSingle); - ctx.registerCommand('debugSingle', commands.debugSingle); - ctx.registerCommand('showReferences', commands.showReferences); - ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEditCommand); - ctx.registerCommand('resolveCodeAction', commands.resolveCodeAction); - ctx.registerCommand('applyActionGroup', commands.applyActionGroup); - ctx.registerCommand('gotoLocation', commands.gotoLocation); + ctx.registerCommand("runSingle", commands.runSingle); + ctx.registerCommand("debugSingle", commands.debugSingle); + ctx.registerCommand("showReferences", commands.showReferences); + ctx.registerCommand("applySnippetWorkspaceEdit", commands.applySnippetWorkspaceEditCommand); + ctx.registerCommand("resolveCodeAction", commands.resolveCodeAction); + ctx.registerCommand("applyActionGroup", commands.applyActionGroup); + ctx.registerCommand("gotoLocation", commands.gotoLocation); } export async function deactivate() { @@ -159,12 +168,16 @@ export async function deactivate() { ctx = undefined; } -async function bootstrap(context: vscode.ExtensionContext, config: Config, state: PersistentState): Promise<string> { +async function bootstrap( + context: vscode.ExtensionContext, + config: Config, + state: PersistentState +): Promise<string> { const path = await getServer(context, config, state); if (!path) { throw new Error( "Rust Analyzer Language Server is not available. " + - "Please, ensure its [proper installation](https://rust-analyzer.github.io/manual.html#installation)." + "Please, ensure its [proper installation](https://rust-analyzer.github.io/manual.html#installation)." ); } @@ -186,7 +199,7 @@ async function patchelf(dest: vscode.Uri): Promise<void> { await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, - title: "Patching rust-analyzer for NixOS" + title: "Patching rust-analyzer for NixOS", }, async (progress, _) => { const expression = ` @@ -207,14 +220,16 @@ async function patchelf(dest: vscode.Uri): Promise<void> { try { progress.report({ message: "Patching executable", increment: 20 }); await new Promise((resolve, reject) => { - const handle = exec(`nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`, + const handle = exec( + `nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`, (err, stdout, stderr) => { if (err != null) { reject(Error(stderr)); } else { resolve(stdout); } - }); + } + ); handle.stdin?.write(expression); handle.stdin?.end(); }); @@ -225,25 +240,35 @@ async function patchelf(dest: vscode.Uri): Promise<void> { ); } -async function getServer(context: vscode.ExtensionContext, config: Config, state: PersistentState): Promise<string | undefined> { +async function getServer( + context: vscode.ExtensionContext, + config: Config, + state: PersistentState +): Promise<string | undefined> { const explicitPath = serverPath(config); if (explicitPath) { if (explicitPath.startsWith("~/")) { return os.homedir() + explicitPath.slice("~".length); } return explicitPath; - }; + } if (config.package.releaseTag === null) return "rust-analyzer"; const ext = process.platform === "win32" ? ".exe" : ""; const bundled = vscode.Uri.joinPath(context.extensionUri, "server", `rust-analyzer${ext}`); - const bundledExists = await vscode.workspace.fs.stat(bundled).then(() => true, () => false); + const bundledExists = await vscode.workspace.fs.stat(bundled).then( + () => true, + () => false + ); if (bundledExists) { let server = bundled; if (await isNixOs()) { await vscode.workspace.fs.createDirectory(config.globalStorageUri).then(); const dest = vscode.Uri.joinPath(config.globalStorageUri, `rust-analyzer${ext}`); - let exists = await vscode.workspace.fs.stat(dest).then(() => true, () => false); + let exists = await vscode.workspace.fs.stat(dest).then( + () => true, + () => false + ); if (exists && config.package.version !== state.serverVersion) { await vscode.workspace.fs.delete(dest); exists = false; @@ -261,11 +286,11 @@ async function getServer(context: vscode.ExtensionContext, config: Config, state await state.updateServerVersion(undefined); await vscode.window.showErrorMessage( "Unfortunately we don't ship binaries for your platform yet. " + - "You need to manually clone the rust-analyzer repository and " + - "run `cargo xtask install --server` to build the language server from sources. " + - "If you feel that your platform should be supported, please create an issue " + - "about that [here](https://github.com/rust-analyzer/rust-analyzer/issues) and we " + - "will consider it." + "You need to manually clone the rust-analyzer repository and " + + "run `cargo xtask install --server` to build the language server from sources. " + + "If you feel that your platform should be supported, please create an issue " + + "about that [here](https://github.com/rust-analyzer/rust-analyzer/issues) and we " + + "will consider it." ); return undefined; } @@ -276,8 +301,10 @@ function serverPath(config: Config): string | null { async function isNixOs(): Promise<boolean> { try { - const contents = (await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release"))).toString(); - const idString = contents.split('\n').find((a) => a.startsWith("ID=")) || "ID=linux"; + const contents = ( + await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release")) + ).toString(); + const idString = contents.split("\n").find((a) => a.startsWith("ID=")) || "ID=linux"; return idString.indexOf("nixos") !== -1; } catch { return false; @@ -286,11 +313,14 @@ async function isNixOs(): Promise<boolean> { function warnAboutExtensionConflicts() { if (vscode.extensions.getExtension("rust-lang.rust")) { - vscode.window.showWarningMessage( - `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` + - "plugins enabled. These are known to conflict and cause various functions of " + - "both plugins to not work correctly. You should disable one of them.", "Got it") - .then(() => { }, console.error); + vscode.window + .showWarningMessage( + `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` + + "plugins enabled. These are known to conflict and cause various functions of " + + "both plugins to not work correctly. You should disable one of them.", + "Got it" + ) + .then(() => {}, console.error); } } @@ -302,38 +332,38 @@ function warnAboutExtensionConflicts() { */ function configureLanguage(): vscode.Disposable { const indentAction = vscode.IndentAction.None; - return vscode.languages.setLanguageConfiguration('rust', { + return vscode.languages.setLanguageConfiguration("rust", { onEnterRules: [ { // Doc single-line comment // e.g. ///| beforeText: /^\s*\/{3}.*$/, - action: { indentAction, appendText: '/// ' }, + action: { indentAction, appendText: "/// " }, }, { // Parent doc single-line comment // e.g. //!| beforeText: /^\s*\/{2}\!.*$/, - action: { indentAction, appendText: '//! ' }, + action: { indentAction, appendText: "//! " }, }, { // Begins an auto-closed multi-line comment (standard or parent doc) // e.g. /** | */ or /*! | */ beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/, afterText: /^\s*\*\/$/, - action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: ' * ' }, + action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: " * " }, }, { // Begins a multi-line comment (standard or parent doc) // e.g. /** ...| or /*! ...| beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/, - action: { indentAction, appendText: ' * ' }, + action: { indentAction, appendText: " * " }, }, { // Continues a multi-line comment // e.g. * ...| beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/, - action: { indentAction, appendText: '* ' }, + action: { indentAction, appendText: "* " }, }, { // Dedents after closing a multi-line comment |