fix(tui): numbered list items showing "1." when code blocks break list continuity

This commit is contained in:
Ogulcan Celik 2026-01-12 18:21:11 +03:00 committed by Mario Zechner
parent 234f367d0d
commit a5441706f3
3 changed files with 45 additions and 2 deletions

View file

@ -6,6 +6,10 @@
- `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions ([#662](https://github.com/badlogic/pi-mono/pull/662) by [@aliou](https://github.com/aliou))
### Fixed
- Numbered list items showing "1." for all items when code blocks break list continuity ([#660](https://github.com/badlogic/pi-mono/pull/660) by [@ogulcancelik](https://github.com/ogulcancelik))
## [0.43.0] - 2026-01-11
### Added

View file

@ -418,13 +418,15 @@ export class Markdown implements Component {
/**
* Render a list with proper nesting support
*/
private renderList(token: Token & { items: any[]; ordered: boolean }, depth: number): string[] {
private renderList(token: Token & { items: any[]; ordered: boolean; start?: number }, depth: number): string[] {
const lines: string[] = [];
const indent = " ".repeat(depth);
// Use the list's start property (defaults to 1 for ordered lists)
const startNumber = token.start ?? 1;
for (let i = 0; i < token.items.length; i++) {
const item = token.items[i];
const bullet = token.ordered ? `${i + 1}. ` : "- ";
const bullet = token.ordered ? `${startNumber + i}. ` : "- ";
// Process item tokens to handle nested lists
const itemLines = this.renderListItem(item.tokens || [], depth);

View file

@ -108,6 +108,43 @@ describe("Markdown component", () => {
assert.ok(plainLines.some((line) => line.includes(" - Unordered nested")));
assert.ok(plainLines.some((line) => line.includes("2. Second ordered")));
});
it("should maintain numbering when code blocks are not indented (LLM output)", () => {
// When code blocks aren't indented, marked parses each item as a separate list.
// We use token.start to preserve the original numbering.
const markdown = new Markdown(
`1. First item
\`\`\`typescript
// code block
\`\`\`
2. Second item
\`\`\`typescript
// another code block
\`\`\`
3. Third item`,
0,
0,
defaultMarkdownTheme,
);
const lines = markdown.render(80);
const plainLines = lines.map((line) => line.replace(/\x1b\[[0-9;]*m/g, "").trim());
// Find all lines that start with a number and period
const numberedLines = plainLines.filter((line) => /^\d+\./.test(line));
// Should have 3 numbered items
assert.strictEqual(numberedLines.length, 3, `Expected 3 numbered items, got: ${numberedLines.join(", ")}`);
// Check the actual numbers
assert.ok(numberedLines[0].startsWith("1."), `First item should be "1.", got: ${numberedLines[0]}`);
assert.ok(numberedLines[1].startsWith("2."), `Second item should be "2.", got: ${numberedLines[1]}`);
assert.ok(numberedLines[2].startsWith("3."), `Third item should be "3.", got: ${numberedLines[2]}`);
});
});
describe("Tables", () => {