Merge #995
995: Install and run `cargo watch` if user agrees r=matklad a=Xanewok
This isn't a glorious patch but hopefully is useful 👍 This introduces a default background `cargo watch` task and (separately from that) asks the user on every startup if they want to run `cargo watch` (installs it if it's not available).
r? @matklad does it fit the what you've been thinking about?
Co-authored-by: Igor Matuszewski <xanewok@gmail.com>
This commit is contained in:
commit
91576afc7e
@ -168,6 +168,11 @@
|
||||
"default": "ra_lsp_server",
|
||||
"description": "Path to ra_lsp_server executable"
|
||||
},
|
||||
"rust-analyzer.enableCargoWatchOnStartup": {
|
||||
"type": "boolean",
|
||||
"default": "true",
|
||||
"description": "When enabled, ask the user whether to run `cargo watch` on startup"
|
||||
},
|
||||
"rust-analyzer.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
|
@ -1,5 +1,8 @@
|
||||
import * as child_process 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 {
|
||||
@ -8,7 +11,6 @@ interface RunnablesParams {
|
||||
}
|
||||
|
||||
interface Runnable {
|
||||
range: lc.Range;
|
||||
label: string;
|
||||
bin: string;
|
||||
args: string[];
|
||||
@ -38,7 +40,7 @@ function createTask(spec: Runnable): vscode.Task {
|
||||
const TASK_SOURCE = 'Rust';
|
||||
const definition: CargoTaskDefinition = {
|
||||
type: 'cargo',
|
||||
label: 'cargo',
|
||||
label: spec.label,
|
||||
command: spec.bin,
|
||||
args: spec.args,
|
||||
env: spec.env
|
||||
@ -124,3 +126,88 @@ export async function handleSingle(runnable: Runnable) {
|
||||
|
||||
return vscode.tasks.executeTask(task);
|
||||
}
|
||||
|
||||
export const autoCargoWatchTask: vscode.Task = {
|
||||
name: 'cargo watch',
|
||||
source: 'rust-analyzer',
|
||||
definition: {
|
||||
type: 'watch'
|
||||
},
|
||||
execution: new vscode.ShellExecution('cargo', ['watch'], { cwd: '.' }),
|
||||
|
||||
isBackground: true,
|
||||
problemMatchers: ['$rustc-watch'],
|
||||
presentationOptions: {
|
||||
clear: true
|
||||
},
|
||||
// Not yet exposed in the vscode.d.ts
|
||||
// https://github.com/Microsoft/vscode/blob/ea7c31d770e04b51d586b0d3944f3a7feb03afb9/src/vs/workbench/contrib/tasks/common/tasks.ts#L444-L456
|
||||
runOptions: ({
|
||||
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() {
|
||||
if (!Server.config.enableCargoWatchOnStartup) {
|
||||
return;
|
||||
}
|
||||
|
||||
const execPromise = util.promisify(child_process.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 execPromise('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) => {
|
||||
const 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 output = await execPromise('cargo watch --version').catch(e => e);
|
||||
if (output.stderr !== '') {
|
||||
vscode.window.showErrorMessage(
|
||||
`Couldn't install \`cargo-\`watch: ${output.stderr}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vscode.tasks.executeTask(autoCargoWatchTask);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ export class Config {
|
||||
public enableEnhancedTyping = true;
|
||||
public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server';
|
||||
public showWorkspaceLoadedNotification = true;
|
||||
public enableCargoWatchOnStartup = true;
|
||||
|
||||
private prevEnhancedTyping: null | boolean = null;
|
||||
|
||||
@ -68,5 +69,12 @@ export class Config {
|
||||
this.raLspServerPath =
|
||||
RA_LSP_DEBUG || (config.get('raLspServerPath') as string);
|
||||
}
|
||||
|
||||
if (config.has('enableCargoWatchOnStartup')) {
|
||||
this.enableCargoWatchOnStartup = config.get<boolean>(
|
||||
'enableCargoWatchOnStartup',
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
|
||||
import * as commands from './commands';
|
||||
import { interactivelyStartCargoWatch } from './commands/runnables';
|
||||
import { SyntaxTreeContentProvider } from './commands/syntaxTree';
|
||||
import * as events from './events';
|
||||
import * as notifications from './notifications';
|
||||
@ -119,6 +120,9 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions
|
||||
);
|
||||
|
||||
// Executing `cargo watch` provides us with inline diagnostics on save
|
||||
interactivelyStartCargoWatch();
|
||||
|
||||
// Start the language server, finally!
|
||||
Server.start(allNotifications);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user