Fix define-tps to set multi-layer properties with tp-layers structure

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-01-04 12:54:36 +00:00
parent a481327727
commit b58065293b
2 changed files with 34 additions and 38 deletions

View File

@ -2104,7 +2104,7 @@ When using tp-regexp-add (direct property setting), tp-name is NOT added."
(ert-deftest tp-test-set-with-group-name ()
"Test tp-set accepts a group name defined by define-tps.
When using tp-set (direct property setting), tp-name is NOT added."
When using tp-set with a group, layers are set with tp-name and tp-layers."
(tp-test-with-temp-buffer
(insert "Hello World")
(define-tps my-group ()
@ -2113,30 +2113,29 @@ When using tp-set (direct property setting), tp-name is NOT added."
(tp-set 1 6 'my-group)
(should (eq (tp-at 1 'face) 'bold))
(should (equal (tp-at 1 'help-echo) "grouped"))
;; tp-name should NOT be set for direct property setting
(should-not (tp-at 1 'tp-name))))
;; tp-name should be set for layer groups
(should (tp-at 1 'tp-name))))
(ert-deftest tp-test-set-with-group-name-multiple-layers ()
"Test tp-set with group containing multiple layers.
When using tp-set (direct property setting), tp-name and tp-layers are NOT added.
Only the first layer's properties are applied."
When using tp-set with a group, all layers are set with tp-name and tp-layers."
(tp-test-with-temp-buffer
(insert "Hello World")
(define-tps my-group ()
'("first" . (face bold))
'("second" . (face italic)))
;; Use group name - only first layer is applied (no layer stacking for direct setting)
;; Use group name - all layers are applied with tp-layers structure
(tp-set 1 6 'my-group)
;; First layer's properties are applied
;; First layer's properties are applied at top
(should (eq (tp-at 1 'face) 'bold))
;; tp-name should NOT be set for direct property setting
(should-not (tp-at 1 'tp-name))
;; tp-layers should NOT be set for direct property setting
(should-not (tp-at 1 'tp-layers))))
;; tp-name should be set for the top layer
(should (tp-at 1 'tp-name))
;; tp-layers should contain the rest of the layers
(should (tp-at 1 'tp-layers))))
(ert-deftest tp-test-match-set-with-group-name ()
"Test tp-match-set accepts a group name.
When using tp-match-set (direct property setting), tp-name is NOT added."
When using tp-match-set with a group, layers are set with tp-name."
(tp-test-with-temp-buffer
(insert "Hello World Hello")
(define-tps my-group ()
@ -2144,8 +2143,8 @@ When using tp-match-set (direct property setting), tp-name is NOT added."
(tp-match-set "Hello" 'my-group)
(should (eq (tp-at 1 'face) 'italic))
(should (eq (tp-at 13 'face) 'italic))
;; tp-name should NOT be set for direct property setting
(should-not (tp-at 1 'tp-name))))
;; tp-name should be set for layer groups
(should (tp-at 1 'tp-name))))
(ert-deftest tp-test-resolve-props-returns-nil-for-unknown ()
"Test tp--resolve-props returns nil for unknown layer name."

45
tp.el
View File

@ -2994,16 +2994,14 @@ Returns the expanded plist."
(tp-layer-props key nil)) ; no tp-name
;; Parameterized layer group - evaluate with the argument (val)
((tp-group-parameterized-p key)
(when-let ((layer-props-list (tp-group-props-with-arg key val nil)))
;; Merge all layers' properties (reverse so first layer wins)
(apply #'append (reverse layer-props-list))))
;; Non-parameterized layer group - merge all layers' properties
(when-let ((layer-props-list (tp-group-props-with-arg key val t)))
;; Build layered structure: first layer at top, rest in tp-layers
(tp--build-layer-props layer-props-list)))
;; Non-parameterized layer group - build layered structure
((assoc key tp-layer-groups)
(when-let ((layer-props-list (tp-group-props key)))
;; For direct property setting, merge all layers' properties
;; without the tp-layers structure.
;; Reverse so first layer's properties are applied last (take precedence)
(apply #'append (reverse layer-props-list)))))))
(when-let ((layer-props-list (tp-group-props key t)))
;; Build layered structure: first layer at top, rest in tp-layers
(tp--build-layer-props layer-props-list))))))
(when layer-props
;; Recursively expand if the layer props contain more layer names
(when (tp--plist-has-layer-key-p layer-props)
@ -3076,16 +3074,14 @@ For group names, includes `tp-layers' property with the full layer stack."
(tp-layer-props first-elem nil)) ; no tp-name
;; Parameterized layer group - evaluate with the argument
((tp-group-parameterized-p first-elem)
(when-let ((layer-props-list (tp-group-props-with-arg first-elem second-elem nil)))
;; Merge all layers' properties (reverse so first layer wins)
(apply #'append (reverse layer-props-list))))
;; Non-parameterized layer group - merge all layers' properties
(when-let ((layer-props-list (tp-group-props-with-arg first-elem second-elem t)))
;; Build layered structure: first layer at top, rest in tp-layers
(tp--build-layer-props layer-props-list)))
;; Non-parameterized layer group - build layered structure
((assoc first-elem tp-layer-groups)
(when-let ((layer-props-list (tp-group-props first-elem)))
;; For direct property setting, merge all layers' properties
;; without the tp-layers structure.
;; Reverse so first layer's properties are applied last (take precedence)
(apply #'append (reverse layer-props-list)))))))
(when-let ((layer-props-list (tp-group-props first-elem t)))
;; Build layered structure: first layer at top, rest in tp-layers
(tp--build-layer-props layer-props-list))))))
;; Recursively resolve extra properties (they may also contain layer names)
(let ((expanded-props
(if (and layer-props extra-props)
@ -3174,13 +3170,14 @@ For group names, includes `tp-layers' property with the full layer stack."
;; Check layer - get props without tp-name for direct property setting
((assoc props tp-layer-alist)
(tp-layer-props props nil)) ; no tp-name
;; Check group - merge all layers' properties for direct setting
;; Check group - build layered structure with tp-layers
((assoc props tp-layer-groups)
(when-let ((layer-props-list (tp-group-props props)))
;; For direct property setting, merge all layers' properties
;; without the tp-layers structure.
;; Reverse so first layer's properties are applied last (take precedence)
(apply #'append (reverse layer-props-list))))
(when-let ((layer-props-list (tp-group-props props t))) ; include tp-name
;; Build layered structure: first layer at top, rest in tp-layers
(tp--build-layer-props layer-props-list)))
;; Parameterized group without argument - cannot resolve, return nil
((tp-group-parameterized-p props)
nil)
;; Not found - return nil (let caller decide how to handle)
(t nil)))
(t nil)))