From 31ade79e637c17ebea84aef8da65541687f4da2c Mon Sep 17 00:00:00 2001 From: Niall Farrell Date: Wed, 17 Dec 2025 15:24:01 +0000 Subject: [PATCH 1/2] Align columns for nested data --- src/utils/queryUtils.ts | 31 ++++++++++++++++++------ src/webview/components/kdbResultsView.ts | 7 +++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/utils/queryUtils.ts b/src/utils/queryUtils.ts index 8d42494d..4bbf9ed0 100644 --- a/src/utils/queryUtils.ts +++ b/src/utils/queryUtils.ts @@ -357,8 +357,10 @@ export function convertRowsToConsole(rows: string[]): string[] { } const columnCounters = vector[0].reduce((counters: number[], _, j) => { + // get max width of column, splitting values by new line const maxLength = vector.reduce( - (max, row) => Math.max(max, row[j].length), + (max, row) => + Math.max(max, Math.max(...row[j].split("\n").map((l) => l.length))), 0, ); counters.push(maxLength + 2); @@ -368,14 +370,27 @@ export function convertRowsToConsole(rows: string[]): string[] { vector.forEach((row) => { row.forEach((value, j) => { const counter = columnCounters[j]; - const diff = counter - value.length; - if (diff > 0) { - if (!haveHeader && j !== columnCounters.length - 1) { - row[j] = value + "|" + " ".repeat(diff > 1 ? diff - 1 : diff); - } else { - row[j] = value + " ".repeat(diff); + const lines = value.split("\n"); + row[j] = ""; + + lines.forEach((line, lineIndex) => { + if (lineIndex > 0) { + // prepend spacing to align lines within the same cell + const prevCol = columnCounters[j - 1]; + if (prevCol) { + row[j] += "\n" + " ".repeat(prevCol); + } } - } + + const diff = counter - line.length; + if (diff > 0) { + if (!haveHeader && j !== columnCounters.length - 1) { + row[j] += line + "|" + " ".repeat(diff > 1 ? diff - 1 : diff); + } else { + row[j] += line + " ".repeat(diff); + } + } + }); }); }); diff --git a/src/webview/components/kdbResultsView.ts b/src/webview/components/kdbResultsView.ts index e4528627..ec9e6cbe 100644 --- a/src/webview/components/kdbResultsView.ts +++ b/src/webview/components/kdbResultsView.ts @@ -189,7 +189,12 @@ export class KdbResultsView extends LitElement { (row: any) => html` ${this.columnDefs.map( - (col: any) => html`${row[col.field]}`, + (col: any) => + html` + ${row[col.field]} + `, )} `, From 8f386a0b00825946abf15b8a34c6931eb3c115af Mon Sep 17 00:00:00 2001 From: Niall Farrell Date: Wed, 17 Dec 2025 15:55:33 +0000 Subject: [PATCH 2/2] Add test --- src/utils/queryUtils.ts | 2 ++ test/suite/utils/queryUtils.test.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/utils/queryUtils.ts b/src/utils/queryUtils.ts index 4bbf9ed0..dab93fe7 100644 --- a/src/utils/queryUtils.ts +++ b/src/utils/queryUtils.ts @@ -379,6 +379,8 @@ export function convertRowsToConsole(rows: string[]): string[] { const prevCol = columnCounters[j - 1]; if (prevCol) { row[j] += "\n" + " ".repeat(prevCol); + } else { + row[j] += "\n"; } } diff --git a/test/suite/utils/queryUtils.test.ts b/test/suite/utils/queryUtils.test.ts index 2d1c8ca3..f3c9cf40 100644 --- a/test/suite/utils/queryUtils.test.ts +++ b/test/suite/utils/queryUtils.test.ts @@ -284,6 +284,19 @@ describe("queryUtils", () => { assert.deepEqual(result, expectedRes); }); + + it("should work with rows with newlines", () => { + const rows = ["a#$#;header;#$#b", "a1\na2#$#;#$#b1\nb2", "3#$#;#$#4"]; + const expectedRes = [ + "a b ", + "--------", + "a1 \na2 b1 \n b2 ", + "3 4 ", + ]; + const result = queryUtils.convertRowsToConsole(rows); + + assert.deepEqual(result, expectedRes); + }); }); it("getConnectionType", () => {