Simon Klee d60641bec2 native: draw a combining mark that starts a chunk (#1651)
A combining mark in another rope chunk than its base glyph was not
drawn. Edits, `TextBuffer.append`, and streamed text split chunks, so
typing U+0301 after `abc` in an editor showed `abc`, while the text held
`abc\u0301`. A chunk of only marks has no columns, and the draw loop
stopped at the chunk's last column, so it never drew the mark. A mark
that starts a chunk with more text was dropped when its base was in the
last column of the target, the viewport, or the scissor, because those
checks ran on the mark's column.

The draw loop now walks the chunk's bytes, and a zero-width cluster
joins the glyph this draw wrote before it as soon as it is read. That
glyph already passed the edge and scissor checks. The skip for chunks
past the right edge waits while such a glyph can still take marks. A
mark with no drawn glyph before it is still dropped: at line start,
after control notation, after a base that is scrolled out or clipped,
and after a truncation ellipsis, which now never takes a mark. A
truncated line's prefix keeps a mark-only chunk that follows its last
glyph. A mark that would change the cluster's width, such as U+FE0F
after a 1-cell glyph, is dropped instead of putting a 2-cell emoji in a
1-cell slot.

The test that attaches marks is now a table. Each row draws split chunks
and the same text in one chunk, through `TextBuffer.append` (controls
hidden) and through editor inserts (controls shown as notation). Rows
vary the x offset, viewport, scissor, wrap, truncation, selection, and
opacity, and name the cell that must hold the mark. Each of eleven
plausible breaks of the change (column loop, chunk skip, attach order,
base reset, ellipsis, prefix, width check) fails a row. In random tests,
split chunks now draw the same as one chunk in every case except joiners
(ZWJ, U+FE0F that widens a glyph), word wrap, and one truncation prefix
shape that main also has.

Fixes #1646
2026-10-12 06:33:25 +02:00
2026-10-11 22:17:57 +02:00
2025-07-21 17:47:38 +02:00
2026-03-23 15:59:52 +01:00
2026-10-11 22:17:57 +02:00
2025-08-12 12:01:55 +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 https://opentui.com --skill opentui

Add -g to install the skill globally. The skill matches the latest release, and npx skills update moves it to each new release. Install from https://opentui.com/docs/next to follow the main branch. A skill installed with npx skills add anomalyco/opentui follows the main branch; run the command above to switch it to releases.

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%