]> git.lizzy.rs Git - rust.git/commitdiff
Ask the user to install and start cargo watch
authorIgor Matuszewski <Xanewok@gmail.com>
Mon, 18 Mar 2019 19:50:52 +0000 (20:50 +0100)
committerIgor Matuszewski <Xanewok@gmail.com>
Mon, 18 Mar 2019 19:50:52 +0000 (20:50 +0100)
editors/code/src/extension.ts

index 941beba180733704e450cf9b62e60c9e5d39d9fe..d5b496b1b3f3eb8b669ce761bd4089354510c3b7 100644 (file)
@@ -1,11 +1,15 @@
+import { exec, spawn } 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 { SyntaxTreeContentProvider } from './commands/syntaxTree';
 import * as events from './events';
 import * as notifications from './notifications';
 import { Server } from './server';
+import { TextDecoder } from 'util';
 
 export function activate(context: vscode.ExtensionContext) {
     function disposeOnDeactivation(disposable: vscode.Disposable) {
@@ -89,11 +93,11 @@ export function activate(context: vscode.ExtensionContext) {
     const allNotifications: Iterable<
         [string, lc.GenericNotificationHandler]
     > = [
-        [
-            'rust-analyzer/publishDecorations',
-            notifications.publishDecorations.handle
-        ]
-    ];
+            [
+                'rust-analyzer/publishDecorations',
+                notifications.publishDecorations.handle
+            ]
+        ];
     const syntaxTreeContentProvider = new SyntaxTreeContentProvider();
 
     // The events below are plain old javascript events, triggered and handled by vscode
@@ -119,6 +123,9 @@ export function activate(context: vscode.ExtensionContext) {
         context.subscriptions
     );
 
+    // Attempts to run `cargo watch`, which provides inline diagnostics on save
+    askToCargoWatch();
+
     // Start the language server, finally!
     Server.start(allNotifications);
 }
@@ -129,3 +136,52 @@ export function deactivate(): Thenable<void> {
     }
     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;
+        }
+
+        try {
+            // await vscode.tasks.executeTask(createTask({label: '', bin: 'cargo', args: ['install', 'cargo-watch'], env: {}}));
+
+            const channel = vscode.window.createOutputChannel('cargo-watch');
+            channel.show(false);
+            const sup = spawn('cargo', ['install', 'cargo-watch']);
+            sup.stderr.on('data', chunk => {
+                const output = new TextDecoder().decode(chunk);
+                channel.append(output);
+            });
+            await new Promise((resolve, reject) => {
+                sup.on('close', (code, signal) => {
+                    if (code === 0) {
+                        resolve(code);
+                    } else {
+                        reject(code);
+                    }
+                });
+            });
+            channel.dispose();
+        } catch (err) {
+            vscode.window.showErrorMessage(
+                `Couldn't install \`cargo-watch\`: ${err.message}`
+            );
+            return;
+        }
+    }
+
+    vscode.tasks.executeTask(autoCargoWatchTask);
+}