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>
This commit is contained in:
copilot-swe-agent[bot] 2026-01-05 17:30:02 +00:00
parent 933acf0292
commit ebe0922c9c
2 changed files with 31 additions and 4 deletions

View File

@ -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)
;;; ============================================================

15
tp.el
View File

@ -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