README.md/README_CN.md: new verified Quick Start (fixes the dead #quick-start nav link); Installation rewritten for the tp-*.el module family; every broken or drifted example fixed and executed in batch Emacs (mandatory () ARGLIST and quoted reactive keywords in all define-tp/define-tps calls, corrected tp-search-map argument order, interval-list returns, stacked duplicate-face results, gap intervals, last-wins tp-plist, non-destructive string forms, per-pattern match ordering, case-fold regexp outputs, rewired end-to-end theme example); documents the symmetric tp-backward contract, the length-changing replacement rules, all four tp-put-layer layer specs, and the previously-missing tp-member, buffer/display macros, and palette system; state resets now use tp-layer-reset; license corrected to GPLv3+. CN mirrors EN exactly (119 headings / 258 fences each; code blocks identical, comments translated). docs/ARCHITECTURE.md rewritten around the real nine-module layering and hook-variable inversions; nonexistent helper names removed. docs/CODE-ANALYSIS.md marked as pre-split historical analysis with locations/counts corrected. Reactive docs aligned with the fixed engine semantics (replace-not-accumulate, buffer-local isolation, nil computed values, batching union, first-render transform). 287 fenced blocks from both READMEs executed: 0 failures; 56-example assertion suite passes; combined ERT suite 439/439 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.7 KiB
tp.el Reactive System Optimization Documentation
This document describes the optimizations and enhancements made to the tp.el reactive system based on practical experience from the twidget project.
Optimization Suggestions Evaluation
The following evaluates and documents the implementation status of six optimization suggestions for the tp.el reactive system:
1. Granular Reactive Updates
Suggestion: Support partial updates within a region - only updating the reactive portion while preserving surrounding text properties.
Evaluation: Already implemented. tp.el uses tp-search-map over tp-name-tagged regions and interval-based update mechanisms to support fine-grained property updates. Updates only affect regions with specific tp-name properties, and only the layer's own property keys are replaced — properties contributed by other sources are left untouched.
2. Reactive Symbol Cleanup ✅ Already Implemented
Suggestion: Add a mechanism to unregister reactive symbols when widgets are destroyed.
Evaluation: Already implemented. The tp--unregister-reactive-deps function handles cleanup:
- Called automatically when a layer is redefined
- Called automatically when a layer is undefined (
tp-undefine-layer) - Cleans up variable watchers, computed properties, and data variables
Key functions:
tp--unregister-reactive-depstp--unregister-layer-watcherstp--unregister-layer-computedtp--unregister-layer-data
3. Scoped Reactivity ✅ Already Implemented
Suggestion: Add instance/context scoping for reactive variables.
Evaluation: Already implemented. The where parameter supports buffer-local updates in:
tp--update-layer-regionstp--update-reactive-text
When using setq-local, updates only affect the specific buffer.
4. Batched Updates 🆕 New Feature
Suggestion: When multiple reactive values change simultaneously, batch updates to avoid redundant buffer modifications.
Implementation: Added tp-with-batch-updates macro:
;; Using batch updates
(tp-with-batch-updates
(setq my-color "red")
(setq my-size 14)
(setq my-text "Hello"))
;; All updates applied to buffer once at the end
Key functions and variables:
tp-with-batch-updates- Batch update macrotp--batch-update-active- Flag indicating batch modetp--batch-update-pending- List of pending updatestp--flush-batch-updates- Apply all pending updates
5. Value Transformation 🆕 New Feature
Suggestion: Allow registering transformation functions that run when tp-text updates.
Implementation: Added :transform option:
;; Define a layer with transformation
(define-tp currency-display ()
:props '(face bold tp-text $amount)
:data '((amount . "100"))
:transform (lambda (text)
(format "$%s.00" text)))
;; After application, 100 displays as $100.00
Key functions and variables:
tp-layer-transforms- Stores layer transform functions- Transforms applied in
tp--handle-tp-text-propertyandtp--update-reactive-text
6. Debug Mode 🆕 New Feature
Suggestion: Add a debug mode to trace reactive updates.
Implementation: Added debug functionality:
;; Enable debug mode
(setq tp-debug-mode t)
;; Also show debug info in minibuffer
(setq tp-debug-echo t)
;; View debug log
(tp-debug-show)
;; Clear debug log
(tp-debug-clear)
Key functions and variables:
tp-debug-mode- Enable/disable debug modetp-debug-echo- Whether to echo debug info to minibuffertp-debug-log- Log debug informationtp-debug-show- Show debug buffertp-debug-clear- Clear debug log
Debug log includes:
- Variable change notifications (old → new value)
- Layer update tracking
- Batch update start/end
- Transform application info
New Features in Detail
Batch Updates (tp-with-batch-updates)
When modifying multiple reactive variables simultaneously, use batch updates to avoid multiple buffer 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)
;; 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
Value Transformation (:transform)
Transform functions allow processing tp-text values before display:
;; Number formatting
(define-tp price-display ()
:props '(tp-text $price)
:data '((price . "99.9"))
:transform (lambda (text)
(format "$%.2f" (string-to-number text))))
;; Date formatting
(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)))))
;; Uppercase conversion
(define-tp uppercase-text ()
:props '(tp-text $content)
:data '((content . "hello"))
:transform #'upcase)
Debug Mode
Debug mode helps developers understand the reactive update flow:
;; Enable full debugging
(setq tp-debug-mode t)
(setq tp-debug-echo t)
;; Define and use a reactive layer
(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"))
;; 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)
Architecture Notes
These optimizations follow tp.el's layered architecture principles:
- Debug Mode - Basic utility layer functionality (
tp-core.el) - Batch Updates - Implemented in the reactive system layer (
tp-reactive.el) - Value Transformation - Implemented in layer definition and reactive text handling (
tp-layer.el/tp-render.el)
All new features integrate seamlessly with the existing reactive system without breaking existing APIs.
Function Reference
| Function/Variable | Description |
|---|---|
tp-debug-mode |
Enable debug mode |
tp-debug-echo |
Enable minibuffer debug output |
tp-debug-log |
Log debug information |
tp-debug-show |
Show debug buffer |
tp-debug-clear |
Clear debug log |
tp-with-batch-updates |
Batch update macro |
tp-layer-transforms |
Layer transform function storage |
:transform |
Transform option in layer definition |