diff --git a/src/problem.ts b/src/problem.ts index 6930e3b..2b8a5e1 100644 --- a/src/problem.ts +++ b/src/problem.ts @@ -7,7 +7,7 @@ import * as path from 'path'; import * as os from 'os'; import {log} from './log'; import {config} from './config'; -import {decodeBufferWithConfidence} from './utils'; +import {decodeBufferWithConfidence, sanitizeBuildLogText} from './utils'; // the problem list class export class ProblemList implements vscode.Disposable { @@ -50,7 +50,7 @@ export class ProblemList implements vscode.Disposable { if (!err && content) { const decoded = decodeBufferWithConfidence(content); - const text = decoded.text; + const text = sanitizeBuildLogText(decoded.text); // log.verbose(`diagnose logfile encoding: ${decoded.encoding}`); // init regex of gcc/clang output diff --git a/src/terminal.ts b/src/terminal.ts index 9a27a0f..3afefbe 100644 --- a/src/terminal.ts +++ b/src/terminal.ts @@ -57,7 +57,13 @@ export class Terminal implements vscode.Disposable { var options = {"cwd": config.workingDirectory}; if (withlog) { - options["env"] = {XMAKE_LOGFILE: this.logfile}; + options["env"] = { + XMAKE_LOGFILE: this.logfile, + XMAKE_COLORTERM: "nocolor", + COLORTERM: "nocolor", + NO_COLOR: "1", + CLICOLOR: "0" + }; } const kind: vscode.TaskDefinition = { @@ -79,7 +85,13 @@ export class Terminal implements vscode.Disposable { var options = {"cwd": config.workingDirectory}; if (withlog) { - options["env"] = {XMAKE_LOGFILE: this.logfile}; + options["env"] = { + XMAKE_LOGFILE: this.logfile, + XMAKE_COLORTERM: "nocolor", + COLORTERM: "nocolor", + NO_COLOR: "1", + CLICOLOR: "0" + }; } const kind: vscode.TaskDefinition = { diff --git a/src/utils.ts b/src/utils.ts index d0cd164..f773774 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -114,6 +114,23 @@ export function decodeBufferWithConfidence(buffer: Buffer): { encoding: string; return { encoding: 'utf8-fallback', text: utf8Text }; } +// Remove terminal control bytes so diagnostics parser gets stable plain text. +export function sanitizeBuildLogText(text: string): string { + let cleaned = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + + // Strip ANSI escape sequences (e.g. colors, cursor controls). + cleaned = cleaned.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g, ''); + + // Apply backspaces to avoid broken words from in-place terminal updates. + while (/\x08/.test(cleaned)) { + cleaned = cleaned.replace(/[^\n]\x08/g, '').replace(/\x08/g, ''); + } + + // Remove other non-printable control chars but keep tab/newline. + cleaned = cleaned.replace(/[\x00-\x08\x0B-\x1F\x7F]/g, ''); + return cleaned; +} + // simplistic function for just checking if a string can be parsed as json export function isJson(text?: string): boolean { try {