You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CJK characters break some features like @ mentions #3734
props.input().visualCursor.offset is based on Unicode codepoints and counts 世界 @ as 5, while props.value.at counts it as 3. Also props.input().logicalCursor.offset returns 5.
Looking more closely at input, it seems expected behaviour in the test.
I'm not sure what logical means here, but maybe it should returns 3? Or to align JavaScript side to zig implementation, Bun.stringWidth looks similar but has some difference like \n proceed the cursor by 1 but Bun.stringWidth returns 0.
All of these issues seem to stem from similar underlying problems with Unicode/CJK character handling in the TUI components. The root cause appears to be inconsistent character width calculation between Unicode codepoints and display width, which is exactly what you've identified in the autocomplete.tsx file.
Feel free to ignore if none of these address your specific case with @ mention autocomplete functionality.
That is a tricky one. The 3 is in "number of utf16 characters", while the 5 is in "in number of terminal cells", so visualCursor.offset is actually number of cells. Currently the underlying EditBuffer in zig uses "number of cells occupied" as main coordinate system for the cursor. Which is bad.
However, there are methods to convert to a byte offset. So I think opentui needs to expose some methods to work with the Editbuffer properly.
String.at is not grapheme aware, it coincidentally works in this specific case, but for combining characters like acutes or devanagari viramas it would treat the combining chars as separate chars.
I think the simplest solution to make this work properly, without going into the huge refactor that is needed for the text handling in opentui, is exposing a getTextRange method for the TextBuffer in opentui, so opencode can use that instead of String.at. Then charBeforeCursor would be something like input.getTextRange(cursor.offset - 1, cursor.offset). I'll check how hard it would be to implement that. Would at least make it reliable for now, no matter how opentui treats text internally.
@kommander Thanks, the problem of auto-completion is solved!
Syntax highlighting is still broken. It seems that extmarks from opentui is based on terminal cells while PromptInfo.parts is based on UTF16 characters.
Activity
[-]CJK characters break features like `@` mentions[/-][+]CJK characters break some features like `@` mentions[/+]github-actions commentedon Nov 2, 2025
This issue might be a duplicate of existing issues. Please check:
All of these issues seem to stem from similar underlying problems with Unicode/CJK character handling in the TUI components. The root cause appears to be inconsistent character width calculation between Unicode codepoints and display width, which is exactly what you've identified in the autocomplete.tsx file.
Feel free to ignore if none of these address your specific case with @ mention autocomplete functionality.
yukukotani commentedon Nov 2, 2025
@kommander FYI since I assume you are working on this
yukukotani commentedon Nov 2, 2025
I can take this on if I get a bit of guidance on the right approach.
kommander commentedon Nov 2, 2025
That is a tricky one. The 3 is in "number of utf16 characters", while the 5 is in "in number of terminal cells", so
visualCursor.offsetis actually number of cells. Currently the underlyingEditBufferin zig uses "number of cells occupied" as main coordinate system for the cursor. Which is bad.However, there are methods to convert to a byte offset. So I think opentui needs to expose some methods to work with the Editbuffer properly.
String.atis not grapheme aware, it coincidentally works in this specific case, but for combining characters like acutes or devanagari viramas it would treat the combining chars as separate chars.For example 世 is U+4E16 in three utf8 bytes.
Edit: I'll follow up on this.
kommander commentedon Nov 3, 2025
I think the simplest solution to make this work properly, without going into the huge refactor that is needed for the text handling in opentui, is exposing a
getTextRangemethod for theTextBufferin opentui, so opencode can use that instead ofString.at. ThencharBeforeCursorwould be something likeinput.getTextRange(cursor.offset - 1, cursor.offset). I'll check how hard it would be to implement that. Would at least make it reliable for now, no matter how opentui treats text internally.use new opentui getTextRange method and Bun.stringWidth instead of va…
kommander commentedon Nov 3, 2025
This should be mitigated in
1.0.16yukukotani commentedon Nov 3, 2025
@kommander Thanks, the problem of auto-completion is solved!
Syntax highlighting is still broken. It seems that
extmarksfrom opentui is based on terminal cells whilePromptInfo.partsis based on UTF16 characters.https://github.com/sst/opencode/blob/d06afd87e5a0325730b11478eb49af4ced12608a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx#L87-L108
fix CJK extmarks sim offsets (#308)
kommander commentedon Nov 13, 2025
Should be better in the latest version?
zenyr commentedon Nov 27, 2025
Update as of v1.0.117
The original issue seems mostly fixed ~2 weeks ago

👇 Working fine now 👍
However

[Pasted]is a bit broken AFTER submitting👇 CJK/Emojis breaking
[Pasted]marker 🥲 (Before & after)fix CJK extmarks sim offsets (#308)
use new opentui getTextRange method and Bun.stringWidth instead of va…
use new opentui getTextRange method and Bun.stringWidth instead of va…
use new opentui getTextRange method and Bun.stringWidth instead of va…