25 KiB
TP 1.0 公共 API 与用法参考
本文是 TP 当前实现的完整公共入口索引。它以 tp.el 加载的模块为准;带 tp-- 前缀的函数、变量和结构体是内部实现,不属于本文的稳定 API。
- 快速开始与能力边界:README、中文 README
- 语义合同:API-SEMANTICS.md
- 当前架构:ARCHITECTURE.md
- 可运行示例:examples/
1. 运行边界
TP 只负责 Emacs text properties、响应式 signal/binding、retained object、 marker-backed mount、diff、事务和 Buffer publication。它不实现 CSS selector、 stylesheet、specificity、cascade、Box、Flex、Grid、测量或布局,也不依赖 Ebox/ECSS。
所有坐标都遵循 Emacs 原生对象的坐标规则:
- string 使用从 0 开始的 [start, end);
- buffer 使用从 1 开始的 [start, end);
- tp-surface-plan 中的 content leaf range 是相对于该 leaf 文本的 0-based offset,不是 Buffer position。
普通函数值、callback、keymap command 和 list 都是 literal data。只有显式的 tp-computed source 会被执行。显式存在且值为 nil 与属性不存在始终不同。
2. 先选入口
| 目标 | 入口 | 是否建立 live state |
|---|---|---|
| 创建带属性的 string | tp-propertize | 否 |
| 一次性改已有范围 | tp-apply、tp-set、tp-reset、tp-add、tp-remove、tp-clear | 否 |
| 查询属性和区间 | tp-get、tp-at、tp-member、tp-lookup | 否 |
| 按文字或属性搜索 | tp-match-、tp-regexp-、tp-search*、tp-forward/backward | 否 |
| 让已有 host text 响应变化 | tp-watch | 是,properties |
| 管理 TP 自己拥有的文字 | tp-surface-mount / tp-surface-update | 是,content |
| 检查或卸载 publication | tp-surface-inspect / tp-surface-report / tp-surface-unmount | 是 |
| 定义可复用声明 | define-tp、define-tps | 只建立 recipe,不建立 live state |
| 定义主题颜色 | define-tp-palette | 只更新 palette registry |
安装只需要把仓库加入 load-path:
(add-to-list 'load-path "/path/to/tp")
(require 'tp)
tp.el 会加载所有运行时模块。单独加载模块只适合包开发或测试。
3. 一次性文本属性操作
3.1 创建和应用
(tp-propertize
"Hello"
'(face bold help-echo "greeting" keymap nil))
(with-current-buffer (get-buffer-create "*tp-demo*")
(erase-buffer)
(insert "abcdef")
(tp-apply (current-buffer) 2 5 '(face italic)))
tp-propertize 返回原 string 的副本;tp-apply 保留范围内未出现在 declarations 中的其他属性,并返回 (START . END)。
declarations 可以是原生 property plist、define-tp recipe、recipe call, 或包含 recipe key 的 plist。tp-apply 和下面的直接操作不会创建 object、 binding、marker、subscription 或 surface。
3.2 set/reset/add/remove/clear
对完整 string 的形式会返回新 string;对 Buffer 范围的形式会原地修改,并 返回 (START . END)(tp-remove 和 tp-clear 的 Buffer 形式返回 nil)。
;; string:property/value 形式,原 string 不变
(tp-set "item" 'face 'bold)
(tp-reset "item" 'face 'italic)
(tp-add "item" 'face 'underline)
(tp-remove (tp-set "item" 'face 'bold) 'face)
;; buffer 或 string 范围:一个 direct property plist,可选 OBJECT
(tp-set start end '(face bold help-echo "tip") buffer)
(tp-reset start end '(face italic) buffer)
(tp-add start end '(face (:weight bold)) buffer)
(tp-remove start end 'help-echo buffer)
(tp-clear start end buffer)
- tp-set 替换所指定的顶层属性;
- tp-reset 用 declarations 完全替换范围内所有属性;
- tp-add 合并属性;face、font-lock-face、mouse-face 支持 contribution 合成和嵌套 plist 合并;
- tp-remove 支持移除顶层属性,也支持 (property sub-key) 或 (property sub-key nested-key...);
- tp-clear 移除范围内全部 text properties。
4. 声明、property policy 和 recipe
4.1 Property policy
(tp-define-property-policy
'text/my-property
:normalizer #'identity
:validator (lambda (_value) t)
:equality #'equal
:merge (lambda (_old new) new)
:projector #'identity)
(tp-property-policy 'text/my-property)
(tp-register-text-property 'help-echo)
(tp-text-property-id 'help-echo)
(tp-text-declarations '(face bold help-echo "tip"))
tp-define-property-policy 的 id 必须是包含 / 的 canonical symbol。可选策略 为 :normalizer、:validator、:equality、:merge、:projector。注册是原子的; 无效策略不会替换旧定义。
- tp-register-text-property 为原生 Emacs property 安装默认 policy;
- tp-text-property-id 把原生 property 映射为 text/PROPERTY;
- tp-text-declarations 把原生 plist 转成 canonical declarations;
- tp-merge-declarations 按参数顺序合并 direct declaration groups,后者 覆盖前者,并保留显式 nil;
- tp-computed 把一个函数标记为唯一允许执行的 value source;
- tp-resolve-value 解析 literal 或显式 computed value;
- tp-define-style、tp-style-declarations、tp-undefine-style 管理已归一化的 命名 direct style。
4.2 静态 recipe
(define-tp link-style (color)
(list 'face (list :foreground color :weight 'bold)
'mouse-face 'highlight))
(define-tps status-group ()
link-style
'(help-echo "status"))
(tp-set 1 5 '(link-style "#58a6ff") buffer)
(tp-layer-props-with-arg 'link-style "#58a6ff")
(tp-group-props 'status-group)
入口及别名:
- define-tp(别名 tp-define-layer)定义一个返回原生 property plist 的 recipe;
- define-tps(别名 define-tp-group、tp-define-group)定义由多个 recipe、 recipe call、原生 plist 或命名元素组成的 declaration group;
- tp-layer-parameterized-p、tp-layer-arglist、tp-layer-props、 tp-layer-props-with-args、tp-layer-props-with-arg 查询或展开 layer;
- tp-group-parameterized-p、tp-group-props、tp-group-props-with-args、 tp-group-props-with-arg 查询或展开 group;
- tp-undefine-layer、tp-undefine-group、tp-layer-reset 删除 recipe;
- tp-describe-layer 返回 recipe 的声明式诊断数据。
recipe 是 definition-time convenience,不是 mounted layer,也不会向文本 写入 identity、provenance、tp-name 或 tp-layers。旧的 $variable reactive syntax 会被拒绝。
tp-layer-alist 和 tp-layer-groups 是 recipe registry;通常通过上面的 query、 undefine 和 reset API 访问,不要直接修改 registry。
5. Reactive signal 和 binding
5.1 Signal
(let ((online (tp-signal-create nil)))
(tp-signal-read online) ; 在 binding/producer 中收集依赖
(tp-signal-peek online) ; 读取但不收集依赖
(tp-signal-set online t)
(tp-signal-subscriber-count online)
(tp-signal-live-p online)
(tp-signal-dispose online))
tp-signal-create 的关键字选项:
- :equality,默认 equal;相等写入是 no-op;
- :scope,默认 global,也可以是一个 live buffer。Buffer kill 会释放该范围 内 signal。
tp-signal-read 只在当前 computation 中登记 dependency;tp-signal-peek 不会 登记。disposed signal 的读取会报错。
5.2 Binding
(let* ((source (tp-signal-create 0))
(owner (list 'owner))
(binding
(tp-bind owner 'value
(lambda () (tp-signal-read source))
:lifecycle 'delete)))
(tp-binding-read binding)
(tp-binding-live-p binding)
(tp-binding-dependency-count binding)
(tp-binding-subscriber-count binding)
(tp-binding-owner-bindings owner)
(tp-binding-dispose binding)
(tp-signal-dispose source))
tp-bind 按 OWNER + KEY 幂等安装 computation。KEY 应使用调用者自己的命名空间; :equality 默认 equal;:lifecycle 为 delete 或 retain。binding 依赖集合按每次 实际读取重建,因此条件分支会自动断开不再使用的 source。tp-binding-read 会在需要时计算并把 binding-to-binding 依赖登记到当前 computation。
tp-binding-dispose-owner 释放 owner 的全部 binding,返回释放数量; tp-binding-dispose 释放单个 binding。
5.3 Transaction 和变量适配器
(let ((left (tp-signal-create 0))
(right (tp-signal-create 0)))
(tp-with-transaction
(tp-signal-set left 1)
(tp-signal-set right 2))
(tp-signal-dispose left)
(tp-signal-dispose right))
(tp-transaction-participate
'my-external-state
(lambda () (my-publish))
(lambda () (my-rollback)))
(tp-transaction-active-p)
(tp-runtime-manifest)
(tp-variable-signal 'my-variable)
(tp-variable-signal 'my-buffer-variable some-buffer)
(tp-reactive-counters)
(tp-reactive-reset-counters)
(tp-reactive-reset)
tp-with-transaction 将 signal、binding、surface 和注册的 transaction participant 一起原子处理。participant 必须在 active transaction 内注册; publish 在 surface publication 后、source commit 前运行,失败时按逆序 rollback。tp-variable-signal 用 Emacs variable watcher 适配全局或指定 Buffer 的变量,不是旧的 $variable API。
tp-transaction-active-p 是只读边界查询:只在当前 dynamic extent 已进入 或加入 TP transaction 时返回严格的 t,否则返回 nil。它不暴露 transaction 对象、participant 或内部状态,调用方只能用它在 mutation 前拒绝不支持的 嵌套事务边界。
tp-runtime-manifest 返回防御性 capability snapshot;本版本的
:transaction-protocol 为 tp-transaction-protocol-v1+v2。该声明是 additive:
旧 tp-transaction-participate façade 与 live writer 都仍保留。
:batch-artifacts 与 :shadow-proof 为 non-nil,:batch-execution 为
v1-bridge,而 :batch-execute 明确为 nil;structured-core execute owner
保留给后续受控 cutover,不在 M1a 伪造第二个 coordinator。
ETAF registers one opaque participant for its immutable generation and Ebox client state. Its publish is paired with rollback across TP final accept; the ETAF runtime separately records effect input/version tuples and reports a bounded non-converging flush instead of spinning.
6. Retained surface
6.1 Plan、result 和 object
(tp-surface-plan-create
:key 'label :kind 'text :text "Ready"
:props '(face bold) :tags '(:role status)
:capability 'content)
Plan 字段为 key、kind、text、props、children、tags、capability。leaf 使用 text,容器使用 children;同一层的 key 必须唯一。capability 是 content 或 properties。
- tp-surface-plan-create 防御性复制 caller-owned 数据;
- tp-surface-plan-create-owned 直接接收 candidate-local 数据;调用者必须 转移所有权,之后不得修改或向其他 owner 暴露;
- tp-surface-result-create 返回携带 plan 和 opaque client-state 的 producer result;
- tp-surface-result-create-owned 只可对当前 active prepare context 使用, 结果只消费一次。
- tp-surface-retained-content-result-create 用于对象拓扑不变的 content
candidate;最后一个可选
property-contributions参数接受按顺序排列的(:start N :end N :props PLIST)相对范围。TP 使用已注册 property merge policy 在 prepare 内组合这些贡献,再通过同一个 content surface 原子 diff、 发布和回滚;调用者不需要创建重叠的 properties surface,也不应预先压平 Theme/状态/inline face。
producer 接收一个 prepare context,并应返回 plan 或 result:
(lambda (context)
(let ((object (tp-object-ensure context nil 'row 'text)))
(tp-surface-plan-create
:key 'row :kind 'text :text "row"
:props '(face italic)
:capability 'content)))
producer 不得在 prepare 阶段直接修改 live surface buffer;plan 不携带 position、marker、patch operation、producer closure 或 continuation。
对象入口:
- tp-object-ensure 按 parent、sibling key、kind 返回或创建当前 candidate 的 稳定 opaque object;
- tp-object-live-p、tp-object-mounted-p 检查 object 状态;
- tp-object-resolve 用 key path 从 surface side index 取得 object,不扫描文本;
- tp-object-mounts 返回 :start、:end、:tags 的数值快照;
- tp-object-retain 保留没有输出 fragment 的 object;
- tp-object-retain-subtree 保留已证明未删除的 object 子树;
- tp-object-reuse-subtree 复用已证明完全不变的 object 子树;
- tp-object-attach-fragment 把一个 object 绑定到 content fragment;
- tp-object-attach-content-range 把 object 绑定到 leaf 的相对字符范围;
- tp-object-attach-content-ranges 批量绑定 range,并复制 tags;
- tp-object-attach-content-ranges-owned 批量绑定 candidate-owned tags。
retain-subtree/reuse-subtree 不会替调用者证明 candidate 完整或输出未变化; producer 仍须提交完整 plan,并承担“不变”证明。
6.2 Mount、update、scope 和 report
(let* ((surface
(tp-surface-mount
buffer producer
'(:capability content
:start 1 :end 1
:client-state initial-state
:inhibit-read-only t
:observers (my-after-commit)))))
(tp-surface-update surface producer)
(tp-surface-update-scoped
surface
(list object)
producer
'(:on-mismatch error :return-report t))
(tp-surface-report surface)
(tp-surface-report-summary surface)
(tp-surface-inspect surface)
(tp-surface-unmount surface))
tp-surface-mount 的 plan-or-producer 可以是 plan、result 或 producer; producer 的调用上下文由 TP 管理。properties surface 只能写属性,content surface 才能拥有和更新文字。可用 mount options: :capability、:start、:end、:inhibit-read-only、:coordinate-mounts、 :client-state、:observers。
tp-surface-update 发布下一份完整 candidate。tp-surface-update-scoped 仍要求 producer 生成完整 candidate,但只授权指定 object 当前 mount 范围; :on-mismatch 默认报 tp-scope-mismatch,设为 root 才允许显式 root fallback; :return-report 控制是否返回 report。
其他 surface API:
- tp-surface-live-p、tp-surface-revision、tp-surface-client-state;
- tp-surface-materialize-string 使用相同 producer/plan 语义生成一次性 string, 但不保留 surface、object、binding、subscription 或 anchor;
- tp-surface-at-point 通过 side index 返回当前位置的 live objects;
- tp-surface-report 返回完整 defensive report;
- tp-surface-report-summary 只返回 scalar commit metrics;
- tp-surface-inspect 返回 surface、capability、revision、object/mount 数量、 client state 和 report;
- tp-surface-unmount 卸载并返回 report。Content 会删除自己的 span; properties 只撤销仍由 TP 拥有的 contribution。
Report 的常用字段包括: :transaction-id、:surface-id、:old-revision、:new-revision、 :candidate-source-writes、:invalidated-bindings、:recomputed-bindings、 :skipped-bindings、:reconciled-objects、:created-objects、:removed-objects、 :moved-objects、:text-operations、:property-operations、 :touched-characters、:full-root、:scope-count、:scope-range-count、 :scope-fallback、:property-conflicts、:rolled-back、:failure、 :observer-errors、:timing。
6.3 Host range 和 tp-watch
(let ((anchor
(tp-range-anchor-create
buffer start end
:start-insertion-type nil
:end-insertion-type t
:boundary-policy 'shorten)))
;; 在 producer 的 context 中:
(tp-object-attach-range context object anchor)
(tp-range-anchor-live-p anchor)
(tp-range-rebase anchor))
boundary-policy 可为 stale、shorten、remove。anchor 是 marker-backed opaque range;host text 编辑由 marker 跟随,TP 不扫描附近文字猜测位置。 tp-range-rebase 明确接受当前 host properties 作为新 baseline。
tp-watch 是 properties-only surface 的便捷入口:
(let ((surface
(tp-watch
buffer start end
(lambda ()
(list 'face
(if enabled 'success 'shadow))))))
(tp-surface-report surface))
compute 是零参数函数,返回原生 declarations。文字由 host 所有;返回值是 底层 properties surface,可交给 update/report/inspect/unmount。
7. 属性查询、区间和 mutation policy
7.1 Direct query
- tp-get 返回范围内的 (START END PROPS) property intervals;指定 property 或 nested path 时只返回对应区间;
- tp-at 返回某一位置的完整 plist,或指定 property/nested path 的值;
- tp-member 只在 property 存在时返回 (PROPERTY VALUE),因此可区分 present nil 和 absent;
- tp-intervals 返回对象范围的 property intervals,可用 absolute 请求 Buffer 原生坐标;
- tp-intervals-map 对每个 interval 调用函数;
- tp-plist 返回位置或 string range 的合并 property plist;
- tp-empty-p 判断对象是否为空;
- tp-text-snapshot 返回 string 和 text properties 的防御性快照。
7.2 Native query
(tp-lookup position 'face
:object buffer
:mode :text-effective)
(tp-property-change position :property 'face :direction :next)
(tp-property-any start end 'face 'bold buffer)
(tp-property-not-all start end 'face 'bold buffer)
(tp-with-mutation-policy '(:modified :silent :read-only :inhibit)
(tp-apply buffer start end '(face bold)))
tp-lookup 返回 tp-lookup-result,mode 可为:
- :text-direct:直接 text property;
- :text-effective:考虑 category/default 等 text-property 继承;
- :text-source:返回实际 text source;
- :char:使用 get-char-property-and-overlay 的字符属性;
- :char-source:字符属性的实际来源,overlay 会记录为 :overlay。
result 的 present-p 区分显式 nil;tp-property-change 的 direction 为 :next 或 :previous,property 为 nil 时观察任意属性变化。
tp-with-mutation-policy 的 :modified 可为 :ordinary 或 :silent, :read-only 可为 :respect 或 :inhibit。支持 ordinary/respect、 ordinary/inhibit、silent/inhibit;silent/respect 会报错。
8. Match、regexp、search 和 navigation
所有 search 都是 presence-aware:省略 VALUE 或显式传入 tp-any-value 匹配 所有存在的值;显式 nil 只匹配“存在且值为 nil”。
8.1 按文字匹配并修改
- tp-match-set:literal pattern 的所有匹配上设置属性;
- tp-match-reset:literal pattern 的所有匹配上重置属性;
- tp-match-add:literal pattern 的所有匹配上合并属性;
- tp-regexp-set、tp-regexp-reset、tp-regexp-add:regexp 匹配,可用 subexp 只操作 capture group。
Pattern 可以是一个 string 或 string 列表。String object 返回新 string; Buffer object 原地修改并返回匹配范围列表。start > end 时边界会交换, 匹配不会跨出指定范围。
8.2 查找和批量处理
(tp-search string 'status)
(tp-search start end 'status 'ready buffer)
(tp-forward 'status tp-any-value buffer 2)
(tp-backward 'status nil buffer)
(tp-search-map
(lambda (text _start _end _index) (upcase text))
'status tp-any-value buffer)
- tp-search 返回所有匹配的 (START END VALUE);
- tp-forward / tp-backward 在 Buffer 中从 point 搜索并返回 prop-match, 在 string 中返回 0-based 区间列表;
- tp-forward-do / tp-backward-do 找到第 N 个匹配后只对最后一个执行 function,不是 for-each;
- tp-search-map 对每个匹配执行 function。function 可返回替换 string、 修改 text 后的 string,或 nil 跳过。String 替换必须保持长度不变; Buffer 替换可以改变长度;
- tp-search-forward / tp-search-backward 只是 Emacs text-property-search-* 的 obsolete raw wrapper,新增代码使用 tp-forward / tp-backward 或直接使用 Emacs primitive。
9. Palette、内置 recipe 和显示辅助
(define-tp-palette status
:fg ("#22863a" . "#3fb950")
:bg ("#f0fff4" . "#1a2e1f"))
(tp-palette-color 'status :fg)
(tp-palette-fg-color 'status)
(tp-palette-bg-color 'status)
(tp-palette-border-color 'status)
(tp-palette-has-p 'status :fg)
(tp-palette-pure 'status-fg)
(tp-set "Ready" 'tp-palette 'status-fg)
define-tp-palette(别名 tp-define-palette)注册 :fg、:bg、:border。颜色 可以是 string、(LIGHT . DARK) 或 (:light LIGHT :dark DARK)。查询和主题工具:
tp-palette-alist 是 palette lookup 的单一来源;使用 define-tp-palette/tp-define-palette 更新它。
- tp-theme-dark-p、tp-theme-light-p、tp-parse-color;
- tp-palette-color、tp-palette-fg-color、tp-palette-bg-color、 tp-palette-border-color;
- tp-palette-has-p 判断 palette 或 key 是否存在;
- tp-palette-p 判断 palette 名;
- tp-palette-fg-p、tp-palette-bg-p、tp-palette-fbg-p、tp-palette-border-p 判断 NAME-* variant;
- tp-palette-pure 去掉 variant suffix;
- tp-palette-show 打开 tp-palette-gallery,按 q 退出。
TP 自带的 recipe 包括:
tp-palette、tp-fg、tp-bg、tp-button、tp-underline、tp-delete、tp-link、 tp-space、tp-headline、tp-action。
显示辅助:
- tp-pop-to-buffer:清空并填充 buffer 后 pop-to-buffer,最后设为只读;
- tp-switch-to-buffer:同样的填充和只读行为,但使用 switch-to-buffer;
- tp-display-buffer-mode:为 TP 显示 buffer 提供 buffer-local 的 q 退出键, 不修改共享 major-mode map。
tp-display-buffer-mode-map 是该 minor mode 的 keymap;默认只绑定 q 到 quit-window。
10. Debug 和公共 record
Debug 入口:
- tp-debug-mode、tp-debug-echo 控制日志行为;
- tp-debug-log 记录格式化消息;
- tp-debug-clear 清空日志;
- tp-debug-show 显示日志;
- tp-with-current-buffer 在指定 Buffer 中执行 body;
- tp-face-properties 列出 face family properties。
以下公共结果类型由 cl-defstruct 提供 predicate 和字段 accessor。调用者不应 直接调用内部 constructor;优先使用前文的 create/query API:
- tp-property-policy:id、normalizer、validator、equality、merge、projector;
- tp-signal:id、committed-value、equality、scope、revision 等运行时字段;
- tp-binding:id、owner、key、compute、last-value、dependencies、lifecycle 等运行时字段;
- tp-surface-plan:key、kind、text、props、children、tags、capability;
- tp-surface-result:plan、client-state 及 owned/consumed 状态;
- tp-lookup-result:property、value、present-p、source、mode、object、 position、overlay。
11. 错误、生命周期和已删除 API
重要错误类型:
- core:tp-unsupported-buffer;
- property:tp-property-error、tp-invalid-property-policy、 tp-invalid-declaration;
- recipe:tp-invalid-layer-definition、tp-unresolved-layer;
- reactive:tp-reactive-error、tp-invalid-signal-scope、tp-disposed-signal、 tp-disposed-binding、tp-binding-cycle;
- surface:tp-surface-error、tp-invalid-surface-plan、tp-duplicate-object-key、 tp-invalid-prepare-context、tp-stale-object、tp-cross-surface-object、 tp-orphan-object、tp-capability-error、tp-stale-mount、 tp-property-conflict、tp-dead-surface、tp-invalid-range-anchor、 tp-invalid-content-range、tp-producer-buffer-mutation、 tp-publication-mismatch、tp-owned-result-error、tp-scope-mismatch。
Live object、binding、surface、anchor 或 signal 被 dispose、unmount 或 Buffer kill 后,继续使用会报相应 stale/disposed 错误。Observer 只在成功 commit 后运行;observer error 会记录在 report,不会回滚已提交 publication。
TP 1.0 已删除并且不应在新代码中使用:
- tp-render.el、tp-stack.el、managed stack mutation;
- tp-text、$variable、inline tp-name/tp-layers/tp-meta runtime database;
- layer-to-buffer registry、scan-driven refresh、managed attach/detach;
- tp-with-batch-updates 和旧 CSS/ECSS runtime integration。
因此,当前正确的组合是:静态声明用 recipe/direct API,已有文字的响应式 属性用 tp-watch,TP 自己拥有的响应式文字用 content surface。
12. 完整模块索引
| 模块 | 当前公共入口 |
|---|---|
| tp-core.el | tp-debug-*、tp-with-current-buffer、tp-intervals、tp-intervals-map、tp-empty-p、tp-plist、tp-text-snapshot |
| tp-style.el | tp-define-property-policy、tp-property-policy、tp-text-property-id、tp-register-text-property、tp-text-declarations、tp-computed、tp-resolve-value、tp-merge-declarations、tp-define-style、tp-style-declarations、tp-undefine-style |
| tp-layer.el | define-tp/tp-define-layer、define-tps/define-tp-group/tp-define-group、layer/group query、tp-layer-reset、tp-undefine-*、tp-describe-layer |
| tp-transaction.el | additive batch/entry、final-marker 与 tagged-outcome 内部合同 |
| tp-reactive.el | signal、binding、transaction coordinator、variable adapter、counter 和 reset API |
| tp-surface.el | plan/result、object、range anchor、surface lifecycle、scoped update、report、tp-watch |
| tp-ops.el | tp-propertize、tp-apply、tp-set、tp-reset、tp-add、tp-remove、tp-clear、tp-get、tp-at、tp-member |
| tp-search.el | tp-match-、tp-regexp-、tp-search、tp-search-map、tp-forward*、tp-backward*、tp-any-value |
| tp-query.el | tp-lookup、tp-property-change、tp-property-any、tp-property-not-all、tp-with-mutation-policy |
| tp-palette.el | palette definition、theme/color lookup、palette predicates |
| tp-builtins.el | built-in recipes、tp-palette-show、display-buffer macros/mode |
Makefile 提供 make test、make test-shuffled、make doctest、make compile-all WERROR=t、 make checkdoc、make package-lint、make diff-check 和 make benchmark。实现细节 和测试合同以 source、tests/、API semantics 和 architecture 为准。