fix(tui): stabilize streaming code fence rendering (#5846)

This commit is contained in:
Alexey Zaytsev
2026-06-20 07:58:30 -05:00
committed by GitHub
parent 8b97e75c6b
commit 3095977d13
2 changed files with 69 additions and 0 deletions

View File

@@ -22,6 +22,31 @@ class StrictStrikethroughTokenizer extends Tokenizer {
}
}
function trimPartialClosingFences(tokens: readonly Token[]): void {
const token = tokens[tokens.length - 1];
if (token?.type === "list") {
trimPartialClosingFences(token.items[token.items.length - 1]?.tokens ?? []);
return;
}
if (token?.type === "blockquote") {
trimPartialClosingFences(token.tokens ?? []);
return;
}
if (token?.type !== "code") {
return;
}
// Trim streamed partial closing fences so code blocks do not shrink/flicker
// when the final fence character arrives. See https://github.com/earendil-works/pi/issues/5825.
const marker = /^(`{3,}|~{3,})/.exec(token.raw)?.[1];
const lastLine = token.raw.split("\n").pop();
if (!marker || !lastLine || lastLine.length >= marker.length || lastLine !== marker[0]?.repeat(lastLine.length)) {
return;
}
token.text = token.text.slice(0, -lastLine.length).replace(/\n$/, "");
}
const markdownParser = new Marked();
markdownParser.setOptions({
tokenizer: new StrictStrikethroughTokenizer(),
@@ -145,6 +170,7 @@ export class Markdown implements Component {
// Parse markdown to HTML-like tokens
const tokens = markdownParser.lexer(normalizedText);
trimPartialClosingFences(tokens);
// Convert tokens to styled terminal output
const renderedLines: string[] = [];