From ebe0922c9c7e28e41e0e7d21b85fbb4ee73146c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:30:02 +0000 Subject: [PATCH] Fix tp-text property detection to scan entire string Use tp--string-has-properties-p helper function instead of checking only position 0. This properly detects text properties that start at non-zero positions in the string. Added test tp-test-tp-text-with-properties-starting-at-nonzero to verify this fix. Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com> --- tp-tests.el | 20 ++++++++++++++++++++ tp.el | 15 +++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/tp-tests.el b/tp-tests.el index d1d6af1..5cdcb4a 100644 --- a/tp-tests.el +++ b/tp-tests.el @@ -3124,6 +3124,26 @@ the inserted text should be that string, not the source text." ;; The embedded custom-prop from tp-text should be preserved (should (equal (tp-at 0 'custom-prop result) 'value)))) +(ert-deftest tp-test-tp-text-with-properties-starting-at-nonzero () + "Test that tp-text with properties starting at non-zero position are preserved." + ;; This tests the fix for the issue where only position 0 was checked + (let* ((propertized-text (copy-sequence "Hello")) + ;; Set properties starting at position 2, not 0 + (_ (put-text-property 2 5 'custom-prop 'value propertized-text)) + (result (tp-set "X" 'tp-text propertized-text 'face 'bold))) + ;; The text content should be from tp-text + (should (equal result "Hello")) + ;; The face from props should be applied uniformly + (should (equal (tp-at 0 'face result) 'bold)) + (should (equal (tp-at 2 'face result) 'bold)) + ;; Position 0-1 should NOT have custom-prop + (should (null (tp-at 0 'custom-prop result))) + (should (null (tp-at 1 'custom-prop result))) + ;; Position 2-4 should have custom-prop + (should (equal (tp-at 2 'custom-prop result) 'value)) + (should (equal (tp-at 3 'custom-prop result) 'value)) + (should (equal (tp-at 4 'custom-prop result) 'value)))) + ;;; ============================================================ ;;; New define-tp Format Tests (Parameterized and Non-Parameterized) ;;; ============================================================ diff --git a/tp.el b/tp.el index 69fab3c..335d76d 100644 --- a/tp.el +++ b/tp.el @@ -252,6 +252,13 @@ NEW values override BASE values." (t val)))))) result)) +(defun tp--string-has-properties-p (str) + "Return non-nil if string STR has any text properties. +Scans the entire string, not just position 0." + (and (stringp str) + (> (length str) 0) + (not (null (object-intervals str))))) + (defun tp--apply-string-props-to-region (str start &optional object) "Apply text properties from string STR to buffer region starting at START. For each character position in STR, its text properties are applied to @@ -929,8 +936,8 @@ Text properties embedded in NEW-TEXT are preserved." (goto-char (point-min)) (let ((match (text-property-search-forward 'tp-name layer-name t)) ;; Check if new-text has embedded text properties - (new-text-has-props (and (stringp new-text) - (text-properties-at 0 new-text)))) + ;; Use tp--string-has-properties-p to scan the entire string + (new-text-has-props (tp--string-has-properties-p new-text))) (while match (let* ((m-start (prop-match-beginning match)) (m-end (prop-match-end match)) @@ -1006,8 +1013,8 @@ NEW-OBJECT is the new string object (only different for strings with tp-text)." tp-text-val)) tp-text-val)) ;; Check if final-text has text properties that should be preserved - (tp-text-has-props (and (stringp final-text) - (text-properties-at 0 final-text)))) + ;; Use tp--string-has-properties-p to scan the entire string + (tp-text-has-props (tp--string-has-properties-p final-text))) (if (stringp object) ;; For strings: create a new string with tp-text content ;; Preserve any text properties from the tp-text value itself