ebox/README.zh-CN.md
Kinneyzhang 3bd75f90c8 fix: preserve standalone layout and source ownership across updates
Expose detached committed snapshots and explicit canonical construction ownership. Preserve scoped publication and rollback, share Box decoration, and reuse completed Flex/Grid work only under proven constraints.
2026-09-06 10:45:47 +08:00

108 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ebox
Ebox 是一个独立的 Emacs Text/Box 布局引擎负责文本测量、Box 几何、
row/column/flex/Grid 布局、retained 渲染和增量 buffer 发布。应用还需要
Component、响应式状态、behavior 或生命周期时,使用同级 ETAF 包。
## 安装
Ebox 需要 Emacs 29.1 或更高版本、ECSS 0.1.0 或更高版本,以及 TP 1.0.1 或
更高版本。包管理器应自动安装声明的依赖。使用同级源码 checkout 时,把三个目录
加入 `load-path` 后加载 Ebox
```elisp
(add-to-list 'load-path "/path/to/ecss")
(add-to-list 'load-path "/path/to/tp")
(add-to-list 'load-path "/path/to/ebox")
(require 'ebox)
```
加载 Ebox 不会创建 buffer也不会构建 native 模块。
## 第一次渲染
普通用户只需理解七个 author 入口:字符串、`text`、`box`、`row`、`column`、
`flex``grid`。子节点直接嵌套,不存在第二套 field-based child 语法。
```elisp
(require 'ebox)
(ebox-render-to-buffer
"*Ebox Example*"
(ebox-build
'(column :padding (1 2)
:border (1 solid "#8A93A6")
(text :color "#263244" "Hello Ebox")
(row :item-gap 1
(box "Left")
(box "Right")))))
```
普通 author DSL 统一通过 `ebox-build`。框架集成可以用一个
`ebox-source-builder` 组合 typed node再把 forest 与同一代 source facts 封装为一个
`CanonicalEboxInput`;这个 evaluated API 不是第二套 author 语法。
已求值的 Box 构造包含 `ebox-child-range` 时,通过 `:source-builder`
显式传入开放的 builder。它必须拥有 Box 及所有直接子节点的 source handle
空 Range 同样需要开放的 builder。builder 只参与构造,不保留在节点中。
组合已有 canonical input 时,使用 `ebox-canonical-input-roots`
`ebox-canonical-input-import-roots`,框架不应读取私有字段或绑定私有动态上下文。
## 如何选择布局
- `box` 创建普通视觉盒子;
- `row``column` 用于简单的一维组合;
- `flex` 用于空间分配和换行;
- `grid` 用于二维轨道与放置;
- 裸字符串是 `(text "...")` 的简写。
Flex/Grid participation property 直接属于子 `box`,不需要额外 wrapper 节点。
## 渲染与更新
- `ebox-render` 返回带属性文本,不发布 live buffer
- `ebox-render-to-buffer` 挂载 retained surface
- `ebox-commit` 原子发布重新构建的 canonical input
- `ebox-buffer-update-report` 返回最近一次成功更新报告;
- `ebox-rerender-buffer-with-context` 应用显式 viewport 变化。
- `ebox-surface-buffer-snapshot` 显式导出当前提交的 `:input`、`:revision`
`:mount-id`,以一个 plist 返回。
Ebox 会在分配 runtime identity 前复制 canonical input因此同一个 built value 可以
挂载到多个 buffer而不会共享 live ownership。
快照只在显式查询时遍历导出数据和 TP 最近的诊断报告,普通更新不会创建快照。其 canonical input 在后续
更新、卸载后仍可使用;节点中的可变数据独立复制,不可变 source facts 与不透明能力
回调、keymap、record保留身份。快照不冻结显示环境或外部能力。TP 事务期间、
卸载后查询会报错。识别提交版本时同时比较 mount ID 与 revision避免重新挂载后
revision 从头计数导致混淆。
Ebox 只通过 TP 的公开 structured participant API 注册可回滚状态。TP 1.0.1
支持 consumer-first 迁移协议TP 2.0.0 发布最终的 v2-only 协议。structured
participant capability 缺失或格式错误时Ebox 会停止加载,不会选择兼容 writer。
## 可选 native 模块
Rust 模块只加速符合条件的 reflow它不是正确性的依赖并有完全等价的 Elisp
fallback。Ebox 加载时不会自动构建它。
```elisp
(ebox-native-status)
(ebox-native-build)
```
## 验证
```sh
make load EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make compile EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make docs-contract-tests EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make c1b-contract-tests EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make check EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make native-rust-tests
```
继续阅读[用户指南](docs/user/ebox-user-guide.zh.md)、[公共 API
参考](docs/user/ebox-api-reference.zh.md),以及同级
[ebox-playground](../ebox-playground/README.md) 示例。