From 33b24890e92cb099f8f0cea637fc0e73fbbf8d0d Mon Sep 17 00:00:00 2001 From: Hyunsoo Lee Date: Sat, 4 Apr 2026 17:06:26 +0900 Subject: [PATCH] fix(opencode): reconstruct pasted prompt text after wide characters --- .../cli/cmd/tui/component/prompt/index.tsx | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 382bd2806ec7..79ec4133062f 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -72,6 +72,22 @@ function randomIndex(count: number) { return Math.floor(Math.random() * count) } +function locate(text: string, width: number) { + if (width <= 0) return 0 + + let seen = 0 + let idx = 0 + for (const char of text) { + const span = Bun.stringWidth(char) + const next = seen + span + if (next >= width) return next === width ? idx + char.length : idx + seen = next + idx += char.length + } + + return idx +} + export function Prompt(props: PromptProps) { let input: TextareaRenderable let anchor: BoxRenderable @@ -642,8 +658,10 @@ export function Prompt(props: PromptProps) { if (partIndex !== undefined) { const part = store.prompt.parts[partIndex] if (part?.type === "text" && part.text) { - const before = inputText.slice(0, extmark.start) - const after = inputText.slice(extmark.end) + const start = locate(inputText, extmark.start) + const end = locate(inputText, extmark.end) + const before = inputText.slice(0, start) + const after = inputText.slice(end) inputText = before + part.text + after } }