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 ;; The embedded custom-prop from tp-text should be preserved
(should (equal (tp-at 0 'custom-prop result) 'value)))) (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) ;;; 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)))))) (t val))))))
result)) 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) (defun tp--apply-string-props-to-region (str start &optional object)
"Apply text properties from string STR to buffer region starting at START. "Apply text properties from string STR to buffer region starting at START.
For each character position in STR, its text properties are applied to 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)) (goto-char (point-min))
(let ((match (text-property-search-forward 'tp-name layer-name t)) (let ((match (text-property-search-forward 'tp-name layer-name t))
;; Check if new-text has embedded text properties ;; Check if new-text has embedded text properties
(new-text-has-props (and (stringp new-text) ;; Use tp--string-has-properties-p to scan the entire string
(text-properties-at 0 new-text)))) (new-text-has-props (tp--string-has-properties-p new-text)))
(while match (while match
(let* ((m-start (prop-match-beginning match)) (let* ((m-start (prop-match-beginning match))
(m-end (prop-match-end 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))
tp-text-val)) tp-text-val))
;; Check if final-text has text properties that should be preserved ;; Check if final-text has text properties that should be preserved
(tp-text-has-props (and (stringp final-text) ;; Use tp--string-has-properties-p to scan the entire string
(text-properties-at 0 final-text)))) (tp-text-has-props (tp--string-has-properties-p final-text)))
(if (stringp object) (if (stringp object)
;; For strings: create a new string with tp-text content ;; For strings: create a new string with tp-text content
;; Preserve any text properties from the tp-text value itself ;; Preserve any text properties from the tp-text value itself