prompt: fix cursor math for wide characters (#27017)

String.length counts code points, not display columns, so CJK
characters and emoji that occupy two terminal cells caused
misaligned cursors, broken mention triggers, and incorrect
history restoration offsets.

Use Bun.stringWidth for now, we need an alternative for this.

Fix #26716
Close #26922
This commit is contained in:
Simon Klee
2026-05-12 11:45:28 +02:00
committed by GitHub
parent d276d96cdf
commit 8f05bbfaa6
5 changed files with 113 additions and 29 deletions
@@ -12,6 +12,7 @@
// The leader-key cycle (promptCycle) uses a two-step pattern: first press
// arms the leader, second press within the timeout fires the action.
import type { KeyBinding } from "@opentui/core"
export { displayCharAt, displaySlice, mentionTriggerIndex } from "../prompt-display"
import { formatBinding, parseBindings } from "./keymap.shared"
import type { FooterKeybinds, RunPrompt } from "./types"
@@ -275,7 +276,7 @@ export function movePromptHistory(state: PromptHistoryState, dir: -1 | 1, text:
return { state, apply: false }
}
if (dir === 1 && cursor !== text.length) {
if (dir === 1 && cursor !== Bun.stringWidth(text)) {
return { state, apply: false }
}
@@ -309,7 +310,7 @@ export function movePromptHistory(state: PromptHistoryState, dir: -1 | 1, text:
index: null,
},
text: state.draft,
cursor: state.draft.length,
cursor: Bun.stringWidth(state.draft),
apply: true,
}
}
@@ -320,7 +321,7 @@ export function movePromptHistory(state: PromptHistoryState, dir: -1 | 1, text:
index: idx,
},
text: state.items[idx].text,
cursor: dir === -1 ? 0 : state.items[idx].text.length,
cursor: dir === -1 ? 0 : Bun.stringWidth(state.items[idx].text),
apply: true,
}
}