diff --git a/src/crystalDiagnostic.ts b/src/crystalDiagnostic.ts index 84940f5..733bf09 100755 --- a/src/crystalDiagnostic.ts +++ b/src/crystalDiagnostic.ts @@ -1,5 +1,4 @@ import * as vscode from "vscode" -import { spawn } from "child_process" import { Concurrent, isNotLib, spawnCompiler } from "./crystalUtils" diff --git a/src/crystalFormatting.ts b/src/crystalFormatting.ts index d4f5e1d..cd8e1cc 100755 --- a/src/crystalFormatting.ts +++ b/src/crystalFormatting.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode" import { spawn } from "child_process" -import { searchProblems, childOnStd, childOnError } from "./crystalUtils" +import { searchProblemsFromRaw, childOnStd, childOnError } from "./crystalUtils" /** * Formatting provider using VSCode module @@ -42,7 +42,8 @@ export class CrystalFormattingProvider implements vscode.DocumentFormattingEditP // } // QuickFix to replace current code with formated one only if no syntax error is found - if (!response.toString().startsWith("Error:")) { + if ((searchProblemsFromRaw(response.toString(), document.uri).length == 0) && + response.toString().length > 0) { let lastLineId = document.lineCount - 1 let range = new vscode.Range(0, 0, lastLineId, document.lineAt(lastLineId).text.length) textEditData = [vscode.TextEdit.replace(range, response.toString())] diff --git a/src/crystalUtils.ts b/src/crystalUtils.ts index 5a3a68a..30870cc 100755 --- a/src/crystalUtils.ts +++ b/src/crystalUtils.ts @@ -191,6 +191,47 @@ export function searchProblems(response: string, uri: vscode.Uri) { return diagnostics } +/** + * Parse raw output from crystal tool format - response and create diagnostics + */ +export function searchProblemsFromRaw(response: string, uri: vscode.Uri) { + let diagnostics = [] + + const config = vscode.workspace.getConfiguration("crystal-lang") + + let responseData = response.match(/.* in (.*):(\d+): (.*)/) + + let parsedLine:number + + try { + parsedLine = parseInt(responseData[2]) + } catch (e) { + parsedLine = 0 + } + + let columnLocation = 1 // No way to get column from crystal tool format - + + if (parsedLine != 0) { + let problem = { + line: parsedLine, + column: columnLocation, + message: responseData[3] + } + + let range = new vscode.Range(problem.line - 1, problem.column - 1, problem.line - 1, problem.column - 1) + let diagnostic = new vscode.Diagnostic(range, problem.message, vscode.DiagnosticSeverity.Error) + diagnostics.push([uri, [diagnostic]]) + } + + if (diagnostics.length == 0) { + diagnosticCollection.clear() + } else if (config["problems"] != "none") { + diagnosticCollection.set(diagnostics) + } + + return diagnostics +} + /** * Execute Crystal tools context and implementations */ @@ -258,13 +299,11 @@ export function spawnCompiler(document, build) { ] } return [ - "build", - "--no-debug", + "tool", + "format", + "--check", "--no-color", - "--no-codegen", - scope, - "-f", - "json" + scope ] })() let child = spawn(config["compiler"], args, spawnOptions) @@ -272,10 +311,12 @@ export function spawnCompiler(document, build) { response += data }) childOnStd(child, "end", () => { - searchProblems(response.toString(), document.uri) if (build) { + searchProblems(response.toString(), document.uri) Concurrent.counter -= 1 statusBarItem.hide() + } else { + searchProblemsFromRaw(response.toString(), document.uri) } }) childOnError(child)