Skip to content

Releases: yibie/textui

TextUI 0.8.0

Choose a tag to compare

@yibie yibie released this 07 Sep 00:44

What's new

  • Add public textui-layout-widget and textui-attach-widget APIs for embedding multiline widgets in ordinary buffers.
  • Add top-level width-aware block widgets through :textui-layout and :textui-attach.
  • Validate attachment bounds, text preservation, and widget lifecycle contracts.
  • Preserve the existing single-line native widget behavior and stable location ordering.

Verification

  • 140 ERT tests pass.
  • Byte compilation and whitespace checks pass.

TextUI 0.7.1

Choose a tag to compare

@yibie yibie released this 05 Sep 14:17

Fixed

  • Preserve complete-line refresh ownership when an outer layout box pads a child to match a wider sibling.
  • Prevent image pixel rounding and similar one-cell width differences from raising Refresh region ... must occupy complete lines.

Validated with the complete 129-test suite and strict byte compilation on Emacs 31 and Emacs 32.

TextUI 0.7.0

Choose a tag to compare

@yibie yibie released this 04 Sep 14:55

TextUI 0.7.0 adds the optional textui-keyed-region deep module for incrementally reconciling ordered, stable items inside one bounded complete-line column.

Highlights:

  • Preserves unchanged rendered items and native widgets during sliding-window updates.
  • Re-renders only added or changed keyed items.
  • Invalidates safely after width changes and unrelated full refreshes.
  • Rejects duplicate keys and nested refresh regions before mutating the buffer.

Requires Emacs 29.1 or later.

TextUI 0.6.0

Choose a tag to compare

@yibie yibie released this 01 Sep 14:18

Added

  • :text accepts :wrap with balanced (default, Knuth–Plass) or greedy, a linear-time low-latency break strategy for interactive readers. Greedy stays kinsoku-aware, preserves attributed source characters, and keeps the non-final-line pixel-justification contract (ADR 0036).
  • A bounded paragraph layout cache (textui-text-layout-cache-size, default 2048 entries) memoizes text planning per content, pixel width, and wrap strategy. Cache keys include resolved named-face metrics, a theme/font environment generation, and face-remap-alist entries in both proper-list and dotted-pair forms; textui-invalidate-text-layout-cache is the manual escape hatch.

Fixed

  • The graphical :image path built rows as unibyte strings and spliced alt text with store-substring: a CJK alt signaled "Attempt to store non-byte value into unibyte string" and alt text properties were dropped. Rows are now multibyte and property-preserving.
  • Alt splicing is bounded by both display width and character count, so combining-mark or variation-selector sequences no longer signal args-out-of-range.
  • A letterboxed image now places its alt and property carrier on the leaf's first row, keeping external row-range bookkeeping aligned to the leaf.
  • Action-triggered refreshes read focus/position snapshots via buffer-local-value from the target buffer, fixing lost point and wrong-type-argument errors when a widget action ran while another buffer was current.

Full test suite: 120/120.

TextUI 0.5.1

Choose a tag to compare

@yibie yibie released this 11 Aug 05:33

TextUI 0.5.1 documents and validates the two supported state-update paths.

  • Automatic reconciliation remains the default: update state and let TextUI evaluate the complete frame and patch changed named regions.
  • textui-update with :region and :producer is now documented as an opt-in performance fast path for a measured update confined to one complete-line region.
  • The state change, target, and producer remain together at the call site; the removed key-to-region dependency graph is not restored.
  • The retained btop benchmark now compares both paths on the same revision. With 1,000 rows at 120 columns, automatic reconciliation measured 4.14 ms median and explicit region update measured 2.36 ms, about 1.75 times faster on that fixture.
  • A regression test verifies that the explicit path skips the complete render function and changes only its named region.

See README.md, CHANGELOG.md, and ADR 0035 for the contract and correctness boundary.

TextUI 0.5.0

Choose a tag to compare

@yibie yibie released this 11 Aug 05:05

TextUI 0.5.0 removes the manually maintained state-to-region dependency graph.

