@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed `Input` horizontal scrolling for wide Unicode text (CJK, fullwidth characters) to use visual column width instead of string length, preventing rendered line overflow and TUI crashes ([#1982](https://github.com/badlogic/pi-mono/issues/1982))
|
- Fixed `Input` horizontal scrolling for wide Unicode text (CJK, fullwidth characters) to use visual column width and strict slice boundaries, preventing rendered line overflow and TUI crashes ([#1982](https://github.com/badlogic/pi-mono/issues/1982))
|
||||||
|
|
||||||
## [0.57.1] - 2026-03-07
|
## [0.57.1] - 2026-03-07
|
||||||
|
|
||||||
|
|||||||
@@ -468,8 +468,8 @@ export class Input implements Component, Focusable {
|
|||||||
startCol = Math.max(0, cursorCol - halfWidth);
|
startCol = Math.max(0, cursorCol - halfWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
visibleText = sliceByColumn(this.value, startCol, scrollWidth);
|
visibleText = sliceByColumn(this.value, startCol, scrollWidth, true);
|
||||||
const beforeCursor = sliceByColumn(this.value, startCol, Math.max(0, cursorCol - startCol));
|
const beforeCursor = sliceByColumn(this.value, startCol, Math.max(0, cursorCol - startCol), true);
|
||||||
cursorDisplay = beforeCursor.length;
|
cursorDisplay = beforeCursor.length;
|
||||||
} else {
|
} else {
|
||||||
visibleText = "";
|
visibleText = "";
|
||||||
|
|||||||
@@ -43,15 +43,28 @@ describe("Input component", () => {
|
|||||||
"这是一段测试文本,用于验证中文字符在终端中的显示宽度是否被正确计算,如果不正确就会导致用户界面崩溃的问题",
|
"这是一段测试文本,用于验证中文字符在终端中的显示宽度是否被正确计算,如果不正确就会导致用户界面崩溃的问题",
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklm",
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklm",
|
||||||
];
|
];
|
||||||
|
const cursorPositions = [
|
||||||
|
{ label: "start", move: (_input: Input) => {} },
|
||||||
|
{
|
||||||
|
label: "middle",
|
||||||
|
move: (input: Input) => {
|
||||||
|
for (let i = 0; i < 10; i++) input.handleInput("\x1b[C");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ label: "end", move: (input: Input) => input.handleInput("\x05") },
|
||||||
|
];
|
||||||
|
|
||||||
for (const text of cases) {
|
for (const text of cases) {
|
||||||
const input = new Input();
|
for (const { label, move } of cursorPositions) {
|
||||||
input.setValue(text);
|
const input = new Input();
|
||||||
input.focused = true;
|
input.setValue(text);
|
||||||
|
input.focused = true;
|
||||||
|
move(input);
|
||||||
|
|
||||||
const [line] = input.render(width);
|
const [line] = input.render(width);
|
||||||
assert.ok(line);
|
assert.ok(line);
|
||||||
assert.ok(visibleWidth(line) <= width, `rendered line overflowed for ${text}`);
|
assert.ok(visibleWidth(line) <= width, `rendered line overflowed for ${text} at ${label}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user