diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e03926..fe2b542 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## v1.0.1 (2025-07-25) +## v1.0.2 (2025-05-20) + + + +## v1.0.1 (2025-05-7) @@ -8,7 +12,7 @@ - help flags can cause issues -## v1.0.0 (2025-07-25) +## v1.0.0 (2025-05-7) ### Features diff --git a/cli/TerminalLayout.ts b/cli/TerminalLayout.ts index a4f400c..4866444 100644 --- a/cli/TerminalLayout.ts +++ b/cli/TerminalLayout.ts @@ -111,6 +111,8 @@ export class TerminalBlock { private renderHeight: number = 0; private lastRenderRow = 1; + private lastRendered: string[] = []; + private preserveHistory = false; constructor(private prepend: string = "") {} @@ -193,27 +195,37 @@ export class TerminalBlock { } renderInternal(startRow?: number) { - this.lastRenderRow = startRow ?? this.lastRenderRow; - this.clear(); // uses old renderedLineCount + const outputLines: string[] = []; - const outputLines = this.renderLines.map((line) => - `${this.prepend}${line}\x1b[K` - ); - const output = outputLines.join("\n"); - if (startRow !== undefined) { - const moveCursor = `\x1b[${startRow};1H`; - Deno.stdout.writeSync(new TextEncoder().encode(moveCursor + output)); - } else { - Deno.stdout.writeSync(new TextEncoder().encode(output)); + for (let i = 0; i < this.renderLines.length; i++) { + const line = `${this.prepend}${this.renderLines[i]}`; + const previous = this.lastRendered[i]; + if (line !== previous) { + const moveToLine = `\x1b[${(startRow ?? this.lastRenderRow) + i};1H`; + outputLines.push(moveToLine + line + "\x1b[K"); + } } - // update rendered line count *after* rendering - this.renderedLineCount = outputLines.reduce( - (count, line) => - count + - Math.ceil((line.length) / (Deno.consoleSize().columns || 80)), - 0, - ); + if (this.lastRendered.length > this.renderLines.length) { + const baseRow = startRow ?? this.lastRenderRow; + for (let i = this.renderLines.length; i < this.lastRendered.length; i++) { + const moveToLine = `\x1b[${baseRow + i};1H\x1b[2K`; + Deno.stdout.writeSync(new TextEncoder().encode(moveToLine)); + } + } + + const baseRow = startRow ?? this.lastRenderRow; + const excessLines = this.renderHeight - this.renderLines.length; + for (let i = 0; i < excessLines; i++) { + const moveToLine = `[${baseRow + this.renderLines.length + i};1H`; + Deno.stdout.writeSync(new TextEncoder().encode(moveToLine)); + } + + this.lastRendered = [...this.renderLines]; + this.renderedLineCount = this.renderHeight; + this.lastRenderRow = baseRow; + const output = outputLines.join("\n"); + Deno.stdout.writeSync(new TextEncoder().encode(output)); } clear() { diff --git a/deno.json b/deno.json index 84dbf51..c371ac4 100644 --- a/deno.json +++ b/deno.json @@ -3,7 +3,7 @@ "version": "1.0.1", "license": "GPL 3.0", "tasks": { - "dev": "deno run -A --env-file=.env --watch main.ts", + "dev": "deno run -A --env-file=.env main.ts", "compile": "deno compile -o compare-form-fields.exe --target x86_64-pc-windows-msvc -R ./main.ts", "install": "deno install -fgq --import-map ./deno.json -n checkfields -R ./main.ts", "debug": "deno run -A --env-file=.env --inspect-wait --watch main.ts"