Skip to content

fix: scroll offset_x by visual width, not char count, in focus() - #16

Open
slaptijack wants to merge 1 commit into
vipmax:masterfrom
slaptijack:slaptijack/fix-focus-wide-glyph-scroll
Open

fix: scroll offset_x by visual width, not char count, in focus()#16
slaptijack wants to merge 1 commit into
vipmax:masterfrom
slaptijack:slaptijack/fix-focus-wide-glyph-scroll

Conversation

@slaptijack

Copy link
Copy Markdown

Summary

  • Editor::focus() decided whether to scroll horizontally by comparing the cursor's raw character-count column against the viewport width, which under-counts the true display width of lines containing double-width glyphs (CJK, emoji). This could leave the cursor off-screen while focus() believed no scroll was needed, disagreeing with get_visible_cursor(), which already accounts for grapheme display width.
  • focus() now computes the cursor's and offset_x's visual columns the same way get_visible_cursor() does (summing grapheme widths), and resolves scroll targets back to a character index via a new char_idx_for_visual_col() helper.

Fixes #15

Test plan

  • Added focus_scrolls_horizontally_for_wide_glyph_lines in tests/input.rs, reproducing the issue's repro case (a 20-character line of , 40-cell-wide viewport) — cursor now stays visible after focus().
  • cargo test (33 tests across lib + integration suites) passes.
  • cargo clippy --all-targets shows no new warnings from this change.

focus() compared the cursor's raw character-count column against the
viewport width when deciding whether to scroll horizontally. For lines
with double-width glyphs (CJK, emoji), character count under-estimates
the true display width, so focus() could decide no scroll was needed
while the cursor was actually off-screen — disagreeing with
get_visible_cursor(), which already computes visual columns correctly
via grapheme widths.

focus() now computes cursor/offset_x visual columns the same way
get_visible_cursor() does, and resolves scroll targets back to a char
index via a new char_idx_for_visual_col() helper.

Fixes vipmax#15
slaptijack added a commit to slaptijack/human-exception that referenced this pull request Aug 28, 2026
## Summary
- Qualifies the unconditional viewport guarantee in `docs/TUI_DESIGN.md`
("The vertical and horizontal viewport auto-scrolls to keep the cursor
visible...") with the accepted, temporary `ratatui-code-editor` 0.0.6
wide-glyph limitation already characterized in
`tests/editor_foundation_contract.rs`.
- Adds a new "Known limitation: wide-glyph cursor visibility" subsection
distinguishing affected behavior (long lines of wide/double-width glyphs
requiring horizontal scroll) from unaffected behavior (ASCII long lines,
short wide-glyph content, combining marks, exact Unicode round-trip),
each backed by an existing test.
- Links the upstream tracking issue
([vipmax/ratatui-code-editor#15](vipmax/ratatui-code-editor#15))
and proposed fix
([vipmax/ratatui-code-editor#16](vipmax/ratatui-code-editor#16)).
- Spells out the future resolution procedure (dependency-upgrade issue →
upgrade → flip the characterization assertion → verify via foundation
contract + Controller `TestBackend` → remove this doc section).
- Documentation-only; no source or test changes.
`known_limitation_wide_glyph_line_can_leave_cursor_offscreen_after_focus`
already fails conspicuously (per its own comment) once the upstream
behavior changes.

Closes #125

## Test plan
- [x] `cargo fmt --check`
- [x] `cargo clippy --locked --all-targets --all-features -- -D
warnings`
- [x] `cargo test --locked --all-targets --all-features`
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.

focus() doesn't scroll horizontally for wide-glyph lines, leaving the cursor off-screen

1 participant