Extract only reactive sub-properties for minimal incremental updates

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-12-20 06:50:39 +00:00
parent c22b596883
commit 7667d1a139
2 changed files with 29 additions and 3 deletions

View File

@ -1877,9 +1877,14 @@ Returns list of (START END VALUE) intervals."
;; Single reactive property ;; Single reactive property
(should (equal (tp--extract-reactive-props '(help-echo "test" face (:foreground $color)) '$color) (should (equal (tp--extract-reactive-props '(help-echo "test" face (:foreground $color)) '$color)
'(face (:foreground $color)))) '(face (:foreground $color))))
;; Multiple properties, only one uses the variable ;; Multiple properties, only one uses the variable - should extract only reactive sub-props
(should (equal (tp--extract-reactive-props '(help-echo "test" face (:foreground $color :background "green")) '$color) (should (equal (tp--extract-reactive-props '(help-echo "test" face (:foreground $color :background "green")) '$color)
'(face (:foreground $color :background "green")))) '(face (:foreground $color))))
;; Nested plist with reactive variable - should extract only reactive nested sub-props
(should (equal (tp--extract-reactive-props
'(face (:foreground $color1 :underline (:style wave :color $color2 :position t)))
'$color2)
'(face (:underline (:color $color2)))))
;; No properties use the variable ;; No properties use the variable
(should (null (tp--extract-reactive-props '(help-echo "test" face bold) '$color)))) (should (null (tp--extract-reactive-props '(help-echo "test" face bold) '$color))))

23
tp.el
View File

@ -86,14 +86,35 @@ Returns a list of reactive symbols found."
(tp--collect-reactive-symbols (cdr form)))) (tp--collect-reactive-symbols (cdr form))))
(t nil))) (t nil)))
(defun tp--extract-reactive-value (val reactive-var)
"Extract only the parts of VAL that use REACTIVE-VAR.
If VAL is a plist, recursively extract only the key-value pairs containing REACTIVE-VAR.
If VAL directly contains REACTIVE-VAR, return VAL as-is.
REACTIVE-VAR should be the $-prefixed symbol (e.g., $my-color)."
(cond
;; If val is the reactive var itself, return it
((eq val reactive-var) val)
;; If val is a plist (starts with a keyword), extract reactive parts recursively
((and (listp val) (keywordp (car val)))
(let ((result nil))
(cl-loop for (key subval) on val by #'cddr
when (member reactive-var (tp--collect-reactive-symbols subval))
do (setq result (plist-put result key
(tp--extract-reactive-value subval reactive-var))))
result))
;; Otherwise return val as-is if it contains the reactive var
(t val)))
(defun tp--extract-reactive-props (plist reactive-var) (defun tp--extract-reactive-props (plist reactive-var)
"Extract only the properties from PLIST that use REACTIVE-VAR. "Extract only the properties from PLIST that use REACTIVE-VAR.
Returns a plist containing only the key-value pairs that reference REACTIVE-VAR. Returns a plist containing only the key-value pairs that reference REACTIVE-VAR.
For nested plists, only the sub-properties containing REACTIVE-VAR are included.
REACTIVE-VAR should be the $-prefixed symbol (e.g., $my-color)." REACTIVE-VAR should be the $-prefixed symbol (e.g., $my-color)."
(let ((result nil)) (let ((result nil))
(cl-loop for (key val) on plist by #'cddr (cl-loop for (key val) on plist by #'cddr
when (member reactive-var (tp--collect-reactive-symbols val)) when (member reactive-var (tp--collect-reactive-symbols val))
do (setq result (plist-put result key val))) do (setq result (plist-put result key
(tp--extract-reactive-value val reactive-var))))
result)) result))
(defun tp--resolve-reactive-symbols (form &optional override-alist) (defun tp--resolve-reactive-symbols (form &optional override-alist)