diff --git a/tp-tests.el b/tp-tests.el index 8a0b119..873cc16 100644 --- a/tp-tests.el +++ b/tp-tests.el @@ -3330,5 +3330,46 @@ When using tp-set (direct property setting), tp-name is NOT added." (should (equal (get-text-property 0 'test1 result) "value1")) (should (equal (get-text-property 0 'test2 result) "value2"))))) +;; Tests for tp-push-layer and tp-put-layer with define-tp layers +(ert-deftest tp-test-push-layer-non-parameterized () + "Test tp-push-layer with non-parameterized define-tp layer." + (tp-test-with-temp-buffer + (define-tp tp-bold () + '(face bold)) + ;; String form + (let ((result (tp-push-layer "emacs" 'tp-bold))) + (should (eq (get-text-property 0 'tp-name result) 'tp-bold)) + (should (eq (get-text-property 0 'face result) 'bold))))) + +(ert-deftest tp-test-push-layer-parameterized () + "Test tp-push-layer with parameterized define-tp layer." + (tp-test-with-temp-buffer + (define-tp tp-space (pixel) + `(display (space :width (,pixel)))) + ;; String form with parameterized layer + (let ((result (tp-push-layer "emacs" '(tp-space 6)))) + (should (eq (get-text-property 0 'tp-name result) 'tp-space)) + (should (equal (get-text-property 0 'display result) '(space :width (6))))))) + +(ert-deftest tp-test-put-layer-non-parameterized () + "Test tp-put-layer with non-parameterized define-tp layer." + (tp-test-with-temp-buffer + (define-tp tp-italic () + '(face italic)) + ;; String form + (let ((result (tp-put-layer "emacs" 'tp-italic 0))) + (should (eq (get-text-property 0 'tp-name result) 'tp-italic)) + (should (eq (get-text-property 0 'face result) 'italic))))) + +(ert-deftest tp-test-put-layer-parameterized () + "Test tp-put-layer with parameterized define-tp layer." + (tp-test-with-temp-buffer + (define-tp tp-width (pixels) + `(display (space :width (,pixels)))) + ;; String form with parameterized layer + (let ((result (tp-put-layer "emacs" '(tp-width 10) 0))) + (should (eq (get-text-property 0 'tp-name result) 'tp-width)) + (should (equal (get-text-property 0 'display result) '(space :width (10))))))) + (provide 'tp-ert-tests) ;;; tp-ert-tests.el ends here diff --git a/tp.el b/tp.el index 7afeba4..f5acb0b 100644 --- a/tp.el +++ b/tp.el @@ -2733,20 +2733,48 @@ Returns a list of (START END PROPERTIES) for matching intervals." (defun tp--normalize-layer-spec (layer-spec) "Normalize LAYER-SPEC to a plist with tp-name. -Used by layer stack functions that need tp-name for identification." +Used by layer stack functions that need tp-name for identification. + +LAYER-SPEC can be: +- A symbol (non-parameterized layer name from define-tp or tp-define-layer) +- A list (LAYER-NAME ARG) for parameterized layers from define-tp +- A plist for inline layer definition +- A list (NAME &rest PLIST) for named inline layer" (cond - ;; Symbol - look up in tp-layer-alist + ;; Symbol - look up in tp-layer-alist (non-parameterized layer) ((symbolp layer-spec) - (or (tp-layer-props layer-spec t) ; include tp-name for layer stack - (error "Layer %S not found in tp-layer-alist" layer-spec))) - ;; List starting with symbol followed by plist - named inline layer (name &rest plist) + (cond + ;; Parameterized layer symbol without arg - error + ((tp-layer-parameterized-p layer-spec) + (error "Parameterized layer %S requires an argument, use '(%S arg)" + layer-spec layer-spec)) + ;; Non-parameterized layer or old-format layer + ((assoc layer-spec tp-layer-alist) + (or (tp-layer-props layer-spec t) ; include tp-name for layer stack + (error "Layer %S not found in tp-layer-alist" layer-spec))) + (t (error "Layer %S not found in tp-layer-alist" layer-spec)))) + + ;; List starting with symbol - check if it's a parameterized layer ((and (listp layer-spec) (symbolp (car layer-spec)) - (not (keywordp (car layer-spec))) - (cdr layer-spec)) + (not (keywordp (car layer-spec)))) (let ((name (car layer-spec)) - (props (cdr layer-spec))) - (append props (list 'tp-name name)))) + (rest (cdr layer-spec))) + (cond + ;; Parameterized layer: (LAYER-NAME ARG) + ((and (tp-layer-parameterized-p name) + (= (length rest) 1)) + (or (tp-layer-props-with-arg name (car rest) t) ; include tp-name + (error "Failed to resolve parameterized layer %S with arg %S" + name (car rest)))) + ;; Named inline layer: (NAME &rest PLIST) + (rest + (append rest (list 'tp-name name))) + ;; Just a symbol in a list - treat as non-parameterized layer + ((null rest) + (or (tp-layer-props name t) + (error "Layer %S not found in tp-layer-alist" name)))))) + ;; Plist (starts with keyword or property name) ((and (listp layer-spec) layer-spec) layer-spec)