Skip to content

Commit 4054944

Browse files
committed
Use the longest common tab indentation
1 parent 8cd5d7c commit 4054944

1 file changed

Lines changed: 35 additions & 5 deletions

File tree

src/modelFactory/tableIndentationDetector.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,51 @@ export class FairTableIndentationDetector extends TableIndentationDetector {
2525
}
2626

2727
protected getIndentationChars(leftPadsPerLine: string[]): string {
28-
const nonEmptyLeftPads = leftPadsPerLine.filter(l => l.length > 0);
28+
const nonEmptyLeftPads: string[] = leftPadsPerLine.filter(l => l.length > 0);
29+
30+
// special handling for tab-based indentation: find longest common tab prefix
31+
let commonTabPrefixLength: number = 0;
32+
if (nonEmptyLeftPads.length > 0) {
33+
// find the shortest indent length from all lines
34+
let shortestLength: number = nonEmptyLeftPads[0].length;
35+
for (let i: number = 1; i < nonEmptyLeftPads.length; i++) {
36+
if (nonEmptyLeftPads[i].length < shortestLength) {
37+
shortestLength = nonEmptyLeftPads[i].length;
38+
}
39+
}
40+
41+
// check each char across all pads up untl the shortest length
42+
for (let pos: number = 0; pos < shortestLength; pos++) {
43+
if (nonEmptyLeftPads.every(pad => pad[pos] === '\t')) {
44+
// tabs are persistent indent char(s) up until here on all lines
45+
commonTabPrefixLength = pos + 1;
46+
} else {
47+
// early exit when first non-tab is found
48+
break;
49+
}
50+
}
51+
}
52+
53+
if (commonTabPrefixLength > 0) {
54+
return '\t'.repeat(commonTabPrefixLength);
55+
}
56+
57+
// Fallback to original logic
2958
let indentCounters: Map<string, number> = new Map();
3059

3160
for (const leftPad of nonEmptyLeftPads) {
32-
let count = 1;
61+
let count: number = 1;
3362
if (indentCounters.has(leftPad)) {
34-
count += indentCounters.get(leftPad);
63+
count += indentCounters.get(leftPad)!;
3564
}
3665
indentCounters.set(leftPad, ++count);
3766
}
3867

3968
// if there is an indentation used for at least 2 distinct lines, then use that, otherwise use the first line's indentation
40-
const indentWithMostRepeats = [...indentCounters.entries()].reduce((prev, curr) => curr[1] > prev[1] ? curr : prev)
69+
const indentWithMostRepeats: [string, number] = [...indentCounters.entries()].reduce((prev, curr) => curr[1] > prev[1] ? curr : prev)
70+
4171
return indentWithMostRepeats[1] > 1
4272
? indentWithMostRepeats[0]
43-
: indentCounters[0];
73+
: nonEmptyLeftPads[0];
4474
}
4575
}

0 commit comments

Comments
 (0)