fix(tui): stop heading underline leaking into padding
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed markdown H1 headings ending with inline code from leaking underline styling into trailing line padding
|
||||||
- Fixed slash-command argument autocomplete to await async `getArgumentCompletions()` results and ignore invalid return values, preventing crashes when extension commands provide asynchronous completions ([#2719](https://github.com/badlogic/pi-mono/issues/2719))
|
- Fixed slash-command argument autocomplete to await async `getArgumentCompletions()` results and ignore invalid return values, preventing crashes when extension commands provide asynchronous completions ([#2719](https://github.com/badlogic/pi-mono/issues/2719))
|
||||||
|
|
||||||
## [0.64.0] - 2026-03-29
|
## [0.64.0] - 2026-03-29
|
||||||
|
|||||||
@@ -505,6 +505,10 @@ export class Markdown implements Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (stylePrefix && result.endsWith(stylePrefix)) {
|
||||||
|
result = result.slice(0, -stylePrefix.length);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ function getCellItalic(terminal: VirtualTerminal, row: number, col: number): num
|
|||||||
return cell.isItalic();
|
return cell.isItalic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCellUnderline(terminal: VirtualTerminal, row: number, col: number): number {
|
||||||
|
const xterm = (terminal as unknown as { xterm: XtermTerminalType }).xterm;
|
||||||
|
const buffer = xterm.buffer.active;
|
||||||
|
const line = buffer.getLine(buffer.viewportY + row);
|
||||||
|
assert.ok(line, `Missing buffer line at row ${row}`);
|
||||||
|
const cell = line.getCell(col);
|
||||||
|
assert.ok(cell, `Missing cell at row ${row} col ${col}`);
|
||||||
|
return cell.isUnderline();
|
||||||
|
}
|
||||||
|
|
||||||
describe("Markdown component", () => {
|
describe("Markdown component", () => {
|
||||||
describe("Nested lists", () => {
|
describe("Nested lists", () => {
|
||||||
it("should render simple nested list", () => {
|
it("should render simple nested list", () => {
|
||||||
@@ -1016,6 +1026,26 @@ bar`,
|
|||||||
assert.ok(precedingChunk.includes("\x1b[4m"), `Should re-apply underline for h1: ${precedingChunk}`);
|
assert.ok(precedingChunk.includes("\x1b[4m"), `Should re-apply underline for h1: ${precedingChunk}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not leak h1 underline into padding when inline code is the last token", async () => {
|
||||||
|
const markdown = new Markdown("# Important distinction from `open()`", 0, 0, defaultMarkdownTheme);
|
||||||
|
const terminal = new VirtualTerminal(80, 4);
|
||||||
|
const tui = new TUI(terminal);
|
||||||
|
tui.addChild(markdown);
|
||||||
|
tui.start();
|
||||||
|
await terminal.flush();
|
||||||
|
|
||||||
|
const renderedLine = markdown.render(80)[0];
|
||||||
|
assert.ok(renderedLine, "Should render heading line");
|
||||||
|
const contentWidth = renderedLine.replace(/\x1b\[[0-9;]*m/g, "").trimEnd().length;
|
||||||
|
assert.ok(contentWidth > 0, "Should have visible heading content");
|
||||||
|
|
||||||
|
for (let col = contentWidth; col < 80; col++) {
|
||||||
|
assert.strictEqual(getCellUnderline(terminal, 0, col), 0, `Expected no underline in padding at col ${col}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
tui.stop();
|
||||||
|
});
|
||||||
|
|
||||||
it("should preserve heading styling after bold text", () => {
|
it("should preserve heading styling after bold text", () => {
|
||||||
const markdown = new Markdown("## Heading with **bold** and more", 0, 0, defaultMarkdownTheme);
|
const markdown = new Markdown("## Heading with **bold** and more", 0, 0, defaultMarkdownTheme);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user