|
@@ -14,7 +14,10 @@ import { createEffect, createMemo, createResource, createSignal, onCleanup, onMo
|
|
|
import * as Locale from "@/util/locale"
|
|
import * as Locale from "@/util/locale"
|
|
|
import {
|
|
import {
|
|
|
createPromptHistory,
|
|
createPromptHistory,
|
|
|
|
|
+ displayCharAt,
|
|
|
|
|
+ displaySlice,
|
|
|
isExitCommand,
|
|
isExitCommand,
|
|
|
|
|
+ mentionTriggerIndex,
|
|
|
isNewCommand,
|
|
isNewCommand,
|
|
|
movePromptHistory,
|
|
movePromptHistory,
|
|
|
promptCycle,
|
|
promptCycle,
|
|
@@ -537,7 +540,7 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const restore = (value: RunPrompt, cursor = value.text.length) => {
|
|
|
|
|
|
|
+ const restore = (value: RunPrompt, cursor = Bun.stringWidth(value.text)) => {
|
|
|
draft = clonePrompt(value)
|
|
draft = clonePrompt(value)
|
|
|
if (!area || area.isDestroyed) {
|
|
if (!area || area.isDestroyed) {
|
|
|
return
|
|
return
|
|
@@ -546,7 +549,7 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
hide()
|
|
hide()
|
|
|
area.setText(value.text)
|
|
area.setText(value.text)
|
|
|
restoreParts(value.parts)
|
|
restoreParts(value.parts)
|
|
|
- area.cursorOffset = Math.min(cursor, area.plainText.length)
|
|
|
|
|
|
|
+ area.cursorOffset = Math.min(cursor, Bun.stringWidth(area.plainText))
|
|
|
scheduleRows()
|
|
scheduleRows()
|
|
|
area.focus()
|
|
area.focus()
|
|
|
}
|
|
}
|
|
@@ -577,7 +580,7 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
area.setText(text)
|
|
area.setText(text)
|
|
|
clearParts()
|
|
clearParts()
|
|
|
draft = { text: area.plainText, parts: [] }
|
|
draft = { text: area.plainText, parts: [] }
|
|
|
- area.cursorOffset = Math.min(text.length, area.plainText.length)
|
|
|
|
|
|
|
+ area.cursorOffset = Math.min(Bun.stringWidth(text), Bun.stringWidth(area.plainText))
|
|
|
scheduleRows()
|
|
scheduleRows()
|
|
|
area.focus()
|
|
area.focus()
|
|
|
}
|
|
}
|
|
@@ -610,12 +613,13 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (visible() && mode() === "mention") {
|
|
if (visible() && mode() === "mention") {
|
|
|
- if (cursor <= at() || /\s/.test(text.slice(at(), cursor))) {
|
|
|
|
|
|
|
+ const query = displaySlice(text, at(), cursor)
|
|
|
|
|
+ if (cursor <= at() || /\s/.test(query)) {
|
|
|
hide()
|
|
hide()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- setQuery(text.slice(at() + 1, cursor))
|
|
|
|
|
|
|
+ setQuery(displaySlice(text, at() + 1, cursor))
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -623,19 +627,12 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const head = text.slice(0, cursor)
|
|
|
|
|
- const idx = head.lastIndexOf("@")
|
|
|
|
|
- if (idx === -1) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const before = idx === 0 ? undefined : head[idx - 1]
|
|
|
|
|
- const tail = head.slice(idx)
|
|
|
|
|
- if ((before === undefined || /\s/.test(before)) && !/\s/.test(tail)) {
|
|
|
|
|
|
|
+ const idx = mentionTriggerIndex(text, cursor)
|
|
|
|
|
+ if (idx !== undefined) {
|
|
|
setAt(idx)
|
|
setAt(idx)
|
|
|
menu.reset()
|
|
menu.reset()
|
|
|
setMode("mention")
|
|
setMode("mention")
|
|
|
- setQuery(head.slice(idx + 1))
|
|
|
|
|
|
|
+ setQuery(displaySlice(text, idx + 1, cursor))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -782,7 +779,7 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const cursor = area.cursorOffset
|
|
const cursor = area.cursorOffset
|
|
|
- const tail = area.plainText.at(cursor)
|
|
|
|
|
|
|
+ const tail = displayCharAt(area.plainText, cursor)
|
|
|
const append = "@" + next.value + (tail === " " ? "" : " ")
|
|
const append = "@" + next.value + (tail === " " ? "" : " ")
|
|
|
area.cursorOffset = at()
|
|
area.cursorOffset = at()
|
|
|
const start = area.logicalCursor
|
|
const start = area.logicalCursor
|
|
@@ -941,7 +938,8 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const dir = up ? -1 : 1
|
|
const dir = up ? -1 : 1
|
|
|
- if ((dir === -1 && area.cursorOffset === 0) || (dir === 1 && area.cursorOffset === area.plainText.length)) {
|
|
|
|
|
|
|
+ const endOffset = Bun.stringWidth(area.plainText)
|
|
|
|
|
+ if ((dir === -1 && area.cursorOffset === 0) || (dir === 1 && area.cursorOffset === endOffset)) {
|
|
|
move(dir, event)
|
|
move(dir, event)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -955,7 +953,7 @@ export function createPromptState(input: PromptInput): PromptState {
|
|
|
? area.height - 1
|
|
? area.height - 1
|
|
|
: Math.max(0, (area.virtualLineCount ?? 1) - 1)
|
|
: Math.max(0, (area.virtualLineCount ?? 1) - 1)
|
|
|
if (dir === 1 && area.visualCursor.visualRow === end) {
|
|
if (dir === 1 && area.visualCursor.visualRow === end) {
|
|
|
- area.cursorOffset = area.plainText.length
|
|
|
|
|
|
|
+ area.cursorOffset = endOffset
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|