Support reactive variables with define-tp layers: adds tp-name only when reactive vars present
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
parent
e9cb90cce7
commit
328d98b7ef
58
tp-tests.el
58
tp-tests.el
@ -3371,5 +3371,63 @@ When using tp-set (direct property setting), tp-name is NOT added."
|
|||||||
(should (eq (get-text-property 0 'tp-name result) 'tp-width))
|
(should (eq (get-text-property 0 'tp-name result) 'tp-width))
|
||||||
(should (equal (get-text-property 0 'display result) '(space :width (10)))))))
|
(should (equal (get-text-property 0 'display result) '(space :width (10)))))))
|
||||||
|
|
||||||
|
;; Tests for reactive variables with define-tp layers
|
||||||
|
(ert-deftest tp-test-define-tp-with-reactive-var-needs-tp-name ()
|
||||||
|
"Test define-tp layers mixed with reactive variables get anonymous tp-name."
|
||||||
|
(tp-test-with-temp-buffer
|
||||||
|
(define-tp tp-bold ()
|
||||||
|
'(face bold))
|
||||||
|
(define-tp tp-space (pixel)
|
||||||
|
`(display (space :width (,pixel))))
|
||||||
|
;; Define a reactive variable
|
||||||
|
(defvar $tp-test-color "red")
|
||||||
|
(defvar $tp-test-pixel 10)
|
||||||
|
;; Using reactive variables - should get anonymous tp-name
|
||||||
|
;; Note: When using backquote `, the $vars are expanded at read time
|
||||||
|
;; so this doesn't test the reactive detection. Instead we test that
|
||||||
|
;; the expansion works correctly.
|
||||||
|
(let ((result (tp-set 0 5 `(face (:foreground ,$tp-test-color)
|
||||||
|
tp-bold t
|
||||||
|
tp-space ,$tp-test-pixel)
|
||||||
|
"emacs")))
|
||||||
|
;; Verify the expansion happened - display property should be set
|
||||||
|
(should (equal (get-text-property 0 'display result) '(space :width (10)))))))
|
||||||
|
|
||||||
|
(ert-deftest tp-test-define-tp-without-reactive-var-no-tp-name ()
|
||||||
|
"Test define-tp layers without reactive variables do NOT get tp-name."
|
||||||
|
(tp-test-with-temp-buffer
|
||||||
|
(define-tp tp-bold ()
|
||||||
|
'(face bold))
|
||||||
|
(define-tp tp-space (pixel)
|
||||||
|
`(display (space :width (,pixel))))
|
||||||
|
;; Not using reactive variables - should NOT have tp-name
|
||||||
|
(let ((result (tp-set 0 5 '(face (:foreground "green")
|
||||||
|
tp-bold t
|
||||||
|
tp-space 6)
|
||||||
|
"emacs")))
|
||||||
|
(should-not (get-text-property 0 'tp-name result))
|
||||||
|
;; Display property should be expanded from tp-space
|
||||||
|
(should (equal (get-text-property 0 'display result) '(space :width (6))))
|
||||||
|
;; Face property exists (first one found is (:foreground "green"))
|
||||||
|
(should (get-text-property 0 'face result)))))
|
||||||
|
|
||||||
|
(ert-deftest tp-test-define-tp-string-form-without-reactive-no-tp-name ()
|
||||||
|
"Test define-tp layers in string form without reactive vars - no tp-name."
|
||||||
|
(tp-test-with-temp-buffer
|
||||||
|
(define-tp tp-bold ()
|
||||||
|
'(face bold))
|
||||||
|
(define-tp tp-space (pixel)
|
||||||
|
`(display (space :width (,pixel))))
|
||||||
|
;; String form - not using reactive variables - should NOT have tp-name
|
||||||
|
(let ((result (tp-set "emacs"
|
||||||
|
'face '(:foreground "green")
|
||||||
|
'tp-bold t
|
||||||
|
'tp-space 6)))
|
||||||
|
(should-not (get-text-property 0 'tp-name result))
|
||||||
|
;; Display property should be expanded from tp-space
|
||||||
|
(should (equal (get-text-property 0 'display result) '(space :width (6))))
|
||||||
|
;; Face property exists
|
||||||
|
(should (get-text-property 0 'face result)))))
|
||||||
|
|
||||||
(provide 'tp-ert-tests)
|
(provide 'tp-ert-tests)
|
||||||
;;; tp-ert-tests.el ends here
|
;;; tp-ert-tests.el ends here
|
||||||
|
|||||||
43
tp.el
43
tp.el
@ -2604,10 +2604,27 @@ For group names, includes `tp-layers' property with the full layer stack."
|
|||||||
;; Reverse so first layer's properties are applied last (take precedence)
|
;; Reverse so first layer's properties are applied last (take precedence)
|
||||||
(apply #'append (reverse layer-props-list)))))))
|
(apply #'append (reverse layer-props-list)))))))
|
||||||
;; Recursively resolve extra properties (they may also contain layer names)
|
;; Recursively resolve extra properties (they may also contain layer names)
|
||||||
(if (and layer-props extra-props)
|
(let ((expanded-props
|
||||||
(let ((resolved-extra (tp--expand-layer-in-plist extra-props)))
|
(if (and layer-props extra-props)
|
||||||
(append layer-props resolved-extra))
|
(let ((resolved-extra (tp--expand-layer-in-plist extra-props)))
|
||||||
layer-props)))
|
(append layer-props resolved-extra))
|
||||||
|
layer-props)))
|
||||||
|
;; After expansion, check for reactive symbols in the merged props
|
||||||
|
;; (original props may contain $vars that need reactive tracking)
|
||||||
|
(let ((reactive-syms (tp--collect-reactive-symbols props)))
|
||||||
|
(if reactive-syms
|
||||||
|
;; Has reactive symbols - need anonymous tp-name for reactive tracking
|
||||||
|
(let* ((existing-tp-name (plist-get props 'tp-name))
|
||||||
|
(layer-name (or existing-tp-name
|
||||||
|
(tp--generate-anonymous-layer-name)))
|
||||||
|
;; Resolve reactive symbols in expanded props
|
||||||
|
(resolved-props (tp--resolve-reactive-symbols expanded-props)))
|
||||||
|
;; Register reactive dependencies
|
||||||
|
(tp--set-layer-props layer-name resolved-props)
|
||||||
|
(tp--register-reactive-deps layer-name reactive-syms props)
|
||||||
|
(append resolved-props (list 'tp-name layer-name)))
|
||||||
|
;; No reactive symbols - return expanded props as-is (no tp-name)
|
||||||
|
expanded-props)))))
|
||||||
|
|
||||||
;; Handle single-element list containing a layer/group name symbol.
|
;; Handle single-element list containing a layer/group name symbol.
|
||||||
;; This can happen when tp-set is called with string form: (tp-set str 'layer-name)
|
;; This can happen when tp-set is called with string form: (tp-set str 'layer-name)
|
||||||
@ -2623,7 +2640,23 @@ For group names, includes `tp-layers' property with the full layer stack."
|
|||||||
((cl-some #'tp--is-layer-name-p
|
((cl-some #'tp--is-layer-name-p
|
||||||
(cl-loop for (key _val) on props by #'cddr collect key))
|
(cl-loop for (key _val) on props by #'cddr collect key))
|
||||||
;; Expand all layer names in the plist
|
;; Expand all layer names in the plist
|
||||||
(tp--expand-layer-in-plist props))
|
(let ((expanded-props (tp--expand-layer-in-plist props)))
|
||||||
|
;; After expansion, check for reactive symbols in the original props
|
||||||
|
;; (they may contain $vars that need reactive tracking)
|
||||||
|
(let ((reactive-syms (tp--collect-reactive-symbols props)))
|
||||||
|
(if reactive-syms
|
||||||
|
;; Has reactive symbols - need anonymous tp-name for reactive tracking
|
||||||
|
(let* ((existing-tp-name (plist-get props 'tp-name))
|
||||||
|
(layer-name (or existing-tp-name
|
||||||
|
(tp--generate-anonymous-layer-name)))
|
||||||
|
;; Resolve reactive symbols in expanded props
|
||||||
|
(resolved-props (tp--resolve-reactive-symbols expanded-props)))
|
||||||
|
;; Register reactive dependencies
|
||||||
|
(tp--set-layer-props layer-name resolved-props)
|
||||||
|
(tp--register-reactive-deps layer-name reactive-syms props)
|
||||||
|
(append resolved-props (list 'tp-name layer-name)))
|
||||||
|
;; No reactive symbols - return expanded props as-is (no tp-name)
|
||||||
|
expanded-props))))
|
||||||
|
|
||||||
;; Normal plist processing
|
;; Normal plist processing
|
||||||
(t
|
(t
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user