Simon Klee 07225659bb native: snap vertical cursor moves to the start of a wide character (#1596)
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
2026-10-09 14:01:59 +02:00
2025-07-21 17:47:38 +02:00
2026-03-23 15:59:52 +01:00
2026-10-08 10:21:20 +02:00
2025-08-12 12:01:55 +02:00
2026-10-07 20:55:43 +02:00
2026-09-04 21:09:49 +02:00

OpenTUI logo

npm version Core build status

OpenTUI is a library to build terminal user interfaces.

  • It is written in Zig.
  • You write TypeScript directly or through React and Solid.
  • You arrange boxes and text with flexbox.
  • You add selects, inputs, and scroll boxes with keyboard and mouse controls.
  • You can play sounds, show images, and render 3D graphics.

OpenCode uses OpenTUI in production for millions of users.

Website | Documentation | Packages

Packages

  • @opentui/core - Native terminal UI library with TypeScript bindings.
  • @opentui/react - React renderer for building terminal user interfaces with OpenTUI Core.
  • @opentui/solid - Solid renderer for building terminal user interfaces with OpenTUI Core.
  • @opentui/keymap - Key binding and command routing library for terminal and browser applications.
  • @opentui/qrcode - QR code encoder and renderable with React and Solid surfaces.
  • @opentui/three - Three.js WebGPU renderer for OpenTUI.
  • @opentui/ssh - SSH server integration for OpenTUI applications.

Private packages

  • @opentui/native - Private workspace with the Zig implementation, native tests, and benchmarks.
  • @opentui/examples - Private workspace with example applications and a standalone examples executable.
  • @opentui/web - Private workspace with the documentation website and the AI agent skill.

AI agent skill

Install the OpenTUI documentation as a skill for your AI coding assistant with npx skills:

npx skills add anomalyco/opentui --skill opentui

Add -g to install the skill globally.

Development

Development requires Bun 1.4.1 or later and Zig 0.16.0.

See AGENTS.md for engineering, tooling, and verification conventions.

bun install

Run package scripts from their package directory. Run bun run build from the repository root after you change native code or cross-package build outputs. Ordinary TypeScript changes do not require a root build.

Run repository tests and static checks from the repository root:

bun run test
bun run fmt:check
bun run lint

To link the source packages into a Bun-managed project, install that project's dependencies, then run ./scripts/link-opentui-dev.sh /path/to/project from the repository root. Add --react or --solid when needed.

Contributing

OpenTUI is open for contributions.

License

OpenTUI is licensed under the MIT License.

S
Description
No description provided
Readme MIT
75 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 63.1%
Zig 27.8%
MDX 6.1%
C 1%
Astro 0.8%
Other 1.1%