Skip to content

Commit 2fc72ca

Browse files
committed
fix
1 parent 7d3ff20 commit 2fc72ca

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

‎src/cm/indentedLineWrapping.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ export function wrappedIndentColumns(
2828
): number {
2929
const extra =
3030
mode === "indent" ? tabSize : mode === "deepIndent" ? 2 * tabSize : 0;
31-
// Unindented/minified lines need no tab scan, even when they are megabytes long.
3231
if (mode === "none" || limit <= 0) return 0;
33-
if (!extra && text[0] !== " " && text[0] !== "\t") return 0;
32+
if (text[0] !== " " && text[0] !== "\t") {
33+
// Extra levels are whole tab stops, so content tabs cannot affect them.
34+
// Keep the width cap tab-aligned too, avoiding a scan even in narrow panes.
35+
return Math.min(extra, Math.floor(limit / tabSize) * tabSize);
36+
}
3437
// Include content tabs deliberately: negative text-indent changes the origin
3538
// of every tab stop on the first visual row. For " key\tvalue", using 2ch
3639
// shifts "value" left by two columns in Chromium; 4ch preserves its position.

‎tests/unit/indentedLineWrapping.test.ts‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { wrappedIndentColumns } from "cm/indentedLineWrapping";
2-
import { describe, expect, it } from "vitest";
2+
import { describe, expect, it, vi } from "vitest";
33

44
describe("wrapped line indentation", () => {
55
it("preserves space indentation and stops at content", () => {
@@ -37,4 +37,24 @@ describe("wrapped line indentation", () => {
3737
expect(wrappedIndentColumns(" key\tvalue", 4, 7, "deepIndent")).toBe(4);
3838
expect(wrappedIndentColumns(" code", 4, 7, "deepIndent")).toBe(7);
3939
});
40+
it("caps unindented lines at whole tab stops without depending on content tabs", () => {
41+
for (const text of ["code", "key\tvalue"]) {
42+
expect(wrappedIndentColumns(text, 4, 7, "deepIndent")).toBe(4);
43+
expect(wrappedIndentColumns(text, 4, 3, "indent")).toBe(0);
44+
}
45+
});
46+
it("skips the full-line tab search for large unindented lines in extra-indent modes", () => {
47+
const text = "x".repeat(1_000_000) + "\tvalue";
48+
const search = vi.spyOn(String.prototype, "includes");
49+
let calls: number;
50+
try {
51+
wrappedIndentColumns(text, 4, 40, "indent");
52+
wrappedIndentColumns(text, 4, 40, "deepIndent");
53+
wrappedIndentColumns(text, 4, 7, "deepIndent");
54+
calls = search.mock.calls.length;
55+
} finally {
56+
search.mockRestore();
57+
}
58+
expect(calls).toBe(0);
59+
});
4060
});

0 commit comments

Comments
 (0)