fix(editor): stop per-keystroke full-document statement reparse

Closes #8600
This commit is contained in:
t8y2 committed 2026-09-17 01:30:02 +08:00
1 parent 84ae93aaa8
commit ab5aba9497
5 files changed
+297 -52

No files matched your search

@@ -1,6 +1,14 @@
import { Text } from "@codemirror/state";
import { ChangeSet, Text } from "@codemirror/state";
import { describe, expect, it, vi } from "vitest";
import { executableStatementRangeAtCursor, executableStatementRangeCacheForDoc, executableStatementRangeStartingAt, type ExecutableStatementRangeParser } from "@/lib/sql/executableStatementRangeCache";
import {
executableStatementRangeAtCursor,
executableStatementRangeCacheForDoc,
executableStatementRangeStartingAt,
mapStatementGutterStartIndex,
statementGutterStartIndexForCache,
statementGutterStartIndexHasStartAt,
type ExecutableStatementRangeParser,
} from "@/lib/sql/executableStatementRangeCache";
describe("executableStatementRangeCacheForDoc", () => {
it("tracks MongoDB commands for current-statement framing", () => {
@@ -237,3 +245,33 @@ describe("executableStatementRangeCacheForDoc", () => {
expect(parse).toHaveBeenCalledTimes(2);
});
});
describe("statementGutterStartIndex", () => {
it("derives membership from both statement starts and executable line starts", () => {
const doc = Text.of(["/*+ hint */", "SELECT 1;", "", "SELECT 2;"]);
const cache = executableStatementRangeCacheForDoc(null, doc, "mysql");
const index = statementGutterStartIndexForCache(cache);
// First statement: executable start lands on the directive's following line.
expect(statementGutterStartIndexHasStartAt(index, doc.line(2).from)).toBe(true);
expect(statementGutterStartIndexHasStartAt(index, doc.line(4).from)).toBe(true);
expect(statementGutterStartIndexHasStartAt(index, doc.line(3).from)).toBe(false);
});
it("shifts start positions through insertions and deletions", () => {
const doc = Text.of(["SELECT 1;", "SELECT 2;"]);
const cache = executableStatementRangeCacheForDoc(null, doc, "mysql");
const index = statementGutterStartIndexForCache(cache);
const secondLineStart = doc.line(2).from;
expect(statementGutterStartIndexHasStartAt(index, secondLineStart)).toBe(true);
const header = "-- lead\n";
const afterInsert = mapStatementGutterStartIndex(index, ChangeSet.of({ from: 0, to: 0, insert: header }, doc.length));
expect(statementGutterStartIndexHasStartAt(afterInsert, secondLineStart)).toBe(false);
expect(statementGutterStartIndexHasStartAt(afterInsert, secondLineStart + header.length)).toBe(true);
const afterDelete = mapStatementGutterStartIndex(index, ChangeSet.of({ from: 0, to: "SELECT 1;\n".length, insert: "" }, doc.length));
expect(statementGutterStartIndexHasStartAt(afterDelete, secondLineStart - "SELECT 1;\n".length)).toBe(true);
expect(statementGutterStartIndexHasStartAt(afterDelete, 0)).toBe(true);
});
});