Breaking change

  • Removes the public textui-route-state function. Delete route declarations; ordinary textui-update and textui-set-state calls need no replacement syntax.

Changed

  • State updates now evaluate the complete frame, then the existing reconciler patches only changed named regions when the surrounding shell is stable.
  • Explicit region refresh remains available for external updates whose caller already knows the owning complete-line region.
  • Documentation now makes clear that bundled TextUI widget types are protocol examples; package widgets should continue to be defined with widget.el.

Performance

  • In the byte-compiled 1,000-row btop fixture at 120 columns, complete reconciliation measured a 4.13 ms median and 4.30 ms p95, compared with 2.39 ms for manual state routing. TextUI accepts the 1.74 ms median cost to remove stale-UI failures and caller-maintained dependencies.

See CHANGELOG.md and ADR 0035 for the complete decision and measurements.

TextUI 0.4.0

Choose a tag to compare

@yibie yibie released this 10 Aug 11:29

TextUI 0.4.0 makes the native-widget fast path a public extension protocol for package-owned widget.el types.

Highlights:

  • Add the inherited :textui-measure and :textui-attach widget fields.
  • Export measurement and attachment helpers for buttons, text checkboxes, and editable fields.
  • Preserve custom widget actions, notifications, validation, and keymaps while accelerating measurement and buffer attachment.
  • Keep textui-button, textui-checkbox, and textui-field as optional convenience types; no registration or replacement widget hierarchy is required.
  • Document the public contract and invariants in ADR 0034.

On the release machine, a full refresh of 3,000 attached controls measured 238.58 ms versus 596.55 ms for the generic native path. These figures describe that fixture and machine, not a cross-system guarantee.

Verification: 105 ERT tests pass, and byte compilation passes with warnings treated as errors on Emacs 29.1 or later.

Full changelog: v0.3.0...v0.4.0

TextUI 0.3.0

Choose a tag to compare

@yibie yibie released this 10 Aug 09:23

TextUI 0.3.0 makes large native-widget interfaces cheaper to refresh and keeps pixel-justified text inside narrow layouts, while continuing to build on Emacs widget.el rather than replacing it.

Highlights:

  • Adds the optional textui-widgets library with text-only textui-button, textui-checkbox, and textui-field controls.
  • Reuses rendered placeholders when attaching those controls, avoiding generic widget delete-and-recreate work during full refreshes.
  • Uses real per-gap ideal, shrink, and stretch widths in the vendored Knuth–Plass implementation.
  • Removes phantom spaces at identifier break points and falls back to natural ragged-right wrapping before an emergency line can overflow.
  • Fixes editable-field and display-glyph width accounting inside bordered layouts.
  • Ships the widget performance and profiling programs under test/performance/.
  • Records the platform-native design constraints that keep TextUI an extension of Emacs instead of a second widget system.

On the release machine, a full refresh of 3,000 attached controls measured 242.79 ms versus 600.89 ms for the generic native path. These numbers describe that fixture and machine, not a cross-system guarantee.

Verification: 102 ERT tests passed; byte compilation passed with warnings treated as errors; minimum Emacs version remains 29.1.

Full changelog: v0.2.0...v0.3.0

TextUI 0.2.0

Choose a tag to compare

@yibie yibie released this 09 Aug 14:38

TextUI 0.2.0 adds buffer runtime coordination while keeping Emacs widget.el as the control system.

Highlights:

  • Routes top-level plist state changes to named refresh regions.
  • Coalesces repeated regional updates and falls back to full reconciliation for structural changes.
  • Adds dependency-aware lifecycle effects for timers, processes, and cleanup.
  • Adds lifecycle-safe async callbacks that ignore stale work.
  • Updates the btop prototype to use automatic state routing and managed live sampling.
  • Documents the new state, effect, and regional refresh interfaces.

In the btop 50-process fixture, the routed details update improved from a median of 11.65 ms to 5.67 ms, about 2.05x faster, while continuing to use native widget.el push-button rows.

Verification:

  • 87 ERT tests pass.
  • Byte compilation passes with warnings treated as errors.
  • Requires Emacs 29.1 or later.