Go to file
Kinneyzhang ab9efe62a7 refactor: move playground fixtures to sibling package
Keep the standalone Ebox package focused on its public layout and DSL primitives while the generic ebox-playground package owns executable .ebox references.
2026-08-05 20:36:24 +08:00
.github/workflows feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
docs refactor: move playground fixtures to sibling package 2026-08-05 20:36:24 +08:00
examples refactor: move playground fixtures to sibling package 2026-08-05 20:36:24 +08:00
native feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
scripts feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
tests refactor: move playground fixtures to sibling package 2026-08-05 20:36:24 +08:00
.gitignore feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
AGENTS.md feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
DESIGN.md feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
DESIGN.zh.md feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-buffer-backend.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-cache.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-dsl.el refactor: move playground fixtures to sibling package 2026-08-05 20:36:24 +08:00
ebox-flex.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-fragment.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-grid.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-incremental.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-layout.el fix: measure full stack leaf width 2026-08-05 12:01:36 +08:00
ebox-measure.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-native-reflow.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-render-context.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-selector.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-style.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox-tree.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
ebox.el feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
Makefile refactor: move playground fixtures to sibling package 2026-08-05 20:36:24 +08:00
README.md feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00
README.zh-CN.md feat(ebox): publish standalone low-level package 2026-08-05 09:15:35 +08:00

Ebox

Ebox is a standalone, pixel-precise box and layout engine for Emacs. It provides the low-level rendering substrate used by the sibling ETAF text-application framework. Ebox can also be used directly without Components, application state, or ETAF.

Install and use

Clone or place this directory on load-path:

(add-to-list 'load-path "/path/to/github/ebox")
(require 'ebox)

(ebox-render-to-buffer
 "*Ebox Example*"
 (ebox-column
  (ebox-create :content "Hello Ebox"
               :padding '(1 2)
               :border '((1) solid "#8A93A6")
               :color "#263244"
               :bgcolor "#F4F6FB")))

The public model is a tree of Ebox nodes. ebox-create builds a leaf or wrapper node; ebox-column, ebox-row, ebox-flex, and ebox-grid compose nodes; ebox-render returns propertized text; ebox-render-to-buffer publishes it into a buffer; and ebox-commit updates an existing runtime from a fresh root tree.

What belongs here

  • box creation, padding, margins, borders, colors, faces, overflow, and text measurement;
  • row, column, flex, and two-dimensional Grid layout;
  • selectors, stable node identity, keyed reconciliation, buffer rendering, and incremental publication;
  • optional Rust native reflow with an exact Elisp fallback;
  • low-level Ebox DSL files and renderer-focused tests.

ETAF belongs in the sibling package. Install it separately when you need the unified View grammar, Components, reactive state, behaviors, Context, Data Controllers, or application lifecycle. The independent example packages are ebox-playground and etaf-playground.

Repository map

Path Responsibility
ebox.el Public facade and package entry point.
ebox-style.el, ebox-tree.el, ebox-measure.el Style, tree, and measurement models.
ebox-layout.el, ebox-flex.el, ebox-grid.el Formatting contexts and layout algorithms.
ebox-buffer-backend.el, ebox-incremental.el Buffer publication and incremental updates.
ebox-dsl.el, ebox-selector.el Standalone DSL and tree/runtime queries.
ebox-native-reflow.el, native/ Optional native reflow boundary.
examples/, tests/ Ebox-only examples and regression tests.
docs/user/, docs/maintainer/ Long-lived English and Chinese documentation.

Verification

make load EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make compile EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make check EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make native-rust-tests

Run the smallest focused target first (make grid-tests, make dsl-tests, or make visual-check-tests), then run make check for shared rendering or public API changes.

Read the Ebox user guide for public construction examples and the current implementation reference for ownership boundaries and invariants.