tp/docs/reactive-optimization-en.md
Kinneyzhang 2b33495898 Align README (EN/CN) and docs/ with modular architecture and 0.2.0 semantics
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>
2026-07-26 21:01:01 +08:00

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-deps
  • tp--unregister-layer-watchers
  • tp--unregister-layer-computed
  • tp--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-regions
  • tp--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 macro
  • tp--batch-update-active - Flag indicating batch mode
  • tp--batch-update-pending - List of pending updates
  • tp--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-property and tp--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 mode
  • tp-debug-echo - Whether to echo debug info to minibuffer
  • tp-debug-log - Log debug information
  • tp-debug-show - Show debug buffer
  • tp-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:

  1. Debug Mode - Basic utility layer functionality (tp-core.el)
  2. Batch Updates - Implemented in the reactive system layer (tp-reactive.el)
  3. 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