From 467a4c16f4b230098c1bd560e39f9131bbb9a0f9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 5 Jan 2026 19:14:59 +0000 Subject: [PATCH] Fix tp-text to update when text properties differ even if text is same - Added `tp--equal-including-string-properties` helper function that uses `equal-including-properties` for strings to properly detect changes in text properties when the text content is the same - Updated `tp--reactive-variable-watcher` to use this new comparison function - Updated `tp--replace-reactive-text-in-buffer` to use `tp-add` when text content is the same but properties may differ - Added test `tp-test-tp-text-same-text-different-properties` to verify the fix Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com> --- tp-tests.el | 28 ++++++++++++++++++++++++++++ tp.el | 24 +++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/tp-tests.el b/tp-tests.el index 68e2e3e..40d9285 100644 --- a/tp-tests.el +++ b/tp-tests.el @@ -3038,6 +3038,34 @@ the inserted text should be that string, not the source text." (ignore-errors (makunbound 'tp-test-name-part2)) (ignore-errors (makunbound 'tp-test-full-text))))) +(ert-deftest tp-test-tp-text-same-text-different-properties () + "Test tp-text updates when text is same but properties differ. +When the reactive variable changes to a propertized string with the same +text content but different properties, the properties should be updated." + (tp-test-with-temp-buffer + (defvar tp-test-same-text nil "Test variable for same text different props.") + (setq tp-test-same-text "emacs") + (unwind-protect + (progn + (define-tp test-same-text-layer () + :props '(face (:foreground "green") tp-text $tp-test-same-text)) + ;; Apply layer to text + (insert "placeholder text here") + (tp-set 1 17 'test-same-text-layer) + ;; Initial text should be "emacs" with foreground green + (should (equal (buffer-substring-no-properties 1 6) "emacs")) + (should (equal (plist-get (tp-at 1 'face) :foreground) "green")) + ;; Change the reactive variable to same text but different properties + (setq tp-test-same-text (propertize "emacs" 'face 'bold)) + ;; Text should still be "emacs" + (should (equal (buffer-substring-no-properties 1 6) "emacs")) + ;; Face should now include bold from the propertized string + (let ((face-val (tp-at 1 'face))) + (should (or (eq face-val 'bold) + (and (listp face-val) (memq 'bold face-val)))))) + ;; Cleanup + (makunbound 'tp-test-same-text)))) + ;;; ============================================================ ;;; tp-text with Embedded Text Properties Tests ;;; ============================================================ diff --git a/tp.el b/tp.el index 91d99af..395540f 100644 --- a/tp.el +++ b/tp.el @@ -258,6 +258,15 @@ Scans the entire string, not just position 0." (and (stringp str) (not (null (object-intervals str))))) +(defun tp--equal-including-string-properties (a b) + "Compare A and B for equality, considering string text properties. +If either A or B is a string, uses `equal-including-properties' to ensure +text properties are considered in the comparison. +Otherwise, uses standard `equal'." + (if (or (stringp a) (stringp b)) + (equal-including-properties a b) + (equal a b))) + (defun tp--parse-face-list (face-list) "Parse a mixed face list into symbols and a plist. FACE-LIST can be a mix of: @@ -621,8 +630,11 @@ Only 'set' operations trigger updates because: - 'defvaralias': Aliasing, the actual value change will trigger a separate 'set' When `tp--batch-update-active' is non-nil, buffer updates are deferred until -the batch completes. Layer definitions are still updated immediately." - (when (and (not (equal (symbol-value symbol) newval)) +the batch completes. Layer definitions are still updated immediately. + +Uses `tp--equal-including-string-properties' for comparison to properly detect +changes in text properties when the text content is the same." + (when (and (not (tp--equal-including-string-properties (symbol-value symbol) newval)) (eq operation 'set)) (tp-debug-log "Variable %s changed: %S -> %S (where: %s)" symbol (symbol-value symbol) newval @@ -998,9 +1010,11 @@ Text properties embedded in NEW-TEXT are merged with PROPS." (let* ((m-start (prop-match-beginning match)) (m-end (prop-match-end match)) (old-text (buffer-substring-no-properties m-start m-end))) - ;; Only replace if text content is different - (unless (equal old-text (substring-no-properties new-text)) - ;; Delete old text and insert new (without properties) + (if (equal old-text (substring-no-properties new-text)) + ;; Text content is the same, but properties may differ + ;; Use tp-add to update properties (merges embedded props from new-text) + (tp-add m-start m-end merged-props) + ;; Text content is different - delete old text and insert new (delete-region m-start m-end) (goto-char m-start) (insert (substring-no-properties new-text))