diff options
Diffstat (limited to 'editors/code/src/commands')
-rw-r--r-- | editors/code/src/commands/cargo_watch.ts | 117 | ||||
-rw-r--r-- | editors/code/src/commands/watch_status.ts | 12 |
2 files changed, 83 insertions, 46 deletions
diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index 6d8e4d885..32bd38a1c 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts | |||
@@ -46,12 +46,15 @@ export class CargoWatchProvider { | |||
46 | 'Cargo Watch Trace' | 46 | 'Cargo Watch Trace' |
47 | ); | 47 | ); |
48 | 48 | ||
49 | let args = '"check --message-format json'; | 49 | let args = 'check --message-format json'; |
50 | if (Server.config.cargoWatchOptions.checkArguments.length > 0) { | 50 | if (Server.config.cargoWatchOptions.checkArguments.length > 0) { |
51 | // Excape the double quote string: | 51 | // Excape the double quote string: |
52 | args += ' ' + Server.config.cargoWatchOptions.checkArguments; | 52 | args += ' ' + Server.config.cargoWatchOptions.checkArguments; |
53 | } | 53 | } |
54 | args += '"'; | 54 | // Windows handles arguments differently than the unix-likes, so we need to wrap the args in double quotes |
55 | if (process.platform === 'win32') { | ||
56 | args = '"' + args + '"'; | ||
57 | } | ||
55 | 58 | ||
56 | // Start the cargo watch with json message | 59 | // Start the cargo watch with json message |
57 | this.cargoProcess = child_process.spawn( | 60 | this.cargoProcess = child_process.spawn( |
@@ -68,7 +71,11 @@ export class CargoWatchProvider { | |||
68 | this.cargoProcess.stdout.on('data', (s: string) => { | 71 | this.cargoProcess.stdout.on('data', (s: string) => { |
69 | stdoutData.processOutput(s, line => { | 72 | stdoutData.processOutput(s, line => { |
70 | this.logInfo(line); | 73 | this.logInfo(line); |
71 | this.parseLine(line); | 74 | try { |
75 | this.parseLine(line); | ||
76 | } catch (err) { | ||
77 | this.logError(`Failed to parse: ${err}, content : ${line}`); | ||
78 | } | ||
72 | }); | 79 | }); |
73 | }); | 80 | }); |
74 | 81 | ||
@@ -133,79 +140,99 @@ export class CargoWatchProvider { | |||
133 | if (s === 'error') { | 140 | if (s === 'error') { |
134 | return vscode.DiagnosticSeverity.Error; | 141 | return vscode.DiagnosticSeverity.Error; |
135 | } | 142 | } |
136 | |||
137 | if (s.startsWith('warn')) { | 143 | if (s.startsWith('warn')) { |
138 | return vscode.DiagnosticSeverity.Warning; | 144 | return vscode.DiagnosticSeverity.Warning; |
139 | } | 145 | } |
140 | |||
141 | return vscode.DiagnosticSeverity.Information; | 146 | return vscode.DiagnosticSeverity.Information; |
142 | } | 147 | } |
143 | 148 | ||
144 | interface ErrorSpan { | 149 | // Reference: |
150 | // https://github.com/rust-lang/rust/blob/master/src/libsyntax/json.rs | ||
151 | interface RustDiagnosticSpan { | ||
145 | line_start: number; | 152 | line_start: number; |
146 | line_end: number; | 153 | line_end: number; |
147 | column_start: number; | 154 | column_start: number; |
148 | column_end: number; | 155 | column_end: number; |
156 | is_primary: boolean; | ||
157 | file_name: string; | ||
149 | } | 158 | } |
150 | 159 | ||
151 | interface ErrorMessage { | 160 | interface RustDiagnostic { |
152 | reason: string; | 161 | spans: RustDiagnosticSpan[]; |
153 | message: { | 162 | rendered: string; |
154 | spans: ErrorSpan[]; | 163 | level: string; |
155 | rendered: string; | 164 | code?: { |
156 | level: string; | 165 | code: string; |
157 | code?: { | ||
158 | code: string; | ||
159 | }; | ||
160 | }; | 166 | }; |
161 | } | 167 | } |
162 | 168 | ||
169 | interface CargoArtifact { | ||
170 | reason: string; | ||
171 | package_id: string; | ||
172 | } | ||
173 | |||
174 | // https://github.com/rust-lang/cargo/blob/master/src/cargo/util/machine_message.rs | ||
175 | interface CargoMessage { | ||
176 | reason: string; | ||
177 | package_id: string; | ||
178 | message: RustDiagnostic; | ||
179 | } | ||
180 | |||
163 | // cargo-watch itself output non json format | 181 | // cargo-watch itself output non json format |
164 | // Ignore these lines | 182 | // Ignore these lines |
165 | let data: ErrorMessage; | 183 | let data: CargoMessage; |
166 | try { | 184 | try { |
167 | data = JSON.parse(line.trim()); | 185 | data = JSON.parse(line.trim()); |
168 | } catch (error) { | 186 | } catch (error) { |
169 | this.logError(`Fail to pass to json : { ${error} }`); | 187 | this.logError(`Fail to parse to json : { ${error} }`); |
170 | return; | 188 | return; |
171 | } | 189 | } |
172 | 190 | ||
173 | // Only handle compiler-message now | 191 | if (data.reason === 'compiler-artifact') { |
174 | if (data.reason !== 'compiler-message') { | 192 | const msg = data as CargoArtifact; |
175 | return; | ||
176 | } | ||
177 | 193 | ||
178 | let spans: any[] = data.message.spans; | 194 | // The format of the package_id is "{name} {version} ({source_id})", |
179 | spans = spans.filter(o => o.is_primary); | 195 | // https://github.com/rust-lang/cargo/blob/37ad03f86e895bb80b474c1c088322634f4725f5/src/cargo/core/package_id.rs#L53 |
196 | this.statusDisplay!.packageName = msg.package_id.split(' ')[0]; | ||
197 | } else if (data.reason === 'compiler-message') { | ||
198 | const msg = data.message as RustDiagnostic; | ||
180 | 199 | ||
181 | // We only handle primary span right now. | 200 | const spans = msg.spans.filter(o => o.is_primary); |
182 | if (spans.length > 0) { | ||
183 | const o = spans[0]; | ||
184 | 201 | ||
185 | const rendered = data.message.rendered; | 202 | // We only handle primary span right now. |
186 | const level = getLevel(data.message.level); | 203 | if (spans.length > 0) { |
187 | const range = new vscode.Range( | 204 | const o = spans[0]; |
188 | new vscode.Position(o.line_start - 1, o.column_start - 1), | 205 | |
189 | new vscode.Position(o.line_end - 1, o.column_end - 1) | 206 | const rendered = msg.rendered; |
190 | ); | 207 | const level = getLevel(msg.level); |
208 | const range = new vscode.Range( | ||
209 | new vscode.Position(o.line_start - 1, o.column_start - 1), | ||
210 | new vscode.Position(o.line_end - 1, o.column_end - 1) | ||
211 | ); | ||
191 | 212 | ||
192 | const fileName = path.join(vscode.workspace.rootPath!, o.file_name); | 213 | const fileName = path.join( |
193 | const diagnostic = new vscode.Diagnostic(range, rendered, level); | 214 | vscode.workspace.rootPath!, |
215 | o.file_name | ||
216 | ); | ||
217 | const diagnostic = new vscode.Diagnostic( | ||
218 | range, | ||
219 | rendered, | ||
220 | level | ||
221 | ); | ||
194 | 222 | ||
195 | diagnostic.source = 'rustc'; | 223 | diagnostic.source = 'rustc'; |
196 | diagnostic.code = data.message.code | 224 | diagnostic.code = msg.code ? msg.code.code : undefined; |
197 | ? data.message.code.code | 225 | diagnostic.relatedInformation = []; |
198 | : undefined; | ||
199 | diagnostic.relatedInformation = []; | ||
200 | 226 | ||
201 | const fileUrl = vscode.Uri.file(fileName!); | 227 | const fileUrl = vscode.Uri.file(fileName!); |
202 | 228 | ||
203 | const diagnostics: vscode.Diagnostic[] = [ | 229 | const diagnostics: vscode.Diagnostic[] = [ |
204 | ...(this.diagnosticCollection!.get(fileUrl) || []) | 230 | ...(this.diagnosticCollection!.get(fileUrl) || []) |
205 | ]; | 231 | ]; |
206 | diagnostics.push(diagnostic); | 232 | diagnostics.push(diagnostic); |
207 | 233 | ||
208 | this.diagnosticCollection!.set(fileUrl, diagnostics); | 234 | this.diagnosticCollection!.set(fileUrl, diagnostics); |
235 | } | ||
209 | } | 236 | } |
210 | } | 237 | } |
211 | } | 238 | } |
diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts index f027d7bbc..86ae821de 100644 --- a/editors/code/src/commands/watch_status.ts +++ b/editors/code/src/commands/watch_status.ts | |||
@@ -3,6 +3,8 @@ import * as vscode from 'vscode'; | |||
3 | const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; | 3 | const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; |
4 | 4 | ||
5 | export class StatusDisplay { | 5 | export class StatusDisplay { |
6 | public packageName?: string; | ||
7 | |||
6 | private i = 0; | 8 | private i = 0; |
7 | private statusBarItem: vscode.StatusBarItem; | 9 | private statusBarItem: vscode.StatusBarItem; |
8 | private timer?: NodeJS.Timeout; | 10 | private timer?: NodeJS.Timeout; |
@@ -17,10 +19,18 @@ export class StatusDisplay { | |||
17 | } | 19 | } |
18 | 20 | ||
19 | public show() { | 21 | public show() { |
22 | this.packageName = undefined; | ||
23 | |||
20 | this.timer = | 24 | this.timer = |
21 | this.timer || | 25 | this.timer || |
22 | setInterval(() => { | 26 | setInterval(() => { |
23 | this.statusBarItem!.text = 'cargo check ' + this.frame(); | 27 | if (this.packageName) { |
28 | this.statusBarItem!.text = `cargo check [${ | ||
29 | this.packageName | ||
30 | }] ${this.frame()}`; | ||
31 | } else { | ||
32 | this.statusBarItem!.text = `cargo check ${this.frame()}`; | ||
33 | } | ||
24 | }, 300); | 34 | }, 300); |
25 | 35 | ||
26 | this.statusBarItem!.show(); | 36 | this.statusBarItem!.show(); |