Refactor tp-text handling to improve code reuse and clarity
- Updated tp--handle-tp-text-property to accept preserve-props parameter - Replaced inefficient nth-based loop with cl-loop in tp-set - Fixed loop structure in tp--replace-reactive-text-in-buffer - Made tp-reset use the helper function instead of duplicated code Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
parent
d75070824a
commit
af5ba6b214
109
tp.el
109
tp.el
@ -497,27 +497,29 @@ WHERE specifies which buffers to update:
|
|||||||
NEW-TEXT is the new text to replace with.
|
NEW-TEXT is the new text to replace with.
|
||||||
PROPS are the properties to apply to the new text."
|
PROPS are the properties to apply to the new text."
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(let ((match t))
|
(let ((match (text-property-search-forward 'tp-name layer-name t)))
|
||||||
(while match
|
(while match
|
||||||
(setq match (text-property-search-forward 'tp-name layer-name t))
|
(let* ((m-start (prop-match-beginning match))
|
||||||
(when match
|
(m-end (prop-match-end match))
|
||||||
(let* ((m-start (prop-match-beginning match))
|
(old-text (buffer-substring-no-properties m-start m-end)))
|
||||||
(m-end (prop-match-end match))
|
;; Only replace if text is different
|
||||||
(old-text (buffer-substring-no-properties m-start m-end)))
|
(unless (equal old-text new-text)
|
||||||
;; Only replace if text is different
|
;; Delete old text and insert new
|
||||||
(unless (equal old-text new-text)
|
(delete-region m-start m-end)
|
||||||
;; Delete old text and insert new
|
(goto-char m-start)
|
||||||
(delete-region m-start m-end)
|
(insert new-text)
|
||||||
(goto-char m-start)
|
;; Apply the layer properties (including tp-text and tp-name) to new text
|
||||||
(insert new-text)
|
(let ((new-end (+ m-start (length new-text))))
|
||||||
;; Apply the layer properties (including tp-text and tp-name) to new text
|
(set-text-properties m-start new-end props))))
|
||||||
(let ((new-end (+ m-start (length new-text))))
|
;; Search for next match
|
||||||
(set-text-properties m-start new-end props))))))))
|
(setq match (text-property-search-forward 'tp-name layer-name t)))))
|
||||||
|
|
||||||
(defun tp--handle-tp-text-property (start end props object)
|
(defun tp--handle-tp-text-property (start end props object &optional preserve-props)
|
||||||
"Handle tp-text property in PROPS for region from START to END in OBJECT.
|
"Handle tp-text property in PROPS for region from START to END in OBJECT.
|
||||||
If tp-text is nil, initialize it to the current text in the region.
|
If tp-text is nil, initialize it to the current text in the region.
|
||||||
If tp-text is a string different from current text, replace the text.
|
If tp-text is a string different from current text, replace the text.
|
||||||
|
When PRESERVE-PROPS is non-nil, existing text properties are preserved
|
||||||
|
on the replaced text (used by tp-set and tp-add).
|
||||||
Returns (PROPS NEW-END) where PROPS is the updated props and NEW-END is
|
Returns (PROPS NEW-END) where PROPS is the updated props and NEW-END is
|
||||||
the new end position after any text replacement."
|
the new end position after any text replacement."
|
||||||
(if (not (plist-member props 'tp-text))
|
(if (not (plist-member props 'tp-text))
|
||||||
@ -548,10 +550,11 @@ the new end position after any text replacement."
|
|||||||
;; Same text, no replacement needed
|
;; Same text, no replacement needed
|
||||||
(list props end)
|
(list props end)
|
||||||
;; Need to replace text
|
;; Need to replace text
|
||||||
(let ((existing-props (if object
|
(let ((existing-props (when preserve-props
|
||||||
(with-current-buffer object
|
(if object
|
||||||
(text-properties-at start))
|
(with-current-buffer object
|
||||||
(text-properties-at start))))
|
(text-properties-at start))
|
||||||
|
(text-properties-at start)))))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(if object
|
(if object
|
||||||
(with-current-buffer object
|
(with-current-buffer object
|
||||||
@ -564,16 +567,10 @@ the new end position after any text replacement."
|
|||||||
(goto-char start)
|
(goto-char start)
|
||||||
(insert tp-text-val))))
|
(insert tp-text-val))))
|
||||||
(let ((new-end (+ start (length tp-text-val))))
|
(let ((new-end (+ start (length tp-text-val))))
|
||||||
;; Re-apply existing properties to new text region
|
;; Re-apply existing properties to new text region if preserving
|
||||||
(when existing-props
|
(when existing-props
|
||||||
(let ((i 0)
|
(cl-loop for (key val) on existing-props by #'cddr
|
||||||
(len (length existing-props)))
|
do (put-text-property start new-end key val object)))
|
||||||
(while (< i len)
|
|
||||||
(put-text-property start new-end
|
|
||||||
(nth i existing-props)
|
|
||||||
(nth (1+ i) existing-props)
|
|
||||||
object)
|
|
||||||
(setq i (+ i 2)))))
|
|
||||||
(list props new-end)))))))
|
(list props new-end)))))))
|
||||||
;; Other types - return unchanged
|
;; Other types - return unchanged
|
||||||
(t (list props end))))))
|
(t (list props end))))))
|
||||||
@ -666,18 +663,12 @@ Return the modified object (string) or region (START . END) for buffer."
|
|||||||
(tp--parse-args start-or-string end-or-prop props-or-val rest)))
|
(tp--parse-args start-or-string end-or-prop props-or-val rest)))
|
||||||
;; Handle tp-text property specially using helper function
|
;; Handle tp-text property specially using helper function
|
||||||
(pcase-let ((`(,new-props ,new-finish)
|
(pcase-let ((`(,new-props ,new-finish)
|
||||||
(tp--handle-tp-text-property start finish props object)))
|
(tp--handle-tp-text-property start finish props object t)))
|
||||||
(setq props new-props)
|
(setq props new-props)
|
||||||
(setq finish new-finish))
|
(setq finish new-finish))
|
||||||
;; Apply properties individually (preserves other properties)
|
;; Apply properties individually (preserves other properties)
|
||||||
(let ((len (length props))
|
(cl-loop for (key val) on props by #'cddr
|
||||||
(i 0))
|
do (put-text-property start finish key val object))
|
||||||
(while (< i len)
|
|
||||||
(put-text-property start finish
|
|
||||||
(nth i props)
|
|
||||||
(nth (1+ i) props)
|
|
||||||
object)
|
|
||||||
(setq i (+ i 2))))
|
|
||||||
(if (stringp object)
|
(if (stringp object)
|
||||||
object
|
object
|
||||||
(cons start finish))))
|
(cons start finish))))
|
||||||
@ -717,40 +708,11 @@ Return the modified object (string) or region (START . END) for buffer."
|
|||||||
(pcase-let ((`(,object ,start ,finish ,props)
|
(pcase-let ((`(,object ,start ,finish ,props)
|
||||||
(tp--parse-args start-or-string end-or-prop props-or-val rest)))
|
(tp--parse-args start-or-string end-or-prop props-or-val rest)))
|
||||||
;; Handle tp-text property specially using helper function
|
;; Handle tp-text property specially using helper function
|
||||||
;; Note: for tp-reset we don't preserve existing props on text replacement
|
;; Pass nil for preserve-props since tp-reset replaces all properties
|
||||||
;; since tp-reset is meant to completely replace all properties
|
(pcase-let ((`(,new-props ,new-finish)
|
||||||
(when (plist-member props 'tp-text)
|
(tp--handle-tp-text-property start finish props object nil)))
|
||||||
(let ((tp-text-val (plist-get props 'tp-text)))
|
(setq props new-props)
|
||||||
(cond
|
(setq finish new-finish))
|
||||||
;; tp-text is nil - initialize it to the current text
|
|
||||||
((null tp-text-val)
|
|
||||||
(let ((current-text (if (stringp object)
|
|
||||||
(substring object start finish)
|
|
||||||
(if object
|
|
||||||
(with-current-buffer object
|
|
||||||
(buffer-substring-no-properties start finish))
|
|
||||||
(buffer-substring-no-properties start finish)))))
|
|
||||||
(setq props (plist-put props 'tp-text current-text))))
|
|
||||||
;; tp-text has a string value - replace the text in the region
|
|
||||||
((stringp tp-text-val)
|
|
||||||
(unless (stringp object)
|
|
||||||
(let ((old-text (if object
|
|
||||||
(with-current-buffer object
|
|
||||||
(buffer-substring-no-properties start finish))
|
|
||||||
(buffer-substring-no-properties start finish))))
|
|
||||||
(unless (equal old-text tp-text-val)
|
|
||||||
(save-excursion
|
|
||||||
(if object
|
|
||||||
(with-current-buffer object
|
|
||||||
(let ((inhibit-read-only t))
|
|
||||||
(delete-region start finish)
|
|
||||||
(goto-char start)
|
|
||||||
(insert tp-text-val)))
|
|
||||||
(let ((inhibit-read-only t))
|
|
||||||
(delete-region start finish)
|
|
||||||
(goto-char start)
|
|
||||||
(insert tp-text-val))))
|
|
||||||
(setq finish (+ start (length tp-text-val))))))))))
|
|
||||||
;; Completely replace all properties
|
;; Completely replace all properties
|
||||||
(set-text-properties start finish props object)
|
(set-text-properties start finish props object)
|
||||||
(if (stringp object)
|
(if (stringp object)
|
||||||
@ -871,8 +833,9 @@ Return the modified object (string) or region (START . END) for buffer."
|
|||||||
(pcase-let ((`(,object ,start ,finish ,props)
|
(pcase-let ((`(,object ,start ,finish ,props)
|
||||||
(tp--parse-args start-or-string end-or-prop props-or-val rest)))
|
(tp--parse-args start-or-string end-or-prop props-or-val rest)))
|
||||||
;; Handle tp-text property specially using helper function
|
;; Handle tp-text property specially using helper function
|
||||||
|
;; Pass t for preserve-props since tp-add preserves existing properties
|
||||||
(pcase-let ((`(,new-props ,new-finish)
|
(pcase-let ((`(,new-props ,new-finish)
|
||||||
(tp--handle-tp-text-property start finish props object)))
|
(tp--handle-tp-text-property start finish props object t)))
|
||||||
(setq props new-props)
|
(setq props new-props)
|
||||||
(setq finish new-finish))
|
(setq finish new-finish))
|
||||||
;; Process each property with deep merging
|
;; Process each property with deep merging
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user