diff options
Diffstat (limited to 'editors/code/src/commands')
-rw-r--r-- | editors/code/src/commands/runnables.ts | 91 |
1 files changed, 89 insertions, 2 deletions
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 @@ | |||
1 | import * as child_process from 'child_process'; | ||
2 | import * as util from 'util'; | ||
1 | import * as vscode from 'vscode'; | 3 | import * as vscode from 'vscode'; |
2 | import * as lc from 'vscode-languageclient'; | 4 | import * as lc from 'vscode-languageclient'; |
5 | |||
3 | import { Server } from '../server'; | 6 | import { Server } from '../server'; |
4 | 7 | ||
5 | interface RunnablesParams { | 8 | interface RunnablesParams { |
@@ -8,7 +11,6 @@ interface RunnablesParams { | |||
8 | } | 11 | } |
9 | 12 | ||
10 | interface Runnable { | 13 | interface 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 | |||
130 | export 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 | */ | ||
155 | export 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 | } | ||