mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-17 04:12:25 +00:00
Fix multiline mentions (#27649)
This commit is contained in:
parent
aa07e21945
commit
0f31fd631b
2 changed files with 20 additions and 5 deletions
|
|
@ -1,11 +1,20 @@
|
|||
const graphemes = new Intl.Segmenter(undefined, { granularity: "grapheme" })
|
||||
|
||||
function promptOffsetWidth(value: string) {
|
||||
let width = 0
|
||||
for (const part of graphemes.segment(value)) {
|
||||
// Textarea offsets count newlines as one position; Bun.stringWidth counts them as zero.
|
||||
width += part.segment === "\n" ? 1 : Bun.stringWidth(part.segment)
|
||||
}
|
||||
return width
|
||||
}
|
||||
|
||||
function displayOffsetIndex(value: string, offset: number) {
|
||||
if (offset <= 0) return 0
|
||||
|
||||
let width = 0
|
||||
for (const part of graphemes.segment(value)) {
|
||||
const next = width + Bun.stringWidth(part.segment)
|
||||
const next = width + promptOffsetWidth(part.segment)
|
||||
if (next > offset) return part.index
|
||||
width = next
|
||||
}
|
||||
|
|
@ -13,20 +22,20 @@ function displayOffsetIndex(value: string, offset: number) {
|
|||
return value.length
|
||||
}
|
||||
|
||||
export function displaySlice(value: string, start = 0, end = Bun.stringWidth(value)) {
|
||||
export function displaySlice(value: string, start = 0, end = promptOffsetWidth(value)) {
|
||||
return value.slice(displayOffsetIndex(value, start), displayOffsetIndex(value, end))
|
||||
}
|
||||
|
||||
export function displayCharAt(value: string, offset: number) {
|
||||
let width = 0
|
||||
for (const part of graphemes.segment(value)) {
|
||||
const next = width + Bun.stringWidth(part.segment)
|
||||
const next = width + promptOffsetWidth(part.segment)
|
||||
if (offset === width || offset < next) return part.segment
|
||||
width = next
|
||||
}
|
||||
}
|
||||
|
||||
export function mentionTriggerIndex(value: string, offset = Bun.stringWidth(value)) {
|
||||
export function mentionTriggerIndex(value: string, offset = promptOffsetWidth(value)) {
|
||||
const text = displaySlice(value, 0, offset)
|
||||
const index = text.lastIndexOf("@")
|
||||
if (index === -1) return
|
||||
|
|
@ -34,6 +43,6 @@ export function mentionTriggerIndex(value: string, offset = Bun.stringWidth(valu
|
|||
const before = index === 0 ? undefined : text[index - 1]
|
||||
const query = text.slice(index)
|
||||
if ((before === undefined || /\s/.test(before)) && !/\s/.test(query)) {
|
||||
return Bun.stringWidth(text.slice(0, index))
|
||||
return promptOffsetWidth(text.slice(0, index))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,12 @@ describe("run prompt shared", () => {
|
|||
expect(mentionTriggerIndex("👨👩👧👦 @src", Bun.stringWidth("👨👩👧👦 @src"))).toBe(3)
|
||||
expect(displayCharAt("👨👩👧👦 @src", Bun.stringWidth("👨👩👧👦 @"))).toBe("s")
|
||||
expect(displaySlice("👨👩👧👦 @src", 3, Bun.stringWidth("👨👩👧👦 @src"))).toBe("@src")
|
||||
expect(mentionTriggerIndex("@file1\n@file2", 13)).toBe(7)
|
||||
expect(displayCharAt("@file1\n@file2", 6)).toBe("\n")
|
||||
expect(displaySlice("@file1\n@file2", 8, 13)).toBe("file2")
|
||||
expect(mentionTriggerIndex("@file1\nfoo @file2", 17)).toBe(11)
|
||||
expect(mentionTriggerIndex("中文 @one\n@two", 14)).toBe(10)
|
||||
expect(displaySlice("中文 @one\n@two", 11, 14)).toBe("two")
|
||||
expect(mentionTriggerIndex("中文@")).toBeUndefined()
|
||||
expect(mentionTriggerIndex("こんにちは@")).toBeUndefined()
|
||||
expect(mentionTriggerIndex("한국어@")).toBeUndefined()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue