From b3683df0cd67ca97c83f5a7ea58a780dbe4e1b8e Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 31 Mar 2019 20:00:50 +0800 Subject: Improve cargo-watch usage --- editors/code/package.json | 12 --- editors/code/src/commands/cargo_watch.ts | 168 +++++++++++++++++++++++++++++++ editors/code/src/commands/runnables.ts | 29 ++---- editors/code/src/extension.ts | 4 +- 4 files changed, 177 insertions(+), 36 deletions(-) create mode 100644 editors/code/src/commands/cargo_watch.ts diff --git a/editors/code/package.json b/editors/code/package.json index facb633d9..240aff6c9 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -223,18 +223,6 @@ "${workspaceRoot}" ], "pattern": "$rustc" - }, - { - "name": "rustc-watch", - "fileLocation": [ - "relative", - "${workspaceRoot}" - ], - "background": { - "beginsPattern": "^\\[Running\\b", - "endsPattern": "^\\[Finished running\\b" - }, - "pattern": "$rustc" } ] } diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts new file mode 100644 index 000000000..55a1909cb --- /dev/null +++ b/editors/code/src/commands/cargo_watch.ts @@ -0,0 +1,168 @@ +import * as child_process from 'child_process'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { setInterval } from 'timers'; + +const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; + +class StatusDisplay { + private i = 0; + private statusBarItem: vscode.StatusBarItem; + private timer?: NodeJS.Timeout; + + constructor(subscriptions: vscode.Disposable[]) { + this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10); + subscriptions.push(this.statusBarItem); + this.statusBarItem.hide(); + } + + public show() { + this.timer = this.timer || setInterval(() => { + this.statusBarItem!.text = "cargo check " + this.frame(); + }, 300); + + this.statusBarItem!.show(); + } + + public hide() { + if(this.timer) { + clearInterval(this.timer); + this.timer = undefined; + } + + this.statusBarItem!.hide(); + } + + frame() { + return spinnerFrames[this.i = ++this.i % spinnerFrames.length]; + } +} + +export class CargoWatchProvider { + private diagnosticCollection?: vscode.DiagnosticCollection; + private cargoProcess?: child_process.ChildProcess; + private outBuffer: string = ""; + private statusDisplay? : StatusDisplay; + + constructor() { + } + + public activate(subscriptions: vscode.Disposable[]) { + subscriptions.push(this); + this.diagnosticCollection = vscode.languages.createDiagnosticCollection("rustc"); + + this.statusDisplay = new StatusDisplay(subscriptions); + + // Start the cargo watch with json message + this.cargoProcess = child_process.spawn('cargo', + ["watch", "-x", "\"check --message-format json\""], + { + // stdio: ['ignore', 'pipe', 'ignore'], + shell: true, + cwd: vscode.workspace.rootPath, + }); + + + this.cargoProcess.stdout.on('data', (s: string) => { + this.processOutput(s); + }); + + this.cargoProcess.stderr.on('data', (s: string) => { + console.error('Error on cargo watch : ' + s); + }); + + this.cargoProcess.on('error', (err: Error) => { + console.error('Error on spawn cargo process : ' + err); + }); + } + + public dispose(): void { + if (this.diagnosticCollection) { + this.diagnosticCollection.clear(); + this.diagnosticCollection.dispose(); + } + + if (this.cargoProcess) { + this.cargoProcess.kill(); + } + } + + parseLine(line: string) { + if (line.startsWith("[Running")) { + this.diagnosticCollection!.clear(); + this.statusDisplay!.show(); + } + + if (line.startsWith("[Finished running")) { + this.statusDisplay!.hide(); + } + + function getLevel(s: string): vscode.DiagnosticSeverity { + if (s === "error") + return vscode.DiagnosticSeverity.Error; + + if (s.startsWith("warn")) + return vscode.DiagnosticSeverity.Warning; + + return vscode.DiagnosticSeverity.Information; + } + + // cargo-watch itself output non json format + // Ignore these lines + let data = null; + try { + data = JSON.parse(line.trim()); + } catch (error) { + return; + } + + // Only handle compiler-message now + if (data.reason !== "compiler-message") { + return; + } + + let spans: any[] = data.message.spans; + spans = spans.filter(o => o.is_primary); + let file_name = null; + + // We only handle primary span right now. + if (spans.length > 0) { + let o = spans[0]; + + console.log("o", o); + let rendered = data.message.rendered; + let level = getLevel(data.message.level); + let range = new vscode.Range( + new vscode.Position(o.line_start - 1, o.column_start - 1), + new vscode.Position(o.line_end - 1, o.column_end - 1) + ); + + file_name = path.join(vscode.workspace.rootPath!, o.file_name); + const diagnostic = new vscode.Diagnostic(range, rendered, level); + + diagnostic.source = 'rustc'; + diagnostic.code = data.message.code.code; + diagnostic.relatedInformation = []; + + let fileUrl = vscode.Uri.file(file_name!); + + let diagnostics: vscode.Diagnostic[] = [...(this.diagnosticCollection!.get(fileUrl) || [])]; + diagnostics.push(diagnostic); + + this.diagnosticCollection!.set(fileUrl, diagnostics); + } + } + + processOutput(chunk: string) { + // The stdout is not line based, convert it to line based for proceess. + this.outBuffer += chunk; + let eolIndex; + while ((eolIndex = this.outBuffer.indexOf('\n')) >= 0) { + // line includes the EOL + const line = this.outBuffer.slice(0, eolIndex + 1); + this.parseLine(line); + this.outBuffer = this.outBuffer.slice(eolIndex + 1); + } + } + +} diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 4187ef4d1..722db158a 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -1,9 +1,11 @@ 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'; +import { CargoWatchProvider } from './cargo_watch'; interface RunnablesParams { textDocument: lc.TextDocumentIdentifier; @@ -127,32 +129,13 @@ 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() { +export async function interactivelyStartCargoWatch(context: vscode.ExtensionContext) { + if (Server.config.enableCargoWatchOnStartup === 'disabled') { return; } @@ -212,5 +195,7 @@ export async function interactivelyStartCargoWatch() { } } - vscode.tasks.executeTask(autoCargoWatchTask); + + let validater = new CargoWatchProvider(); + validater.activate(context.subscriptions); } diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts index 2e13c87de..5cbf285e5 100644 --- a/editors/code/src/extension.ts +++ b/editors/code/src/extension.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import * as commands from './commands'; -import { interactivelyStartCargoWatch } from './commands/runnables'; +import { interactivelyStartCargoWatch} from './commands/runnables'; import { SyntaxTreeContentProvider } from './commands/syntaxTree'; import * as events from './events'; import * as notifications from './notifications'; @@ -121,7 +121,7 @@ export function activate(context: vscode.ExtensionContext) { ); // Executing `cargo watch` provides us with inline diagnostics on save - interactivelyStartCargoWatch(); + interactivelyStartCargoWatch(context); // Start the language server, finally! Server.start(allNotifications); -- cgit v1.2.3 From ac8f35019bd6224a0c2b085381dde2efc8888dc1 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 31 Mar 2019 20:51:17 +0800 Subject: Fix tslint error --- editors/code/src/commands/cargo_watch.ts | 91 ++++++++++--------------------- editors/code/src/commands/watch_status.ts | 37 +++++++++++++ 2 files changed, 65 insertions(+), 63 deletions(-) create mode 100644 editors/code/src/commands/watch_status.ts diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index 55a1909cb..c6ce6ba06 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -1,61 +1,24 @@ import * as child_process from 'child_process'; import * as path from 'path'; +import * as timers from 'timers'; import * as vscode from 'vscode'; -import { setInterval } from 'timers'; - -const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; - -class StatusDisplay { - private i = 0; - private statusBarItem: vscode.StatusBarItem; - private timer?: NodeJS.Timeout; - - constructor(subscriptions: vscode.Disposable[]) { - this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10); - subscriptions.push(this.statusBarItem); - this.statusBarItem.hide(); - } - - public show() { - this.timer = this.timer || setInterval(() => { - this.statusBarItem!.text = "cargo check " + this.frame(); - }, 300); - - this.statusBarItem!.show(); - } - - public hide() { - if(this.timer) { - clearInterval(this.timer); - this.timer = undefined; - } - - this.statusBarItem!.hide(); - } - - frame() { - return spinnerFrames[this.i = ++this.i % spinnerFrames.length]; - } -} +import {StatusDisplay} from './watch_status'; export class CargoWatchProvider { private diagnosticCollection?: vscode.DiagnosticCollection; private cargoProcess?: child_process.ChildProcess; - private outBuffer: string = ""; - private statusDisplay? : StatusDisplay; - - constructor() { - } + private outBuffer: string = ''; + private statusDisplay?: StatusDisplay; public activate(subscriptions: vscode.Disposable[]) { subscriptions.push(this); - this.diagnosticCollection = vscode.languages.createDiagnosticCollection("rustc"); + this.diagnosticCollection = vscode.languages.createDiagnosticCollection('rustc'); this.statusDisplay = new StatusDisplay(subscriptions); // Start the cargo watch with json message this.cargoProcess = child_process.spawn('cargo', - ["watch", "-x", "\"check --message-format json\""], + ['watch', '-x', '\"check --message-format json\"'], { // stdio: ['ignore', 'pipe', 'ignore'], shell: true, @@ -68,11 +31,11 @@ export class CargoWatchProvider { }); this.cargoProcess.stderr.on('data', (s: string) => { - console.error('Error on cargo watch : ' + s); + // console.error('Error on cargo watch : ' + s); }); this.cargoProcess.on('error', (err: Error) => { - console.error('Error on spawn cargo process : ' + err); + // console.error('Error on spawn cargo process : ' + err); }); } @@ -87,22 +50,24 @@ export class CargoWatchProvider { } } - parseLine(line: string) { - if (line.startsWith("[Running")) { + private parseLine(line: string) { + if (line.startsWith('[Running')) { this.diagnosticCollection!.clear(); this.statusDisplay!.show(); } - if (line.startsWith("[Finished running")) { + if (line.startsWith('[Finished running')) { this.statusDisplay!.hide(); } function getLevel(s: string): vscode.DiagnosticSeverity { - if (s === "error") + if (s === 'error') { return vscode.DiagnosticSeverity.Error; + } - if (s.startsWith("warn")) + if (s.startsWith('warn')) { return vscode.DiagnosticSeverity.Warning; + } return vscode.DiagnosticSeverity.Information; } @@ -117,51 +82,51 @@ export class CargoWatchProvider { } // Only handle compiler-message now - if (data.reason !== "compiler-message") { + if (data.reason !== 'compiler-message') { return; } let spans: any[] = data.message.spans; spans = spans.filter(o => o.is_primary); - let file_name = null; // We only handle primary span right now. if (spans.length > 0) { - let o = spans[0]; + const o = spans[0]; - console.log("o", o); - let rendered = data.message.rendered; - let level = getLevel(data.message.level); - let range = new vscode.Range( + const rendered = data.message.rendered; + const level = getLevel(data.message.level); + const range = new vscode.Range( new vscode.Position(o.line_start - 1, o.column_start - 1), new vscode.Position(o.line_end - 1, o.column_end - 1) ); - file_name = path.join(vscode.workspace.rootPath!, o.file_name); + const fileName = path.join(vscode.workspace.rootPath!, o.file_name); const diagnostic = new vscode.Diagnostic(range, rendered, level); diagnostic.source = 'rustc'; diagnostic.code = data.message.code.code; diagnostic.relatedInformation = []; - let fileUrl = vscode.Uri.file(file_name!); + const fileUrl = vscode.Uri.file(fileName!); - let diagnostics: vscode.Diagnostic[] = [...(this.diagnosticCollection!.get(fileUrl) || [])]; + const diagnostics: vscode.Diagnostic[] = [...(this.diagnosticCollection!.get(fileUrl) || [])]; diagnostics.push(diagnostic); this.diagnosticCollection!.set(fileUrl, diagnostics); } } - processOutput(chunk: string) { + private processOutput(chunk: string) { // The stdout is not line based, convert it to line based for proceess. this.outBuffer += chunk; - let eolIndex; - while ((eolIndex = this.outBuffer.indexOf('\n')) >= 0) { + let eolIndex = this.outBuffer.indexOf('\n'); + while (eolIndex >= 0) { // line includes the EOL const line = this.outBuffer.slice(0, eolIndex + 1); this.parseLine(line); this.outBuffer = this.outBuffer.slice(eolIndex + 1); + + eolIndex = this.outBuffer.indexOf('\n'); } } diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts new file mode 100644 index 000000000..0943e8533 --- /dev/null +++ b/editors/code/src/commands/watch_status.ts @@ -0,0 +1,37 @@ +import * as timers from 'timers'; +import * as vscode from 'vscode'; + +const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; + +export class StatusDisplay { + private i = 0; + private statusBarItem: vscode.StatusBarItem; + private timer?: NodeJS.Timeout; + + constructor(subscriptions: vscode.Disposable[]) { + this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10); + subscriptions.push(this.statusBarItem); + this.statusBarItem.hide(); + } + + public show() { + this.timer = this.timer || setInterval(() => { + this.statusBarItem!.text = 'cargo check ' + this.frame(); + }, 300); + + this.statusBarItem!.show(); + } + + public hide() { + if (this.timer) { + clearInterval(this.timer); + this.timer = undefined; + } + + this.statusBarItem!.hide(); + } + + private frame() { + return spinnerFrames[this.i = ++this.i % spinnerFrames.length]; + } +} \ No newline at end of file -- cgit v1.2.3 From 6971c7f1185fb7c1c0ce5f19867b999de71b5937 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 31 Mar 2019 21:01:51 +0800 Subject: Fixed tslint error --- editors/code/src/commands/runnables.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 722db158a..0adb85d5f 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -196,6 +196,6 @@ export async function interactivelyStartCargoWatch(context: vscode.ExtensionCont } - let validater = new CargoWatchProvider(); + const validater = new CargoWatchProvider(); validater.activate(context.subscriptions); } -- cgit v1.2.3 From c894a3e19b0e658622a03a7d0539a78a433b42ae Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 31 Mar 2019 21:21:14 +0800 Subject: Fix prettier error --- editors/code/src/commands/cargo_watch.ts | 26 +++++++++++++++----------- editors/code/src/commands/runnables.ts | 8 ++++---- editors/code/src/commands/watch_status.ts | 17 +++++++++++------ editors/code/src/extension.ts | 2 +- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index c6ce6ba06..037f1e302 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -2,7 +2,7 @@ import * as child_process from 'child_process'; import * as path from 'path'; import * as timers from 'timers'; import * as vscode from 'vscode'; -import {StatusDisplay} from './watch_status'; +import { StatusDisplay } from './watch_status'; export class CargoWatchProvider { private diagnosticCollection?: vscode.DiagnosticCollection; @@ -12,19 +12,22 @@ export class CargoWatchProvider { public activate(subscriptions: vscode.Disposable[]) { subscriptions.push(this); - this.diagnosticCollection = vscode.languages.createDiagnosticCollection('rustc'); + this.diagnosticCollection = vscode.languages.createDiagnosticCollection( + 'rustc' + ); this.statusDisplay = new StatusDisplay(subscriptions); - // Start the cargo watch with json message - this.cargoProcess = child_process.spawn('cargo', - ['watch', '-x', '\"check --message-format json\"'], + // Start the cargo watch with json message + this.cargoProcess = child_process.spawn( + 'cargo', + ['watch', '-x', '"check --message-format json"'], { - // stdio: ['ignore', 'pipe', 'ignore'], + // stdio: ['ignore', 'pipe', 'ignore'], shell: true, - cwd: vscode.workspace.rootPath, - }); - + cwd: vscode.workspace.rootPath + } + ); this.cargoProcess.stdout.on('data', (s: string) => { this.processOutput(s); @@ -109,7 +112,9 @@ export class CargoWatchProvider { const fileUrl = vscode.Uri.file(fileName!); - const diagnostics: vscode.Diagnostic[] = [...(this.diagnosticCollection!.get(fileUrl) || [])]; + const diagnostics: vscode.Diagnostic[] = [ + ...(this.diagnosticCollection!.get(fileUrl) || []) + ]; diagnostics.push(diagnostic); this.diagnosticCollection!.set(fileUrl, diagnostics); @@ -129,5 +134,4 @@ export class CargoWatchProvider { eolIndex = this.outBuffer.indexOf('\n'); } } - } diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 0adb85d5f..7bba6f9cb 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -134,8 +134,9 @@ export async function handleSingle(runnable: Runnable) { * 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(context: vscode.ExtensionContext) { - +export async function interactivelyStartCargoWatch( + context: vscode.ExtensionContext +) { if (Server.config.enableCargoWatchOnStartup === 'disabled') { return; } @@ -195,7 +196,6 @@ export async function interactivelyStartCargoWatch(context: vscode.ExtensionCont } } - const validater = new CargoWatchProvider(); - validater.activate(context.subscriptions); + validater.activate(context.subscriptions); } diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts index 0943e8533..1b0611ce3 100644 --- a/editors/code/src/commands/watch_status.ts +++ b/editors/code/src/commands/watch_status.ts @@ -9,15 +9,20 @@ export class StatusDisplay { private timer?: NodeJS.Timeout; constructor(subscriptions: vscode.Disposable[]) { - this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10); + this.statusBarItem = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Left, + 10 + ); subscriptions.push(this.statusBarItem); this.statusBarItem.hide(); } public show() { - this.timer = this.timer || setInterval(() => { - this.statusBarItem!.text = 'cargo check ' + this.frame(); - }, 300); + this.timer = + this.timer || + setInterval(() => { + this.statusBarItem!.text = 'cargo check ' + this.frame(); + }, 300); this.statusBarItem!.show(); } @@ -32,6 +37,6 @@ export class StatusDisplay { } private frame() { - return spinnerFrames[this.i = ++this.i % spinnerFrames.length]; + return spinnerFrames[(this.i = ++this.i % spinnerFrames.length)]; } -} \ No newline at end of file +} diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts index 5cbf285e5..ef83c0b8b 100644 --- a/editors/code/src/extension.ts +++ b/editors/code/src/extension.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import * as commands from './commands'; -import { interactivelyStartCargoWatch} from './commands/runnables'; +import { interactivelyStartCargoWatch } from './commands/runnables'; import { SyntaxTreeContentProvider } from './commands/syntaxTree'; import * as events from './events'; import * as notifications from './notifications'; -- cgit v1.2.3 From b84d0fc1a307f6103ea2c2620a106db821696434 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 01:11:22 +0800 Subject: Add proper process teminate method --- editors/code/package-lock.json | 51 ++++++++++++++++++++++++++++++ editors/code/package.json | 5 +-- editors/code/src/commands/cargo_watch.ts | 17 ++++++---- editors/code/src/commands/watch_status.ts | 1 - editors/code/src/utils/processes.ts | 40 +++++++++++++++++++++++ editors/code/src/utils/terminateProcess.sh | 12 +++++++ 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 editors/code/src/utils/processes.ts create mode 100644 editors/code/src/utils/terminateProcess.sh diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index 5a0d21e78..008df6f52 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json @@ -607,6 +607,12 @@ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1121,6 +1127,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, "is": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", @@ -1791,6 +1803,15 @@ "util-deprecate": "^1.0.1" } }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, "remove-bom-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", @@ -1902,6 +1923,36 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shx": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.2.tgz", + "integrity": "sha512-aS0mWtW3T2sHAenrSrip2XGv39O9dXIFUqxAEWHEOS1ePtGIBavdPJY1kE2IHl14V/4iCbUiNDPGdyYTtmhSoA==", + "dev": true, + "requires": { + "es6-object-assign": "^1.0.3", + "minimist": "^1.2.0", + "shelljs": "^0.8.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/editors/code/package.json b/editors/code/package.json index 240aff6c9..ba9c9433a 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -18,7 +18,7 @@ "scripts": { "vscode:prepublish": "npm run compile", "package": "vsce package", - "compile": "tsc -p ./", + "compile": "tsc -p ./ && shx cp src/utils/terminateProcess.sh out/utils/terminateProcess.sh", "watch": "tsc -watch -p ./", "postinstall": "node ./node_modules/vscode/bin/install", "fix": "prettier **/*.{json,ts} --write && tslint --project . --fix", @@ -41,7 +41,8 @@ "tslint-config-prettier": "^1.18.0", "typescript": "^3.3.1", "vsce": "^1.57.0", - "vscode": "^1.1.29" + "vscode": "^1.1.29", + "shx": "^0.3.1" }, "activationEvents": [ "onLanguage:rust", diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index 037f1e302..e51cac78a 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -1,9 +1,10 @@ import * as child_process from 'child_process'; import * as path from 'path'; -import * as timers from 'timers'; import * as vscode from 'vscode'; +import { terminate } from '../utils/processes'; import { StatusDisplay } from './watch_status'; + export class CargoWatchProvider { private diagnosticCollection?: vscode.DiagnosticCollection; private cargoProcess?: child_process.ChildProcess; @@ -21,24 +22,25 @@ export class CargoWatchProvider { // Start the cargo watch with json message this.cargoProcess = child_process.spawn( 'cargo', - ['watch', '-x', '"check --message-format json"'], + ['watch', '-x', '\"check --message-format json\"'], { - // stdio: ['ignore', 'pipe', 'ignore'], - shell: true, - cwd: vscode.workspace.rootPath + stdio: ['ignore', 'pipe', 'pipe'], + cwd: vscode.workspace.rootPath, + windowsVerbatimArguments: true, } ); this.cargoProcess.stdout.on('data', (s: string) => { this.processOutput(s); + console.log(s); }); this.cargoProcess.stderr.on('data', (s: string) => { - // console.error('Error on cargo watch : ' + s); + console.error('Error on cargo watch : ' + s); }); this.cargoProcess.on('error', (err: Error) => { - // console.error('Error on spawn cargo process : ' + err); + console.error('Error on spawn cargo process : ' + err); }); } @@ -50,6 +52,7 @@ export class CargoWatchProvider { if (this.cargoProcess) { this.cargoProcess.kill(); + terminate(this.cargoProcess); } } diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts index 1b0611ce3..f027d7bbc 100644 --- a/editors/code/src/commands/watch_status.ts +++ b/editors/code/src/commands/watch_status.ts @@ -1,4 +1,3 @@ -import * as timers from 'timers'; import * as vscode from 'vscode'; const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; diff --git a/editors/code/src/utils/processes.ts b/editors/code/src/utils/processes.ts new file mode 100644 index 000000000..09fdf6e24 --- /dev/null +++ b/editors/code/src/utils/processes.ts @@ -0,0 +1,40 @@ +'use strict'; + +import * as cp from 'child_process'; +import ChildProcess = cp.ChildProcess; + +import { join } from 'path'; + +const isWindows = (process.platform === 'win32'); +const isMacintosh = (process.platform === 'darwin'); +const isLinux = (process.platform === 'linux'); +export function terminate(process: ChildProcess, cwd?: string): boolean { + if (isWindows) { + try { + // This we run in Atom execFileSync is available. + // Ignore stderr since this is otherwise piped to parent.stderr + // which might be already closed. + const options: any = { + stdio: ['pipe', 'pipe', 'ignore'] + }; + if (cwd) { + options.cwd = cwd + } + (cp).execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options); + return true; + } catch (err) { + return false; + } + } else if (isLinux || isMacintosh) { + try { + const cmd = join(__dirname, 'terminateProcess.sh'); + const result = cp.spawnSync(cmd, [process.pid.toString()]); + return result.error ? false : true; + } catch (err) { + return false; + } + } else { + process.kill('SIGKILL'); + return true; + } +} \ No newline at end of file diff --git a/editors/code/src/utils/terminateProcess.sh b/editors/code/src/utils/terminateProcess.sh new file mode 100644 index 000000000..2ec9e1c2e --- /dev/null +++ b/editors/code/src/utils/terminateProcess.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +terminateTree() { + for cpid in $(pgrep -P $1); do + terminateTree $cpid + done + kill -9 $1 > /dev/null 2>&1 +} + +for pid in $*; do + terminateTree $pid +done \ No newline at end of file -- cgit v1.2.3 From ee05eafe6c657c3d3710655e11d88d61bc5febf0 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 13:07:40 +0800 Subject: Add config for cargo-watch trace --- docs/user/README.md | 1 + editors/code/package.json | 11 +++++++++ editors/code/src/commands/cargo_watch.ts | 41 ++++++++++++++++++++++++++------ editors/code/src/commands/runnables.ts | 4 ++-- editors/code/src/config.ts | 25 ++++++++++++++----- 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/docs/user/README.md b/docs/user/README.md index 439c4e6ae..722a86c9b 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -60,6 +60,7 @@ for details. * `rust-analyzer.enableCargoWatchOnStartup`: prompt to install & enable `cargo watch` for live error highlighting (note, this **does not** use rust-analyzer) * `rust-analyzer.trace.server`: enables internal logging +* `rust-analyzer.trace.cargo-watch`: enables cargo-watch logging ## Emacs diff --git a/editors/code/package.json b/editors/code/package.json index ba9c9433a..cc364d478 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -194,6 +194,17 @@ ], "default": "off", "description": "Trace requests to the ra_lsp_server" + }, + "rust-analyzer.trace.cargo-watch": { + "type": "string", + "scope": "window", + "enum": [ + "off", + "error", + "verbose" + ], + "default": "off", + "description": "Trace output of cargo-watch" } } }, diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index e51cac78a..9864ce01a 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -1,6 +1,7 @@ import * as child_process from 'child_process'; import * as path from 'path'; import * as vscode from 'vscode'; +import { Server } from '../server'; import { terminate } from '../utils/processes'; import { StatusDisplay } from './watch_status'; @@ -10,6 +11,7 @@ export class CargoWatchProvider { private cargoProcess?: child_process.ChildProcess; private outBuffer: string = ''; private statusDisplay?: StatusDisplay; + private outputChannel?: vscode.OutputChannel; public activate(subscriptions: vscode.Disposable[]) { subscriptions.push(this); @@ -18,7 +20,10 @@ export class CargoWatchProvider { ); this.statusDisplay = new StatusDisplay(subscriptions); - + this.outputChannel = vscode.window.createOutputChannel( + 'Cargo Watch Trace' + ); + // Start the cargo watch with json message this.cargoProcess = child_process.spawn( 'cargo', @@ -31,17 +36,23 @@ export class CargoWatchProvider { ); this.cargoProcess.stdout.on('data', (s: string) => { - this.processOutput(s); - console.log(s); + this.processOutput(s, (line) => { + this.logInfo(line); + this.parseLine(line); + }); }); this.cargoProcess.stderr.on('data', (s: string) => { - console.error('Error on cargo watch : ' + s); + this.processOutput(s, (line) => { + this.logError('Error on cargo-watch : {\n' + line + '}\n' ); + }); }); this.cargoProcess.on('error', (err: Error) => { - console.error('Error on spawn cargo process : ' + err); + this.logError('Error on cargo-watch process : {\n' + err.message + '}\n'); }); + + this.logInfo('cargo-watch started.'); } public dispose(): void { @@ -54,6 +65,22 @@ export class CargoWatchProvider { this.cargoProcess.kill(); terminate(this.cargoProcess); } + + if(this.outputChannel) { + this.outputChannel.dispose(); + } + } + + private logInfo(line: string) { + if (Server.config.cargoWatchOptions.trace === 'verbose') { + this.outputChannel!.append(line); + } + } + + private logError(line: string) { + if (Server.config.cargoWatchOptions.trace === 'error' || Server.config.cargoWatchOptions.trace === 'verbose' ) { + this.outputChannel!.append(line); + } } private parseLine(line: string) { @@ -124,14 +151,14 @@ export class CargoWatchProvider { } } - private processOutput(chunk: string) { + private processOutput(chunk: string, cb: (line: string) => void ) { // The stdout is not line based, convert it to line based for proceess. this.outBuffer += chunk; let eolIndex = this.outBuffer.indexOf('\n'); while (eolIndex >= 0) { // line includes the EOL const line = this.outBuffer.slice(0, eolIndex + 1); - this.parseLine(line); + cb(line); this.outBuffer = this.outBuffer.slice(eolIndex + 1); eolIndex = this.outBuffer.indexOf('\n'); diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 7bba6f9cb..3589edcee 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -137,11 +137,11 @@ export async function handleSingle(runnable: Runnable) { export async function interactivelyStartCargoWatch( context: vscode.ExtensionContext ) { - if (Server.config.enableCargoWatchOnStartup === 'disabled') { + if (Server.config.cargoWatchOptions.enableOnStartup === 'disabled') { return; } - if (Server.config.enableCargoWatchOnStartup === 'ask') { + if (Server.config.cargoWatchOptions.enableOnStartup === 'ask') { const watch = await vscode.window.showInformationMessage( 'Start watching changes with cargo? (Executes `cargo watch`, provides inline diagnostics)', 'yes', diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 420589068..c95d13878 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -4,14 +4,20 @@ import { Server } from './server'; const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; -export type CargoWatchOptions = 'ask' | 'enabled' | 'disabled'; +export type CargoWatchStartupOptions = 'ask' | 'enabled' | 'disabled'; +export type CargoWatchTraceOptions = 'off' | 'error' | 'verbose'; + +export interface CargoWatchOptions { + enableOnStartup: CargoWatchStartupOptions, + trace: CargoWatchTraceOptions, +}; export class Config { public highlightingOn = true; public enableEnhancedTyping = true; public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server'; public showWorkspaceLoadedNotification = true; - public enableCargoWatchOnStartup: CargoWatchOptions = 'ask'; + public cargoWatchOptions: CargoWatchOptions = { enableOnStartup: 'ask', trace: 'off' }; private prevEnhancedTyping: null | boolean = null; @@ -73,10 +79,17 @@ export class Config { } if (config.has('enableCargoWatchOnStartup')) { - this.enableCargoWatchOnStartup = config.get( - 'enableCargoWatchOnStartup', - 'ask' - ); + this.cargoWatchOptions.enableOnStartup = + config.get( + 'enableCargoWatchOnStartup', + 'ask' + ); + this.cargoWatchOptions.trace = + config.get( + 'trace.cargo-watch', + 'off' + ); + } } } -- cgit v1.2.3 From 02e450f354ccd978c90425929c635139210843a3 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 14:43:02 +0800 Subject: Add cargo-watch.check-arguments --- docs/user/README.md | 2 + editors/code/package.json | 10 ++++ editors/code/src/commands/cargo_watch.ts | 78 ++++++++++++++++++++------------ editors/code/src/commands/line_buffer.ts | 16 +++++++ editors/code/src/config.ts | 39 ++++++++++------ editors/code/src/utils/processes.ts | 68 +++++++++++++++------------- 6 files changed, 139 insertions(+), 74 deletions(-) create mode 100644 editors/code/src/commands/line_buffer.ts diff --git a/docs/user/README.md b/docs/user/README.md index 722a86c9b..33dd4f995 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -59,6 +59,8 @@ for details. * `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable * `rust-analyzer.enableCargoWatchOnStartup`: prompt to install & enable `cargo watch` for live error highlighting (note, this **does not** use rust-analyzer) +* `rust-analyzer.cargo-watch.check-arguments`: cargo-watch check arguments. + (e.g: `--features="shumway,pdf"` will run as `cargo watch -x "check --features="shumway,pdf""` ) * `rust-analyzer.trace.server`: enables internal logging * `rust-analyzer.trace.cargo-watch`: enables cargo-watch logging diff --git a/editors/code/package.json b/editors/code/package.json index cc364d478..1c8caaa60 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -184,6 +184,11 @@ ], "description": "Whether to run `cargo watch` on startup" }, + "rust-analyzer.cargo-watch.check-arguments": { + "type": "string", + "description": "`cargo-watch` check arguments. (e.g: `--features=\"shumway,pdf\"` will run as `cargo watch -x \"check --features=\"shumway,pdf\"\"` )", + "default": "" + }, "rust-analyzer.trace.server": { "type": "string", "scope": "window", @@ -192,6 +197,11 @@ "messages", "verbose" ], + "enumDescriptions": [ + "No traces", + "Error only", + "Full log" + ], "default": "off", "description": "Trace requests to the ra_lsp_server" }, diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index 9864ce01a..fb8fcaeb3 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -3,9 +3,9 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { Server } from '../server'; import { terminate } from '../utils/processes'; +import { LineBuffer } from './line_buffer'; import { StatusDisplay } from './watch_status'; - export class CargoWatchProvider { private diagnosticCollection?: vscode.DiagnosticCollection; private cargoProcess?: child_process.ChildProcess; @@ -23,33 +23,44 @@ export class CargoWatchProvider { this.outputChannel = vscode.window.createOutputChannel( 'Cargo Watch Trace' ); - + + let args = '"check --message-format json'; + if (Server.config.cargoWatchOptions.checkArguments.length > 0) { + // Excape the double quote string: + args += ' ' + Server.config.cargoWatchOptions.checkArguments; + } + args += '"'; + // Start the cargo watch with json message this.cargoProcess = child_process.spawn( 'cargo', - ['watch', '-x', '\"check --message-format json\"'], + ['watch', '-x', args], { stdio: ['ignore', 'pipe', 'pipe'], cwd: vscode.workspace.rootPath, - windowsVerbatimArguments: true, + windowsVerbatimArguments: true } ); + const stdoutData = new LineBuffer(); this.cargoProcess.stdout.on('data', (s: string) => { - this.processOutput(s, (line) => { + stdoutData.processOutput(s, line => { this.logInfo(line); this.parseLine(line); }); }); + const stderrData = new LineBuffer(); this.cargoProcess.stderr.on('data', (s: string) => { - this.processOutput(s, (line) => { - this.logError('Error on cargo-watch : {\n' + line + '}\n' ); + stderrData.processOutput(s, line => { + this.logError('Error on cargo-watch : {\n' + line + '}\n'); }); }); this.cargoProcess.on('error', (err: Error) => { - this.logError('Error on cargo-watch process : {\n' + err.message + '}\n'); + this.logError( + 'Error on cargo-watch process : {\n' + err.message + '}\n' + ); }); this.logInfo('cargo-watch started.'); @@ -66,7 +77,7 @@ export class CargoWatchProvider { terminate(this.cargoProcess); } - if(this.outputChannel) { + if (this.outputChannel) { this.outputChannel.dispose(); } } @@ -74,13 +85,16 @@ export class CargoWatchProvider { private logInfo(line: string) { if (Server.config.cargoWatchOptions.trace === 'verbose') { this.outputChannel!.append(line); - } + } } private logError(line: string) { - if (Server.config.cargoWatchOptions.trace === 'error' || Server.config.cargoWatchOptions.trace === 'verbose' ) { + if ( + Server.config.cargoWatchOptions.trace === 'error' || + Server.config.cargoWatchOptions.trace === 'verbose' + ) { this.outputChannel!.append(line); - } + } } private parseLine(line: string) { @@ -105,12 +119,32 @@ export class CargoWatchProvider { return vscode.DiagnosticSeverity.Information; } + interface ErrorSpan { + line_start: number; + line_end: number; + column_start: number; + column_end: number; + } + + interface ErrorMessage { + reason: string; + message: { + spans: ErrorSpan[]; + rendered: string; + level: string; + code?: { + code: string; + }; + }; + } + // cargo-watch itself output non json format // Ignore these lines - let data = null; + let data: ErrorMessage; try { data = JSON.parse(line.trim()); } catch (error) { + this.logError(`Fail to pass to json : { ${error} }`); return; } @@ -137,7 +171,9 @@ export class CargoWatchProvider { const diagnostic = new vscode.Diagnostic(range, rendered, level); diagnostic.source = 'rustc'; - diagnostic.code = data.message.code.code; + diagnostic.code = data.message.code + ? data.message.code.code + : undefined; diagnostic.relatedInformation = []; const fileUrl = vscode.Uri.file(fileName!); @@ -150,18 +186,4 @@ export class CargoWatchProvider { this.diagnosticCollection!.set(fileUrl, diagnostics); } } - - private processOutput(chunk: string, cb: (line: string) => void ) { - // The stdout is not line based, convert it to line based for proceess. - this.outBuffer += chunk; - let eolIndex = this.outBuffer.indexOf('\n'); - while (eolIndex >= 0) { - // line includes the EOL - const line = this.outBuffer.slice(0, eolIndex + 1); - cb(line); - this.outBuffer = this.outBuffer.slice(eolIndex + 1); - - eolIndex = this.outBuffer.indexOf('\n'); - } - } } diff --git a/editors/code/src/commands/line_buffer.ts b/editors/code/src/commands/line_buffer.ts new file mode 100644 index 000000000..fb5b9f7f2 --- /dev/null +++ b/editors/code/src/commands/line_buffer.ts @@ -0,0 +1,16 @@ +export class LineBuffer { + private outBuffer: string = ''; + + public processOutput(chunk: string, cb: (line: string) => void) { + this.outBuffer += chunk; + let eolIndex = this.outBuffer.indexOf('\n'); + while (eolIndex >= 0) { + // line includes the EOL + const line = this.outBuffer.slice(0, eolIndex + 1); + cb(line); + this.outBuffer = this.outBuffer.slice(eolIndex + 1); + + eolIndex = this.outBuffer.indexOf('\n'); + } + } +} diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index c95d13878..481a5e5f1 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -8,16 +8,21 @@ export type CargoWatchStartupOptions = 'ask' | 'enabled' | 'disabled'; export type CargoWatchTraceOptions = 'off' | 'error' | 'verbose'; export interface CargoWatchOptions { - enableOnStartup: CargoWatchStartupOptions, - trace: CargoWatchTraceOptions, -}; + enableOnStartup: CargoWatchStartupOptions; + checkArguments: string; + trace: CargoWatchTraceOptions; +} export class Config { public highlightingOn = true; public enableEnhancedTyping = true; public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server'; public showWorkspaceLoadedNotification = true; - public cargoWatchOptions: CargoWatchOptions = { enableOnStartup: 'ask', trace: 'off' }; + public cargoWatchOptions: CargoWatchOptions = { + enableOnStartup: 'ask', + trace: 'off', + checkArguments: '' + }; private prevEnhancedTyping: null | boolean = null; @@ -79,17 +84,23 @@ export class Config { } if (config.has('enableCargoWatchOnStartup')) { - this.cargoWatchOptions.enableOnStartup = - config.get( - 'enableCargoWatchOnStartup', - 'ask' - ); - this.cargoWatchOptions.trace = - config.get( - 'trace.cargo-watch', - 'off' - ); + this.cargoWatchOptions.enableOnStartup = config.get< + CargoWatchStartupOptions + >('enableCargoWatchOnStartup', 'ask'); + } + + if (config.has('trace.cargo-watch')) { + this.cargoWatchOptions.trace = config.get( + 'trace.cargo-watch', + 'off' + ); + } + if (config.has('cargo-watch.check-arguments')) { + this.cargoWatchOptions.checkArguments = config.get( + 'cargo-watch.check-arguments', + '' + ); } } } diff --git a/editors/code/src/utils/processes.ts b/editors/code/src/utils/processes.ts index 09fdf6e24..d4c2c8778 100644 --- a/editors/code/src/utils/processes.ts +++ b/editors/code/src/utils/processes.ts @@ -5,36 +5,40 @@ import ChildProcess = cp.ChildProcess; import { join } from 'path'; -const isWindows = (process.platform === 'win32'); -const isMacintosh = (process.platform === 'darwin'); -const isLinux = (process.platform === 'linux'); +const isWindows = process.platform === 'win32'; +const isMacintosh = process.platform === 'darwin'; +const isLinux = process.platform === 'linux'; export function terminate(process: ChildProcess, cwd?: string): boolean { - if (isWindows) { - try { - // This we run in Atom execFileSync is available. - // Ignore stderr since this is otherwise piped to parent.stderr - // which might be already closed. - const options: any = { - stdio: ['pipe', 'pipe', 'ignore'] - }; - if (cwd) { - options.cwd = cwd - } - (cp).execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options); - return true; - } catch (err) { - return false; - } - } else if (isLinux || isMacintosh) { - try { - const cmd = join(__dirname, 'terminateProcess.sh'); - const result = cp.spawnSync(cmd, [process.pid.toString()]); - return result.error ? false : true; - } catch (err) { - return false; - } - } else { - process.kill('SIGKILL'); - return true; - } -} \ No newline at end of file + if (isWindows) { + try { + // This we run in Atom execFileSync is available. + // Ignore stderr since this is otherwise piped to parent.stderr + // which might be already closed. + const options: any = { + stdio: ['pipe', 'pipe', 'ignore'] + }; + if (cwd) { + options.cwd = cwd; + } + cp.execFileSync( + 'taskkill', + ['/T', '/F', '/PID', process.pid.toString()], + options + ); + return true; + } catch (err) { + return false; + } + } else if (isLinux || isMacintosh) { + try { + const cmd = join(__dirname, 'terminateProcess.sh'); + const result = cp.spawnSync(cmd, [process.pid.toString()]); + return result.error ? false : true; + } catch (err) { + return false; + } + } else { + process.kill('SIGKILL'); + return true; + } +} -- cgit v1.2.3 From 06053a0a7636b620d36d49678a5d73424e0010e9 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 14:58:58 +0800 Subject: Add Cargo.toml file check before cargo watch start --- editors/code/src/commands/cargo_watch.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index fb8fcaeb3..6d8e4d885 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -1,4 +1,5 @@ import * as child_process from 'child_process'; +import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; import { Server } from '../server'; @@ -14,6 +15,27 @@ export class CargoWatchProvider { private outputChannel?: vscode.OutputChannel; public activate(subscriptions: vscode.Disposable[]) { + let cargoExists = false; + const cargoTomlFile = path.join( + vscode.workspace.rootPath!, + 'Cargo.toml' + ); + // Check if the working directory is valid cargo root path + try { + if (fs.existsSync(cargoTomlFile)) { + cargoExists = true; + } + } catch (err) { + cargoExists = false; + } + + if (!cargoExists) { + vscode.window.showErrorMessage( + `Couldn\'t find \'Cargo.toml\' in ${cargoTomlFile}` + ); + return; + } + subscriptions.push(this); this.diagnosticCollection = vscode.languages.createDiagnosticCollection( 'rustc' -- cgit v1.2.3 From 9d269849987fbe374b0f76a4893fdf9d867b8b84 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 17:13:14 +0800 Subject: Add terminate process implemntation note --- editors/code/src/utils/processes.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/editors/code/src/utils/processes.ts b/editors/code/src/utils/processes.ts index d4c2c8778..f62e2a346 100644 --- a/editors/code/src/utils/processes.ts +++ b/editors/code/src/utils/processes.ts @@ -8,6 +8,13 @@ import { join } from 'path'; const isWindows = process.platform === 'win32'; const isMacintosh = process.platform === 'darwin'; const isLinux = process.platform === 'linux'; + +// this is very complex, but is basically copy-pased from VSCode implementation here: +// https://github.com/Microsoft/vscode-languageserver-node/blob/dbfd37e35953ad0ee14c4eeced8cfbc41697b47e/client/src/utils/processes.ts#L15 + +// And see discussion at +// https://github.com/rust-analyzer/rust-analyzer/pull/1079#issuecomment-478908109 + export function terminate(process: ChildProcess, cwd?: string): boolean { if (isWindows) { try { -- cgit v1.2.3 From b60e2f779b28f654dbd5a2657c668de8452933c6 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 17:43:09 +0800 Subject: Fix prettier error --- editors/code/src/utils/processes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/utils/processes.ts b/editors/code/src/utils/processes.ts index f62e2a346..da8be9eb1 100644 --- a/editors/code/src/utils/processes.ts +++ b/editors/code/src/utils/processes.ts @@ -12,7 +12,7 @@ const isLinux = process.platform === 'linux'; // this is very complex, but is basically copy-pased from VSCode implementation here: // https://github.com/Microsoft/vscode-languageserver-node/blob/dbfd37e35953ad0ee14c4eeced8cfbc41697b47e/client/src/utils/processes.ts#L15 -// And see discussion at +// And see discussion at // https://github.com/rust-analyzer/rust-analyzer/pull/1079#issuecomment-478908109 export function terminate(process: ChildProcess, cwd?: string): boolean { -- cgit v1.2.3