mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 20:04:55 +00:00
fix(tui): avoid split of emojis when scrolling input
This commit is contained in:
parent
c983bfdb1e
commit
99c78b91cb
1 changed files with 32 additions and 5 deletions
|
|
@ -289,18 +289,45 @@ export class Input implements Component, Focusable {
|
||||||
const scrollWidth = this.cursor === this.value.length ? availableWidth - 1 : availableWidth;
|
const scrollWidth = this.cursor === this.value.length ? availableWidth - 1 : availableWidth;
|
||||||
const halfWidth = Math.floor(scrollWidth / 2);
|
const halfWidth = Math.floor(scrollWidth / 2);
|
||||||
|
|
||||||
|
const findValidStart = (start: number) => {
|
||||||
|
while (start < this.value.length) {
|
||||||
|
const charCode = this.value.charCodeAt(start);
|
||||||
|
// this is low surrogate, not a valid start
|
||||||
|
if (charCode >= 0xdc00 && charCode < 0xe000) {
|
||||||
|
start++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findValidEnd = (end: number) => {
|
||||||
|
while (end > 0) {
|
||||||
|
const charCode = this.value.charCodeAt(end - 1);
|
||||||
|
// this is high surrogate, might be split.
|
||||||
|
if (charCode >= 0xd800 && charCode < 0xdc00) {
|
||||||
|
end--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return end;
|
||||||
|
};
|
||||||
|
|
||||||
if (this.cursor < halfWidth) {
|
if (this.cursor < halfWidth) {
|
||||||
// Cursor near start
|
// Cursor near start
|
||||||
visibleText = this.value.slice(0, scrollWidth);
|
visibleText = this.value.slice(0, findValidEnd(scrollWidth));
|
||||||
cursorDisplay = this.cursor;
|
cursorDisplay = this.cursor;
|
||||||
} else if (this.cursor > this.value.length - halfWidth) {
|
} else if (this.cursor > this.value.length - halfWidth) {
|
||||||
// Cursor near end
|
// Cursor near end
|
||||||
visibleText = this.value.slice(this.value.length - scrollWidth);
|
const start = findValidStart(this.value.length - scrollWidth);
|
||||||
cursorDisplay = scrollWidth - (this.value.length - this.cursor);
|
visibleText = this.value.slice(start);
|
||||||
|
cursorDisplay = this.cursor - start;
|
||||||
} else {
|
} else {
|
||||||
// Cursor in middle
|
// Cursor in middle
|
||||||
const start = this.cursor - halfWidth;
|
const start = findValidStart(this.cursor - halfWidth);
|
||||||
visibleText = this.value.slice(start, start + scrollWidth);
|
visibleText = this.value.slice(start, findValidEnd(start + scrollWidth));
|
||||||
cursorDisplay = halfWidth;
|
cursorDisplay = halfWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue