Add documentation for :transform, batch updates, and debug mode in English and Chinese

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-12-31 07:29:18 +00:00
parent c20c1efb54
commit 95f0f3d702
5 changed files with 299 additions and 6 deletions

View File

@ -98,9 +98,12 @@
- [:data - Additional Reactive State](#data---additional-reactive-state)
- [:compute - Computed Properties](#compute---computed-properties)
- [:watch - Side Effect Callbacks](#watch---side-effect-callbacks)
- [:transform - Value Transformation](#transform---value-transformation)
- [Anonymous Reactive Layers](#anonymous-reactive-layers)
- [Layer Name Resolution in APIs](#layer-name-resolution-in-apis)
- [Reactive Layer Groups](#reactive-layer-groups)
- [Batched Updates](#batched-updates)
- [Debug Mode](#debug-mode)
- [Resetting Reactive State](#resetting-reactive-state)
- [Complete Example: Theme-Aware Text](#complete-example-theme-aware-text)
- [Practical Examples](#practical-examples)
@ -2526,6 +2529,8 @@ Return t if OBJECT has no text properties.
## Reactive Text Properties
> 📖 **For a comprehensive guide with detailed examples, see [Reactive Text Properties Complete Guide](docs/reactive-text-properties-en.md)**
>
> 📖 **For advanced optimization features, see [Reactive System Optimization](docs/reactive-optimization-en.md)**
**Reactive Text Properties** is tp.el's groundbreaking innovation that brings reactive programming paradigms to Emacs text properties. Inspired by modern frontend frameworks like Vue.js, this feature enables text properties to automatically update when underlying variable values change.
@ -2654,6 +2659,41 @@ The `:watch` keyword lets you execute callbacks when reactive variables change:
;; Message: "Layer monitored-layer: color changed from red to green"
```
### :transform - Value Transformation
The `:transform` keyword allows you to register a transformation function that processes `tp-text` values before they are displayed. This is useful for formatting numbers, dates, or other values:
```elisp
;; Number formatting
(tp-define-layer 'price-display
:props '(tp-text $price)
:data '((price . "99.9"))
:transform (lambda (text)
(format "$%.2f" (string-to-number text))))
;; 99.9 displays as $99.00
;; Date formatting
(tp-define-layer '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)))))
;; Uppercase conversion
(tp-define-layer 'uppercase-text
:props '(tp-text $content)
:data '((content . "hello"))
:transform #'upcase)
;; "hello" displays as "HELLO"
```
The transform function:
- Receives the raw `tp-text` string value
- Returns the transformed string for display
- Is applied both on initial display and reactive updates
- Errors in transform functions are caught and logged
### Anonymous Reactive Layers
You can use reactive variables even without `tp-define-layer`. When you use `$`-prefixed symbols in an anonymous plist, tp.el automatically generates a unique layer name:
@ -2698,6 +2738,64 @@ Layer groups can also use reactive features:
:data ((error-color . "red"))))
```
### Batched Updates
When modifying multiple reactive variables simultaneously, each `setq` triggers a separate buffer update. Use `tp-with-batch-updates` to consolidate all changes and apply them once at the end:
```elisp
(tp-define-layer '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)
;; Without batching: each setq triggers a buffer update
(setq fg-color "yellow") ; First update
(setq bg-color "navy") ; Second update
;; With batching: all changes applied once at the end
(tp-with-batch-updates
(setq fg-color "red")
(setq bg-color "blue"))) ; Only one update
```
Benefits of batched updates:
- Reduces redundant buffer modifications
- Improves performance when changing multiple variables
- Ensures consistent state when multiple variables are interdependent
### Debug Mode
tp.el provides a debug mode to help understand reactive update flow:
```elisp
;; Enable debug mode
(setq tp-debug-mode t)
;; Also show debug info in minibuffer (optional)
(setq tp-debug-echo t)
;; View debug log
(tp-debug-show)
;; Clear debug log
(tp-debug-clear)
```
Debug log includes:
- Variable change notifications (old → new value)
- Layer update tracking
- Batch update start/end
- Transform application info
Example debug output:
```
[12:34:56.789] Variable my-color changed: "red" -> "blue" (where: global)
[12:34:56.790] Updating layer test-layer (tp-text affected: no)
```
### Resetting Reactive State
To clear all reactive dependencies and watchers:

View File

@ -97,9 +97,12 @@
- [:data - 附加响应式状态](#data---附加响应式状态)
- [:compute - 计算属性](#compute---计算属性)
- [:watch - 副作用回调](#watch---副作用回调)
- [:transform - 值转换](#transform---值转换)
- [匿名响应式层](#匿名响应式层)
- [API 中的层名解析](#api-中的层名解析)
- [响应式层组](#响应式层组)
- [批量更新](#批量更新)
- [调试模式](#调试模式)
- [重置响应式状态](#重置响应式状态)
- [完整示例:主题感知文本](#完整示例主题感知文本)
- [实用示例](#实用示例)
@ -2515,6 +2518,8 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
## 响应式文本属性
> 📖 **完整的详细指南和示例,请参阅 [响应式文本属性完全指南](docs/reactive-text-properties.md)**
>
> 📖 **高级优化功能,请参阅 [响应式系统优化文档](docs/reactive-optimization.md)**
**响应式文本属性**是 tp.el 的突破性创新,它将响应式编程范式带入了 Emacs 文本属性。受 Vue.js 等现代前端框架启发,这个功能使文本属性能够在底层变量值改变时自动更新。
@ -2643,6 +2648,41 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
;; 消息: "层 monitored-layer: 颜色从 red 改为 green"
```
### :transform - 值转换
`:transform` 关键字允许你注册一个转换函数,在 `tp-text` 值显示之前对其进行处理。这对于格式化数字、日期或其他值非常有用:
```elisp
;; 数字格式化
(tp-define-layer 'price-display
:props '(tp-text $price)
:data '((price . "99.9"))
:transform (lambda (text)
(format "$%.2f" (string-to-number text))))
;; 99.9 显示为 $99.00
;; 日期格式化
(tp-define-layer '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)))))
;; 大写转换
(tp-define-layer 'uppercase-text
:props '(tp-text $content)
:data '((content . "hello"))
:transform #'upcase)
;; "hello" 显示为 "HELLO"
```
转换函数的特点:
- 接收原始的 `tp-text` 字符串值
- 返回用于显示的转换后字符串
- 在初始显示和响应式更新时都会应用
- 转换函数中的错误会被捕获并记录
### 匿名响应式层
即使不使用 `tp-define-layer`,你也可以使用响应式变量。当你在匿名 plist 中使用 `$` 前缀的符号时tp.el 会自动生成唯一的层名:
@ -2687,6 +2727,64 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
:data ((error-color . "red"))))
```
### 批量更新
同时修改多个响应式变量时,每个 `setq` 都会触发一次缓冲区更新。使用 `tp-with-batch-updates` 可以合并所有更改,在结束时一次性应用:
```elisp
(tp-define-layer '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"))) ; 只更新一次
```
批量更新的好处:
- 减少冗余的缓冲区修改
- 提高同时更改多个变量时的性能
- 当多个变量相互依赖时确保状态一致
### 调试模式
tp.el 提供调试模式来帮助理解响应式更新流程:
```elisp
;; 启用调试模式
(setq tp-debug-mode t)
;; 同时在 minibuffer 显示调试信息(可选)
(setq tp-debug-echo t)
;; 查看调试日志
(tp-debug-show)
;; 清除调试日志
(tp-debug-clear)
```
调试日志包含:
- 变量变化通知(旧值 → 新值)
- 层更新追踪
- 批量更新开始/结束
- 转换应用信息
调试输出示例:
```
[12:34:56.789] Variable my-color changed: "red" -> "blue" (where: global)
[12:34:56.790] Updating layer test-layer (tp-text affected: no)
```
### 重置响应式状态
清除所有响应式依赖和监听器:

View File

@ -208,6 +208,27 @@ tp.el 采用分层架构设计,每一层建立在下层功能之上:
|------|------|------|
| `tp--handle-tp-text-property` | 处理 tp-text 属性 | - |
#### 批量更新
| 函数/宏 | 描述 | 依赖 |
|---------|------|------|
| `tp-with-batch-updates` | 批量更新宏 | tp--flush-batch-updates |
| `tp--flush-batch-updates` | 刷新待处理的批量更新 | tp--update-layer-regions, tp--update-reactive-text |
#### 值转换
| 变量/函数 | 描述 | 依赖 |
|-----------|------|------|
| `tp-layer-transforms` | 存储层转换函数的 alist | - |
| `:transform` 选项 | 在 tp-define-layer 中指定转换函数 | tp-layer-transforms |
#### 调试工具
| 变量/函数 | 描述 | 依赖 |
|-----------|------|------|
| `tp-debug-mode` | 启用/禁用调试模式 | - |
| `tp-debug-echo` | 是否在 minibuffer 显示调试信息 | - |
| `tp-debug-log` | 记录调试信息 | tp-debug-mode, tp-debug-echo |
| `tp-debug-show` | 显示 *tp-debug* 缓冲区 | - |
| `tp-debug-clear` | 清除调试日志 | - |
---
### 第五层:高级 API

View File

@ -455,9 +455,46 @@ You can also use reactive `tp-text` directly in property lists without defining
2. **Preserves existing properties**: When using `tp-set` or `tp-add` to set `tp-text`, existing text properties are preserved.
3. **Non-reactive properties don't add tp-name**: If there are no reactive variables (`$` prefix) in the text properties, `tp-name` and other reactive-specific properties won't be added, maintaining native text property behavior.
## Value Transformation with :transform
The `:transform` keyword allows you to register a transformation function that processes `tp-text` values before they are displayed. This is useful for formatting numbers, dates, or other values:
```lisp
;; Number formatting
(tp-define-layer 'price-display
:props '(tp-text $price)
:data '((price . "99.9"))
:transform (lambda (text)
(format "$%.2f" (string-to-number text))))
;; 99.9 displays as $99.00
;; Date formatting
(tp-define-layer '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)))))
;; Uppercase conversion
(tp-define-layer 'uppercase-text
:props '(tp-text $content)
:data '((content . "hello"))
:transform #'upcase)
;; "hello" displays as "HELLO"
```
The transform function:
- Receives the raw `tp-text` string value
- Returns the transformed string for display
- Is applied both on initial display and reactive updates
- Errors in transform functions are caught and logged
> 📖 **For more optimization features like batched updates and debug mode, see [Reactive System Optimization](reactive-optimization-en.md)**
## Summary
tp.el's reactive text properties feature brings a modern reactive programming experience to Emacs development. By using `$`-prefixed reactive variables, `:data` to define state, `:compute` for derived values, and `:watch` to monitor changes, you can build a more dynamic and maintainable text property system.
tp.el's reactive text properties feature brings a modern reactive programming experience to Emacs development. By using `$`-prefixed reactive variables, `:data` to define state, `:compute` for derived values, `:watch` to monitor changes, and `:transform` for value formatting, you can build a more dynamic and maintainable text property system.
Key points:
1. **Reactive Variables**: Use `$` prefix to reference variables
@ -465,5 +502,6 @@ Key points:
3. **:data**: Define additional reactive state and initial values
4. **:compute**: Define computed properties derived from other variables
5. **:watch**: Watch variable changes and execute side effects
6. **Automatic Updates**: Change variable values, all related text updates automatically
7. **Reactive Text (tp-text)**: Make text content itself reactive
6. **:transform**: Transform tp-text values before display
7. **Automatic Updates**: Change variable values, all related text updates automatically
8. **Reactive Text (tp-text)**: Make text content itself reactive

View File

@ -455,9 +455,46 @@ tp.el 的响应式系统借鉴了 Vue 的 API提供了三个强大的关键
2. **保留现有属性**:使用 `tp-set``tp-add` 设置 `tp-text` 时,现有的文本属性会被保留。
3. **非响应式属性不添加 tp-name**:如果文本属性中没有响应式变量(`$` 前缀),则不会添加 `tp-name` 等响应式专用属性,保持原生文本属性行为。
## 使用 :transform 进行值转换
`:transform` 关键字允许你注册一个转换函数,在 `tp-text` 值显示之前对其进行处理。这对于格式化数字、日期或其他值非常有用:
```lisp
;; 数字格式化
(tp-define-layer 'price-display
:props '(tp-text $price)
:data '((price . "99.9"))
:transform (lambda (text)
(format "$%.2f" (string-to-number text))))
;; 99.9 显示为 $99.00
;; 日期格式化
(tp-define-layer '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)))))
;; 大写转换
(tp-define-layer 'uppercase-text
:props '(tp-text $content)
:data '((content . "hello"))
:transform #'upcase)
;; "hello" 显示为 "HELLO"
```
转换函数的特点:
- 接收原始的 `tp-text` 字符串值
- 返回用于显示的转换后字符串
- 在初始显示和响应式更新时都会应用
- 转换函数中的错误会被捕获并记录
> 📖 **更多优化功能如批量更新和调试模式,请参阅 [响应式系统优化文档](reactive-optimization.md)**
## 总结
tp.el 的响应式文本属性功能为 Emacs 开发带来了现代化的响应式编程体验。通过使用 `$` 前缀的响应式变量、`:data` 定义状态、`:compute` 计算派生值、`:watch` 监听变化,你可以构建出更加动态、易于维护的文本属性系统。
tp.el 的响应式文本属性功能为 Emacs 开发带来了现代化的响应式编程体验。通过使用 `$` 前缀的响应式变量、`:data` 定义状态、`:compute` 计算派生值、`:watch` 监听变化、`:transform` 格式化值,你可以构建出更加动态、易于维护的文本属性系统。
核心要点:
1. **响应式变量**:使用 `$` 前缀引用变量
@ -465,5 +502,6 @@ tp.el 的响应式文本属性功能为 Emacs 开发带来了现代化的响应
3. **:data**:定义额外的响应式状态和初始值
4. **:compute**:定义由其他变量派生的计算属性
5. **:watch**:监听变量变化并执行副作用
6. **自动更新**:改变变量值,所有相关文本自动更新
7. **响应式文本 (tp-text)**:让文本内容本身也能响应式更新
6. **:transform**:在显示之前转换 tp-text 值
7. **自动更新**:改变变量值,所有相关文本自动更新
8. **响应式文本 (tp-text)**:让文本内容本身也能响应式更新