mirror of
https://github.com/earendil-works/pi.git
synced 2026-10-02 00:35:27 +08:00
fix(tui): preserve ANSI order at slice boundaries
Fixes color bleeding after mouse selection and search highlights in fullscreen mode when a styled token ends at the highlight boundary. closes #10169
This commit is contained in:
@@ -6,6 +6,10 @@
|
||||
|
||||
- Added `TuiAltScreen.getScreenLines()`, which returns the lines of the last rendered frame.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed color bleeding past mouse selections and search highlights in fullscreen mode when a styled token ends at the highlight boundary ([#10169](https://github.com/earendil-works/pi/issues/10169))
|
||||
|
||||
## [0.99.2] - 2026-09-30
|
||||
|
||||
## [0.99.1] - 2026-09-29
|
||||
|
||||
@@ -1273,8 +1273,11 @@ export function sliceWithWidth(
|
||||
while (i < line.length) {
|
||||
const ansi = extractAnsiCode(line, i);
|
||||
if (ansi) {
|
||||
if (currentCol >= startCol && currentCol < endCol) result += ansi.code;
|
||||
else if (currentCol < startCol) pendingAnsi += ansi.code;
|
||||
if (currentCol >= startCol && currentCol < endCol) {
|
||||
// Keep original order: codes from before the range must precede codes at the boundary
|
||||
result += pendingAnsi + ansi.code;
|
||||
pendingAnsi = "";
|
||||
} else if (currentCol < startCol) pendingAnsi += ansi.code;
|
||||
i += ansi.length;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, it } from "node:test";
|
||||
import { sliceByColumn } from "../src/utils.ts";
|
||||
|
||||
// https://github.com/earendil-works/pi/issues/10169
|
||||
describe("sliceByColumn ANSI order regression", () => {
|
||||
it("keeps a reset at the slice start after earlier style codes", () => {
|
||||
const line = "\x1b[32mfoo\x1b[39m bar";
|
||||
assert.strictEqual(sliceByColumn(line, 3, 4, true), "\x1b[32m\x1b[39m bar");
|
||||
});
|
||||
|
||||
it("does not leak color into text after a highlighted token", () => {
|
||||
const line = "Another \x1b[35malpha\x1b[39m line with \x1b[35mbeta\x1b[39m later.";
|
||||
const after = sliceByColumn(line, 13, 100, true);
|
||||
assert.strictEqual(after, "\x1b[35m\x1b[39m line with \x1b[35mbeta\x1b[39m later.");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user