Skip to content

Conversation

@soifou
Copy link
Collaborator

@soifou soifou commented Nov 14, 2025

Fixes ghost text display with multibyte characters showing as gibberish. Was using byte offsets instead of character counts, now properly uses strchars() and strcharpart() for UTF-8 handling.

Demo Before:
2025-11-14_12-25-59.mp4

After:

2025-11-14_12-27-10.mp4

Also addresses a few fixes for noice.nvim ; the ghost text did not appear in cmdline for some context, e.g. :cd<Space> and an extra redraw was making the search highlighted text blinking.

Refactored to keep only the event-driven architecture:

  • Removed decoration provider in favor of explicit list events
  • Pass context object to avoid repeated mode/line lookups
  • Drop TextChangedI but retained CursorMovedI autocmd to prevent text shaking during typing.

Overall this translate in a small performance improvements. The draw calls are reduced by 22-29% and total CPU time reduced by 9-95% depending on operation.

Performance benchmarks details

Typing vim.fn.getcmdtype with slow typing, fast typing, and extended 500-iteration test.

Draw Preview Performance

Branch Test Type Calls Total Time Avg per Call vs Main
Main Slow 56 11.29ms 0.20ms baseline
Main Fast 45 5.79ms 0.13ms baseline
Main 500 iterations 500 31.22ms 0.06ms baseline
PR Slow 40 9.25ms 0.23ms 29% fewer calls, 18% faster
PR Fast 35 5.07ms 0.14ms 22% fewer calls, 12% faster
PR 500 iterations 500 28.35ms 0.06ms 9% faster

Show Preview Performance

Branch Test Type Calls Total Time Avg per Call vs Main
Main Slow 24 2.35ms 0.10ms baseline
Main Fast 21 1.76ms 0.08ms baseline
Main 500 iterations 500 21.49ms 0.04ms baseline
PR Slow 24 0.13ms 0.01ms 94% faster
PR Fast 21 0.09ms <0.01ms 95% faster
PR 500 iterations 500 2.34ms <0.01ms 89% faster

saghen

This comment was marked as resolved.

@soifou soifou force-pushed the fix/ghost-multibyte branch 2 times, most recently from 995f185 to 833138e Compare November 15, 2025 15:47
@soifou

This comment was marked as outdated.

@soifou soifou marked this pull request as draft November 15, 2025 17:01
@soifou soifou force-pushed the fix/ghost-multibyte branch 2 times, most recently from 48dbb8d to 17e6005 Compare November 15, 2025 17:21
Fixes ghost text displaying gibberish with multibyte characters. Now
uses `vim.fn.strchars()` and `vim.fn.strcharpart()` for proper UTF-8
handling instead of byte-based string operations.

Also addresses a few fixes for noice.nvim ; the ghost text did not
appear in cmdline for some context, e.g. `:cd<Space>` and an extra
redraw was making the search highlighted text blinking.

Refactored to keep only the event-driven architecture:
- Removed decoration provider in favor of explicit list events
- Pass context object to avoid repeated mode/line lookups
- Drop `TextChangedI` but retained `CursorMovedI` autocmd to prevent
  text shaking during typing.

Overall this translate in a small performance improvements. The draw
calls are reduced by 22-29% and total CPU time reduced by 9-95%
depending on operation.
@soifou soifou force-pushed the fix/ghost-multibyte branch from 17e6005 to 738133d Compare November 19, 2025 00:11
@soifou
Copy link
Collaborator Author

soifou commented Nov 19, 2025

Pushed an update, I took another stab at it. Details are in the PR description. LGTM I've been using it for 24 hours and haven't seen any regressions.

@soifou soifou marked this pull request as ready for review November 19, 2025 16:48
@soifou soifou requested a review from saghen November 19, 2025 16:49
@soifou soifou changed the title fix(ghost_text): handle multibyte characters and reduce render calls refactor(ghost_text): handle multibyte characters and reduce render calls Nov 19, 2025
@saghen saghen merged commit 73ea297 into main Nov 19, 2025
6 checks passed
@saghen
Copy link
Owner

saghen commented Nov 19, 2025

Brilliant, thank you!

@soifou soifou deleted the fix/ghost-multibyte branch November 19, 2025 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants