aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/code/package.json5
-rw-r--r--editors/code/src/commands/runnables.ts91
-rw-r--r--editors/code/src/config.ts8
-rw-r--r--editors/code/src/extension.ts4
4 files changed, 106 insertions, 2 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index 3834f2847..3e8cde388 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -168,6 +168,11 @@
168 "default": "ra_lsp_server", 168 "default": "ra_lsp_server",
169 "description": "Path to ra_lsp_server executable" 169 "description": "Path to ra_lsp_server executable"
170 }, 170 },
171 "rust-analyzer.enableCargoWatchOnStartup": {
172 "type": "boolean",
173 "default": "true",
174 "description": "When enabled, ask the user whether to run `cargo watch` on startup"
175 },
171 "rust-analyzer.trace.server": { 176 "rust-analyzer.trace.server": {
172 "type": "string", 177 "type": "string",
173 "scope": "window", 178 "scope": "window",
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts
index c0f2ada76..ea2883ad4 100644
--- a/editors/code/src/commands/runnables.ts
+++ b/editors/code/src/commands/runnables.ts
@@ -1,5 +1,8 @@
1import * as child_process from 'child_process';
2import * as util from 'util';
1import * as vscode from 'vscode'; 3import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient'; 4import * as lc from 'vscode-languageclient';
5
3import { Server } from '../server'; 6import { Server } from '../server';
4 7
5interface RunnablesParams { 8interface RunnablesParams {
@@ -8,7 +11,6 @@ interface RunnablesParams {
8} 11}
9 12
10interface Runnable { 13interface Runnable {
11 range: lc.Range;
12 label: string; 14 label: string;
13 bin: string; 15 bin: string;
14 args: string[]; 16 args: string[];
@@ -38,7 +40,7 @@ function createTask(spec: Runnable): vscode.Task {
38 const TASK_SOURCE = 'Rust'; 40 const TASK_SOURCE = 'Rust';
39 const definition: CargoTaskDefinition = { 41 const definition: CargoTaskDefinition = {
40 type: 'cargo', 42 type: 'cargo',
41 label: 'cargo', 43 label: spec.label,
42 command: spec.bin, 44 command: spec.bin,
43 args: spec.args, 45 args: spec.args,
44 env: spec.env 46 env: spec.env
@@ -124,3 +126,88 @@ export async function handleSingle(runnable: Runnable) {
124 126
125 return vscode.tasks.executeTask(task); 127 return vscode.tasks.executeTask(task);
126} 128}
129
130export const autoCargoWatchTask: vscode.Task = {
131 name: 'cargo watch',
132 source: 'rust-analyzer',
133 definition: {
134 type: 'watch'
135 },
136 execution: new vscode.ShellExecution('cargo', ['watch'], { cwd: '.' }),
137
138 isBackground: true,
139 problemMatchers: ['$rustc-watch'],
140 presentationOptions: {
141 clear: true
142 },
143 // Not yet exposed in the vscode.d.ts
144 // https://github.com/Microsoft/vscode/blob/ea7c31d770e04b51d586b0d3944f3a7feb03afb9/src/vs/workbench/contrib/tasks/common/tasks.ts#L444-L456
145 runOptions: ({
146 runOn: 2 // RunOnOptions.folderOpen
147 } as unknown) as vscode.RunOptions
148};
149
150/**
151 * Interactively asks the user whether we should run `cargo check` in order to
152 * provide inline diagnostics; the user is met with a series of dialog boxes
153 * that, when accepted, allow us to `cargo install cargo-watch` and then run it.
154 */
155export async function interactivelyStartCargoWatch() {
156 if (!Server.config.enableCargoWatchOnStartup) {
157 return;
158 }
159
160 const execPromise = util.promisify(child_process.exec);
161
162 const watch = await vscode.window.showInformationMessage(
163 'Start watching changes with cargo? (Executes `cargo watch`, provides inline diagnostics)',
164 'yes',
165 'no'
166 );
167 if (watch === 'no') {
168 return;
169 }
170
171 const { stderr } = await execPromise('cargo watch --version').catch(e => e);
172 if (stderr.includes('no such subcommand: `watch`')) {
173 const msg =
174 'The `cargo-watch` subcommand is not installed. Install? (takes ~1-2 minutes)';
175 const install = await vscode.window.showInformationMessage(
176 msg,
177 'yes',
178 'no'
179 );
180 if (install === 'no') {
181 return;
182 }
183
184 const label = 'install-cargo-watch';
185 const taskFinished = new Promise((resolve, reject) => {
186 const disposable = vscode.tasks.onDidEndTask(({ execution }) => {
187 if (execution.task.name === label) {
188 disposable.dispose();
189 resolve();
190 }
191 });
192 });
193
194 vscode.tasks.executeTask(
195 createTask({
196 label,
197 bin: 'cargo',
198 args: ['install', 'cargo-watch'],
199 env: {}
200 })
201 );
202 await taskFinished;
203 const output = await execPromise('cargo watch --version').catch(e => e);
204 if (output.stderr !== '') {
205 vscode.window.showErrorMessage(
206 `Couldn't install \`cargo-\`watch: ${output.stderr}`
207 );
208 return;
209 }
210 }
211
212 vscode.tasks.executeTask(autoCargoWatchTask);
213}
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index afc5cc6af..d8795f3b0 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -9,6 +9,7 @@ export class Config {
9 public enableEnhancedTyping = true; 9 public enableEnhancedTyping = true;
10 public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server'; 10 public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server';
11 public showWorkspaceLoadedNotification = true; 11 public showWorkspaceLoadedNotification = true;
12 public enableCargoWatchOnStartup = true;
12 13
13 private prevEnhancedTyping: null | boolean = null; 14 private prevEnhancedTyping: null | boolean = null;
14 15
@@ -68,5 +69,12 @@ export class Config {
68 this.raLspServerPath = 69 this.raLspServerPath =
69 RA_LSP_DEBUG || (config.get('raLspServerPath') as string); 70 RA_LSP_DEBUG || (config.get('raLspServerPath') as string);
70 } 71 }
72
73 if (config.has('enableCargoWatchOnStartup')) {
74 this.enableCargoWatchOnStartup = config.get<boolean>(
75 'enableCargoWatchOnStartup',
76 true
77 );
78 }
71 } 79 }
72} 80}
diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts
index 941beba18..2e13c87de 100644
--- a/editors/code/src/extension.ts
+++ b/editors/code/src/extension.ts
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient'; 2import * as lc from 'vscode-languageclient';
3 3
4import * as commands from './commands'; 4import * as commands from './commands';
5import { interactivelyStartCargoWatch } from './commands/runnables';
5import { SyntaxTreeContentProvider } from './commands/syntaxTree'; 6import { SyntaxTreeContentProvider } from './commands/syntaxTree';
6import * as events from './events'; 7import * as events from './events';
7import * as notifications from './notifications'; 8import * as notifications from './notifications';
@@ -119,6 +120,9 @@ export function activate(context: vscode.ExtensionContext) {
119 context.subscriptions 120 context.subscriptions
120 ); 121 );
121 122
123 // Executing `cargo watch` provides us with inline diagnostics on save
124 interactivelyStartCargoWatch();
125
122 // Start the language server, finally! 126 // Start the language server, finally!
123 Server.start(allNotifications); 127 Server.start(allNotifications);
124} 128}