Replace the legacy managed layer renderer with one independent retained/reactive text runtime. TP now owns exact dependencies, stable objects, marker-backed mounts, property contribution composition, atomic publication, rollback, and direct text-property facades without ECSS or Ebox dependencies.\n\nBREAKING CHANGE: remove tp-render, tp-stack, scan-driven managed layers, inline runtime metadata, TP-owned CSS cascade APIs, and dollar-variable declarations.\n\nVerified: 290/290 ERT, shuffled 290/290 (seed 20260806), 8/8 doctests, WERROR compile-all, checkdoc, package-lint, diff-check, and isolated TP-only load.
6.7 KiB
tp.el 响应式系统优化文档
历史 TP 0.3 文档,TP 1.0 已废弃。 本文评估的是已经删除的
$variable、tp-text、inlinetp-name、tp-render.el与扫描式批处理模型,仅作为设计历史保留;下文的实现状态、函数名和示例均不适用于 TP 1.0。当前优化模型建立在精确 signal/binding 依赖图、事务批处理和 retained surface diff 上,详见 README、当前架构 和 API 合同。
本文档基于 twidget 项目的实践经验,对 tp.el 的响应式系统进行了优化和增强。
优化建议评估
以下是针对 tp.el 响应式系统的六项优化建议的评估和实现情况:
1. 细粒度响应式更新(Granular Reactive Updates)
建议:支持区域内的部分更新,只更新响应式部分,保留周围文本属性。
评估:已经实现。tp.el 通过在带 tp-name 标记的区域上使用 tp-search-map,以及基于区间的更新机制,已经支持细粒度的属性更新。更新只影响具有特定 tp-name 的区域,并且只替换该层自身的属性键——由其他来源贡献的属性保持不变。
2. 响应式符号清理(Reactive Symbol Cleanup)✅ 已实现
建议:当 widget 销毁时,添加注销响应式符号的机制。
评估:已经实现。tp--unregister-reactive-deps 函数负责清理:
- 当层被重新定义时自动调用
- 当层被取消定义(
tp-undefine-layer)时自动调用 - 清理变量监听器、计算属性和数据变量
关键函数:
tp--unregister-reactive-depstp--unregister-layer-watcherstp--unregister-layer-computedtp--unregister-layer-data
3. 作用域响应式(Scoped Reactivity)✅ 已实现
建议:为响应式变量添加实例/上下文作用域。
评估:已经实现。where 参数在以下函数中支持缓冲区局部更新:
tp--update-layer-regionstp--update-reactive-text
当使用 setq-local 时,更新只影响特定缓冲区。
4. 批量更新(Batched Updates)🆕 新增
建议:当多个响应式值同时变化时,批量处理更新以避免冗余的缓冲区修改。
实现:新增 tp-with-batch-updates 宏:
;; 使用批量更新
(tp-with-batch-updates
(setq my-color "red")
(setq my-size 14)
(setq my-text "Hello"))
;; 所有更新在批量结束后一次性应用到缓冲区
关键函数和变量:
tp-with-batch-updates- 批量更新宏tp--batch-update-active- 标记是否在批量更新中tp--batch-update-pending- 待处理的更新列表tp--flush-batch-updates- 应用所有待处理更新
5. 值转换(Value Transformation)🆕 新增
建议:允许注册转换函数,在 tp-text 更新时运行。
实现:新增 :transform 选项:
;; 定义带转换的层
(define-tp currency-display ()
:props '(face bold tp-text $amount)
:data '((amount . "100"))
:transform (lambda (text)
(format "$%s.00" text)))
;; 使用后,100 会显示为 $100.00
关键函数和变量:
tp-layer-transforms- 存储层转换函数- 转换在
tp--handle-tp-text-property和tp--update-reactive-text中应用
6. 调试模式(Debug Mode)🆕 新增
建议:添加调试模式以追踪响应式更新。
实现:新增调试功能:
;; 启用调试模式
(setq tp-debug-mode t)
;; 同时在 minibuffer 显示调试信息
(setq tp-debug-echo t)
;; 查看调试日志
(tp-debug-show)
;; 清除调试日志
(tp-debug-clear)
关键函数和变量:
tp-debug-mode- 启用/禁用调试模式tp-debug-echo- 是否在 minibuffer 显示调试信息tp-debug-log- 记录调试信息tp-debug-show- 显示调试缓冲区tp-debug-clear- 清除调试日志
调试日志包含:
- 变量变化通知(旧值 → 新值)
- 层更新追踪
- 批量更新开始/结束
- 转换应用信息
新增功能详解
批量更新 (tp-with-batch-updates)
当需要同时修改多个响应式变量时,使用批量更新可以避免多次缓冲区更新:
(define-tp themed-text ()
:props '(face (:foreground $fg-color :background $bg-color))
:data '((fg-color . "white") (bg-color . "black")))
(with-temp-buffer
(insert "Hello World")
(tp-set 1 12 'themed-text)
;; 不使用批量更新:每个 setq 都会触发一次缓冲区更新
(setq fg-color "yellow") ; 第一次更新
(setq bg-color "navy") ; 第二次更新
;; 使用批量更新:所有变化在结束时一次性应用
(tp-with-batch-updates
(setq fg-color "red")
(setq bg-color "blue"))) ; 只更新一次
值转换 (:transform)
转换函数允许在显示前处理 tp-text 的值:
;; 数字格式化
(define-tp price-display ()
:props '(tp-text $price)
:data '((price . "99.9"))
:transform (lambda (text)
(format "$%.2f" (string-to-number text))))
;; 日期格式化
(define-tp date-display ()
:props '(tp-text $timestamp)
:data '((timestamp . "1703865600"))
:transform (lambda (text)
(format-time-string "%Y-%m-%d"
(seconds-to-time (string-to-number text)))))
;; 大写转换
(define-tp uppercase-text ()
:props '(tp-text $content)
:data '((content . "hello"))
:transform #'upcase)
调试模式
调试模式帮助开发者理解响应式更新流程:
;; 启用完整调试
(setq tp-debug-mode t)
(setq tp-debug-echo t)
;; 定义和使用响应式层
(define-tp test-layer ()
:props '(face (:foreground $my-color))
:data '((my-color . "red")))
(with-temp-buffer
(insert "Test")
(tp-set 1 5 'test-layer)
(setq my-color "blue"))
;; 调试输出示例:
;; [12:34:56.789] Variable my-color changed: "red" -> "blue" (where: global)
;; [12:34:56.790] Updating layer test-layer (tp-text affected: no)
架构说明
这些优化遵循 tp.el 的分层架构原则:
- 调试模式 - 作为基础工具层功能(
tp-core.el) - 批量更新 - 在响应式系统层实现(
tp-reactive.el) - 值转换 - 在层定义和响应式文本处理中实现(
tp-layer.el/tp-render.el)
所有新功能都与现有的响应式系统无缝集成,不破坏现有 API。
相关函数一览
| 函数/变量 | 描述 |
|---|---|
tp-debug-mode |
启用调试模式 |
tp-debug-echo |
启用 minibuffer 调试输出 |
tp-debug-log |
记录调试信息 |
tp-debug-show |
显示调试缓冲区 |
tp-debug-clear |
清除调试日志 |
tp-with-batch-updates |
批量更新宏 |
tp-layer-transforms |
层转换函数存储 |
:transform |
层定义中的转换选项 |