Address code review: improve pattern matching and readability
- Collect all match positions before applying transformations to avoid string-match position invalidation issues - Use list* instead of nested cons for better readability - Improve plist building efficiency by iterating instead of copy-sequence - Add detailed comment explaining :reset mode usage with tp-text Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
parent
98f807993a
commit
a48a523120
51
tp.el
51
tp.el
@ -1280,9 +1280,15 @@ Returns a new propertized string."
|
||||
result))
|
||||
;; nil/:set - set properties, preserving unspecified ones
|
||||
(t
|
||||
(let ((result (copy-sequence existing-props)))
|
||||
;; Build a new plist by iterating through existing props and overriding with new props
|
||||
(let ((result nil))
|
||||
;; First add all props from new props
|
||||
(cl-loop for (key val) on props by #'cddr
|
||||
do (setq result (plist-put result key val)))
|
||||
;; Then add existing props that are not in new props
|
||||
(cl-loop for (key val) on existing-props by #'cddr
|
||||
unless (plist-member props key)
|
||||
do (setq result (plist-put result key val)))
|
||||
result))))
|
||||
;; Create the middle section with properties using propertize
|
||||
(middle-propertized (apply #'propertize middle-text final-props)))
|
||||
@ -1494,9 +1500,14 @@ Returns: For buffers, (START . END) cons. For strings, the result string."
|
||||
;; Entire string form: create a new propertized string (non-destructive)
|
||||
((and (stringp object) entire-string-form)
|
||||
(if (plist-member props 'tp-text)
|
||||
;; For tp-text, properties are already merged
|
||||
;; For tp-text: tp--handle-tp-text-property has already merged embedded
|
||||
;; properties with props (in :merge mode above). The new-object is a
|
||||
;; fresh string with tp-text content, and new-props contains all merged
|
||||
;; properties. We use :reset mode here to simply apply these final
|
||||
;; merged properties to the new string, without re-merging with any
|
||||
;; (non-existent) existing properties on the new string.
|
||||
(tp--apply-props-to-string object start finish props :reset)
|
||||
;; Otherwise use :add mode for deep merging
|
||||
;; Otherwise use :add mode for deep merging with any existing properties
|
||||
(tp--apply-props-to-string object start finish props :add)))
|
||||
;; Region form with string object: modify in-place with deep merging
|
||||
((stringp object)
|
||||
@ -1864,7 +1875,7 @@ Returns: For buffers, nil. For entire string forms, a new string."
|
||||
;; (tp-remove str 'face 'help-echo ...) - multiple properties
|
||||
((symbolp end-or-prop)
|
||||
(let ((props-to-remove (cl-remove-if-not #'symbolp
|
||||
(cons end-or-prop (cons prop-or-sub rest)))))
|
||||
(list* end-or-prop prop-or-sub rest))))
|
||||
(tp--remove-props-from-string str start end props-to-remove)))
|
||||
;; (tp-remove str '(face :underline)) - nested property spec
|
||||
((listp end-or-prop)
|
||||
@ -2028,15 +2039,20 @@ For buffers, modifies in-place and returns list of regions."
|
||||
(cond
|
||||
;; String object
|
||||
((stringp object)
|
||||
(let ((result object)
|
||||
;; First, collect all match positions from the original string
|
||||
(let ((matches nil)
|
||||
(pos 0))
|
||||
(while (string-match (regexp-quote pattern) result pos)
|
||||
(while (string-match (regexp-quote pattern) object pos)
|
||||
(let ((beg (match-beginning 0))
|
||||
(end (match-end 0)))
|
||||
(when properties
|
||||
(setq result (funcall apply-fn beg end properties result)))
|
||||
(push (cons beg end) matches)
|
||||
(setq pos (if (= beg end) (1+ beg) end))))
|
||||
result))
|
||||
;; Apply function to each match in order (reverse to get correct order)
|
||||
(let ((result object))
|
||||
(dolist (match (nreverse matches))
|
||||
(when properties
|
||||
(setq result (funcall apply-fn (car match) (cdr match) properties result))))
|
||||
result)))
|
||||
;; Buffer or nil (current buffer)
|
||||
(t
|
||||
(let ((buf (or object (current-buffer))))
|
||||
@ -2083,15 +2099,20 @@ For buffers, modifies in-place and returns list of regions."
|
||||
(cond
|
||||
;; String object
|
||||
((stringp object)
|
||||
(let ((result object)
|
||||
;; First, collect all match positions from the original string
|
||||
(let ((matches nil)
|
||||
(pos 0))
|
||||
(while (string-match pattern result pos)
|
||||
(while (string-match pattern object pos)
|
||||
(let ((beg (match-beginning 0))
|
||||
(end (match-end 0)))
|
||||
(when properties
|
||||
(setq result (funcall apply-fn beg end properties result)))
|
||||
(push (cons beg end) matches)
|
||||
(setq pos (if (= beg end) (1+ beg) end))))
|
||||
result))
|
||||
;; Apply function to each match in order (reverse to get correct order)
|
||||
(let ((result object))
|
||||
(dolist (match (nreverse matches))
|
||||
(when properties
|
||||
(setq result (funcall apply-fn (car match) (cdr match) properties result))))
|
||||
result)))
|
||||
;; Buffer or nil (current buffer)
|
||||
(t
|
||||
(let ((buf (or object (current-buffer))))
|
||||
@ -2105,7 +2126,7 @@ For buffers, modifies in-place and returns list of regions."
|
||||
(when properties
|
||||
(funcall apply-fn beg end properties buf))
|
||||
(push (cons beg end) regions)))
|
||||
(nreverse regions))))))))
|
||||
(nreverse regions)))))))))
|
||||
|
||||
(defun tp--regexp-apply (pattern properties apply-fn &optional object)
|
||||
"Internal function to apply APPLY-FN to regexp matches of PATTERN.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user