From 60cac299640912ad1ad75644bfa0088d7ba6e367 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 18 Mar 2019 22:30:23 +0100 Subject: Separate out the interactive cargo watch procedure --- editors/code/src/commands/runnables.ts | 68 +++++++++++++++++++++++++++++++++- editors/code/src/extension.ts | 66 ++------------------------------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 23fd280b4..285afaaf6 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -1,5 +1,8 @@ +import { exec } from 'child_process'; +import * as util from 'util'; import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; + import { Server } from '../server'; interface RunnablesParams { @@ -33,7 +36,7 @@ interface CargoTaskDefinition extends vscode.TaskDefinition { env?: { [key: string]: string }; } -export function createTask(spec: Runnable): vscode.Task { +function createTask(spec: Runnable): vscode.Task { const TASK_SOURCE = 'Rust'; const definition: CargoTaskDefinition = { type: 'cargo', @@ -143,3 +146,66 @@ export const autoCargoWatchTask: vscode.Task = { runOn: 2 // RunOnOptions.folderOpen } as unknown) as vscode.RunOptions }; + +/** + * Interactively asks the user whether we should run `cargo check` in order to + * provide inline diagnostics; the user is met with a series of dialog boxes + * that, when accepted, allow us to `cargo install cargo-watch` and then run it. + */ +export async function interactivelyStartCargoWatch() { + const execAsync = util.promisify(exec); + + const watch = await vscode.window.showInformationMessage( + 'Start watching changes with cargo? (Executes `cargo watch`, provides inline diagnostics)', + 'yes', + 'no' + ); + if (watch === 'no') { + return; + } + + const { stderr } = await execAsync('cargo watch --version').catch(e => e); + if (stderr.includes('no such subcommand: `watch`')) { + const msg = + 'The `cargo-watch` subcommand is not installed. Install? (takes ~1-2 minutes)'; + const install = await vscode.window.showInformationMessage( + msg, + 'yes', + 'no' + ); + if (install === 'no') { + return; + } + + const label = 'install-cargo-watch'; + const taskFinished = new Promise((resolve, reject) => { + let disposable = vscode.tasks.onDidEndTask(({ execution }) => { + if (execution.task.name === label) { + disposable.dispose(); + resolve(); + } + }); + }); + + vscode.tasks.executeTask( + createTask({ + label, + bin: 'cargo', + args: ['install', 'cargo-watch'], + env: {} + }) + ); + await taskFinished; + const { stderr } = await execAsync('cargo watch --version').catch( + e => e + ); + if (stderr !== '') { + vscode.window.showErrorMessage( + `Couldn't install \`cargo-\`watch: ${stderr}` + ); + return; + } + } + + vscode.tasks.executeTask(autoCargoWatchTask); +} diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts index f915a5023..2e13c87de 100644 --- a/editors/code/src/extension.ts +++ b/editors/code/src/extension.ts @@ -1,10 +1,8 @@ -import { exec } from 'child_process'; -import * as util from 'util'; import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import * as commands from './commands'; -import { autoCargoWatchTask, createTask } from './commands/runnables'; +import { interactivelyStartCargoWatch } from './commands/runnables'; import { SyntaxTreeContentProvider } from './commands/syntaxTree'; import * as events from './events'; import * as notifications from './notifications'; @@ -122,8 +120,8 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions ); - // Attempts to run `cargo watch`, which provides inline diagnostics on save - askToCargoWatch(); + // Executing `cargo watch` provides us with inline diagnostics on save + interactivelyStartCargoWatch(); // Start the language server, finally! Server.start(allNotifications); @@ -135,61 +133,3 @@ export function deactivate(): Thenable { } return Server.client.stop(); } - -async function askToCargoWatch() { - const watch = await vscode.window.showInformationMessage( - 'Start watching changes with cargo? (Executes `cargo watch`, provides inline diagnostics)', - 'yes', - 'no' - ); - if (watch === 'no') { - return; - } - - const { stderr } = await util - .promisify(exec)('cargo watch --version') - .catch(e => e); - if (stderr.includes('no such subcommand: `watch`')) { - const msg = - 'The `cargo-watch` subcommand is not installed. Install? (takes ~1-2 minutes)'; - const install = await vscode.window.showInformationMessage( - msg, - 'yes', - 'no' - ); - if (install === 'no') { - return; - } - - const label = 'install-cargo-watch'; - const taskFinished = new Promise((resolve, reject) => { - let disposable = vscode.tasks.onDidEndTask(({ execution }) => { - if (execution.task.name === label) { - disposable.dispose(); - resolve(); - } - }); - }); - - vscode.tasks.executeTask( - createTask({ - label, - bin: 'cargo', - args: ['install', 'cargo-watch'], - env: {} - }) - ); - await taskFinished; - const { stderr } = await util - .promisify(exec)('cargo watch --version') - .catch(e => e); - if (stderr !== '') { - vscode.window.showErrorMessage( - `Couldn't install \`cargo-\`watch: ${stderr}` - ); - return; - } - } - - vscode.tasks.executeTask(autoCargoWatchTask); -} -- cgit v1.2.3