use new opentui getTextRange method and Bun.stringWidth instead of value.length to mitigate issues like #3734

This commit is contained in:
Sebastian Herrlinger
2025-11-03 15:15:55 +01:00
parent d549cd3213
commit 6deaf54bb3
3 changed files with 24 additions and 16 deletions

View File

@@ -54,8 +54,8 @@
"@opencode-ai/plugin": "workspace:*",
"@opencode-ai/script": "workspace:*",
"@opencode-ai/sdk": "workspace:*",
"@opentui/core": "0.1.32",
"@opentui/solid": "0.1.32",
"@opentui/core": "0.1.33",
"@opentui/solid": "0.1.33",
"@parcel/watcher": "2.5.1",
"@solid-primitives/event-bus": "1.1.2",
"@pierre/precision-diffs": "catalog:",

View File

@@ -49,7 +49,12 @@ export function Autocomplete(props: {
})
const filter = createMemo(() => {
if (!store.visible) return
return props.value.substring(store.index + 1).split(" ")[0]
// Track props.value to make memo reactive to text changes
props.value // <- there surely is a better way to do this, like making .input() reactive
const val = props.input().getTextRange(store.index + 1, props.input().visualCursor.offset + 1)
return val
})
function insertPart(text: string, part: PromptInfo["parts"][number]) {
@@ -70,7 +75,7 @@ export function Autocomplete(props: {
const virtualText = "@" + text
const extmarkStart = store.index
const extmarkEnd = extmarkStart + virtualText.length
const extmarkEnd = extmarkStart + Bun.stringWidth(virtualText)
const styleId =
part.type === "file"
@@ -364,7 +369,7 @@ export function Autocomplete(props: {
return store.visible
},
onInput(value: string) {
if (store.visible && value.length <= store.index) hide()
if (store.visible && Bun.stringWidth(value) <= store.index) hide()
},
onKeyDown(e: KeyEvent) {
if (store.visible) {
@@ -378,7 +383,10 @@ export function Autocomplete(props: {
if (e.name === "@") {
const cursorOffset = props.input().visualCursor.offset
const charBeforeCursor =
cursorOffset === 0 ? undefined : props.value.at(cursorOffset - 1)
cursorOffset === 0
? undefined
: props.input().getTextRange(cursorOffset - 1, cursorOffset)
if (
charBeforeCursor === " " ||
charBeforeCursor === "\n" ||