fix(tui): cleared stale streaming prefix caches
Cleared frozen-prefix render state after full-lex renders cannot establish a current appendable prefix, preventing truncated transient text from reusing spacer lines produced with a former tail. Added regression coverage for truncating back to a previously frozen prefix. Fixes #3975
This commit is contained in:
@@ -890,15 +890,16 @@ export class Markdown implements Component {
|
||||
) {
|
||||
const tailTokens = markdownParser.lexer(text.slice(prefix.length));
|
||||
const tokens = [...prefixTokens, ...tailTokens];
|
||||
this.#freezeStablePrefix(text, tokens);
|
||||
this.#freezeStablePrefix(text, tokens, { preserveExisting: true });
|
||||
return tokens;
|
||||
}
|
||||
const tokens = markdownParser.lexer(text);
|
||||
if (canStream) {
|
||||
this.#freezeStablePrefix(text, tokens);
|
||||
this.#freezeStablePrefix(text, tokens, { preserveExisting: false });
|
||||
} else {
|
||||
this.#streamPrefixText = undefined;
|
||||
this.#streamPrefixTokens = undefined;
|
||||
this.#streamPrefixLineCache = undefined;
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
@@ -908,7 +909,7 @@ export class Markdown implements Component {
|
||||
// render re-lexes only the unfrozen tail. Caller guarantees no CR / no
|
||||
// reference definitions, so each token's `raw` is a verbatim slice of `text`
|
||||
// and the summed offsets address `text` exactly.
|
||||
#freezeStablePrefix(text: string, tokens: Token[]): void {
|
||||
#freezeStablePrefix(text: string, tokens: Token[], opts: { preserveExisting: boolean }): void {
|
||||
let pos = 0;
|
||||
let frozenEnd = 0;
|
||||
let frozenCount = 0;
|
||||
@@ -937,8 +938,15 @@ export class Markdown implements Component {
|
||||
if (next !== 0x20 /* space */ && next !== 0x0a /* \n */) {
|
||||
this.#streamPrefixText = text.slice(0, frozenEnd);
|
||||
this.#streamPrefixTokens = tokens.slice(0, frozenCount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts.preserveExisting) {
|
||||
this.#streamPrefixText = undefined;
|
||||
this.#streamPrefixTokens = undefined;
|
||||
this.#streamPrefixLineCache = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
render(width: number): readonly string[] {
|
||||
|
||||
@@ -78,4 +78,16 @@ describe("Markdown streaming prefix render cache", () => {
|
||||
expect(codeBlockBorderCalls).toBe(0);
|
||||
expect(streamingLines).toEqual(renderCold(thirdText, theme));
|
||||
});
|
||||
|
||||
it("drops cached prefix lines after truncating to a previously frozen prefix", () => {
|
||||
const prefix = "---\n\n";
|
||||
const md = new Markdown(`${prefix}body`, 0, 0, defaultMarkdownTheme);
|
||||
md.transientRenderCache = true;
|
||||
md.render(WIDTH);
|
||||
|
||||
md.setText(prefix);
|
||||
const streamingLines = md.render(WIDTH);
|
||||
|
||||
expect(streamingLines).toEqual(renderCold(prefix, defaultMarkdownTheme));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user