fix(tui): correct multi-click text selection (#7733)

This commit is contained in:
Volkan Sagcan 2026-08-06 22:25:00 +02:00 • committed by GitHub
parent 6fb2d766ae
commit 171c6b520b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 2 deletions

View file

@ -906,14 +906,14 @@ export class TuiAltScreen extends TuiBase implements ViewportTUI {
maxColumn = Math.min(this.terminal.columns, box.rect.x + box.rect.width, box.clip.x + box.clip.width);
screenSelection = {
start: {
...selection.start,
row: box.rect.y + selection.start.row - selection.start.scrollView.scrollTop,
col: box.rect.x + selection.start.col,
scrollView: selection.start.scrollView,
},
end: {
...selection.end,
row: box.rect.y + selection.end.row - selection.start.scrollView.scrollTop,
col: box.rect.x + selection.end.col,
scrollView: selection.start.scrollView,
},
};
}

View file

@ -763,6 +763,39 @@ describe("TuiAltScreen", () => {
tui.stop();
});
it("does not append whitespace to double-click word highlighting", async () => {
const terminal = new RecordingTerminal(20, 1);
const tui = new TuiAltScreen(terminal);
tui.addChild(new Text("foo bar", 0, 0));
tui.start();
await terminal.waitForRender();
terminal.sendInput("\x1b[<0;1;1M");
terminal.sendInput("\x1b[<0;1;1m");
terminal.sendInput("\x1b[<0;3;1M");
await terminal.waitForRender();
assert.ok(terminal.events.some((event) => event.type === "write" && event.data.includes("foo\x1b[27m")));
tui.stop();
});
it("highlights a complete whitespace segment during a word drag", async () => {
const terminal = new RecordingTerminal(20, 1);
const tui = new TuiAltScreen(terminal);
tui.addChild(new Text("foo bar", 0, 0));
tui.start();
await terminal.waitForRender();
terminal.sendInput("\x1b[<0;1;1M");
terminal.sendInput("\x1b[<0;1;1m");
terminal.sendInput("\x1b[<0;2;1M");
terminal.sendInput("\x1b[<32;4;1M");
await terminal.waitForRender();
assert.ok(terminal.events.some((event) => event.type === "write" && event.data.includes("foo \x1b[27m")));
tui.stop();
});
it("selects whole words on double click, extends word drags, and selects lines on triple click", async () => {
const terminal = new RecordingTerminal(20, 2);
const tui = new TuiAltScreen(terminal);