From 7667d1a1396c62a338936afd2ce377ac37887845 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 20 Dec 2025 06:50:39 +0000 Subject: [PATCH] Extract only reactive sub-properties for minimal incremental updates Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com> --- tp-tests.el | 9 +++++++-- tp.el | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/tp-tests.el b/tp-tests.el index e452cd8..d2b2b54 100644 --- a/tp-tests.el +++ b/tp-tests.el @@ -1877,9 +1877,14 @@ Returns list of (START END VALUE) intervals." ;; Single reactive property (should (equal (tp--extract-reactive-props '(help-echo "test" face (:foreground $color)) '$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) - '(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 (should (null (tp--extract-reactive-props '(help-echo "test" face bold) '$color)))) diff --git a/tp.el b/tp.el index 3279d85..2e150c9 100644 --- a/tp.el +++ b/tp.el @@ -86,14 +86,35 @@ Returns a list of reactive symbols found." (tp--collect-reactive-symbols (cdr form)))) (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) "Extract only the properties from PLIST that use 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)." (let ((result nil)) (cl-loop for (key val) on plist by #'cddr 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)) (defun tp--resolve-reactive-symbols (form &optional override-alist)