mirror of
https://github.com/aphrody-labs/opentui.git
synced 2026-10-14 05:09:27 +00:00
Up and Down kept the desired display column and committed it as is. When the target line had a wide character (CJK, emoji) or a tab at that column, the cursor landed on its second cell: the logical moves (`moveUp`/`moveDown`), the visual moves that Textarea's arrow keys use (`moveUpVisual`/`moveDownVisual`, also Shift+Up/Down), and `setViewport(..., moveCursor = true)`. The terminal cursor was drawn in the middle of the character, and typed text went in front of it while the cursor moved on to the next mid-character column. Each of these now passes its column through `EditBuffer.snapColumn`, which returns the start of the cursor unit under the column. Left/Right and mouse clicks already snap to that start. The desired column stays unsnapped, so the cursor returns to it on the next line that has a boundary there. A cursor unit never spans two virtual lines, so the snapped column stays on the target visual row. Source additions: `snapColumn` is the one shared snap (3 call sites); `moveToRow` replaces the two copies of the move body in `moveUp` and `moveDown`; `makeCursorVisible` keeps an unsnapped desired column in its own variable. Tests: one table in `editor-view_test.zig` replaces seven vertical-move tests (each old assertion is a row, most now exact) and adds CJK, tab, skin-tone and ZWJ emoji rows for both width methods, the https://github.com/anomalyco/opentui/issues/1289 lines, a wrapped https://github.com/anomalyco/opentui/issues/1289 line, and `setViewport(moveCursor)`. The seeded Textarea model test presses Up/Down and requires a grapheme boundary. The Textarea Shift+Up/Down tests become one table with the https://github.com/anomalyco/opentui/issues/1289 rows in both selection occupancies. One `editor-view.test.ts` assertion pinned the mid-emoji column 8; it is now 7. Issue: 001 Fixes https://github.com/anomalyco/opentui/issues/1289