Fix tp-match and tp-regexp APIs to support multiple patterns as list

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-12-15 12:59:28 +00:00
parent 3123f01b1b
commit a3b531177e
4 changed files with 216 additions and 81 deletions

View File

@ -529,17 +529,20 @@ Clear all text properties from a region.
#### `tp-match-set` - Match String #### `tp-match-set` - Match String
```elisp ```elisp
;; Buffer ;; Single pattern - Buffer
(tp-match-set PATTERN '(PROPERTY VALUE ...)) (tp-match-set PATTERN '(PROPERTY VALUE ...))
;; String or Buffer object ;; Single pattern - String or Buffer object
(tp-match-set PATTERN OBJECT '(PROPERTY VALUE ...)) (tp-match-set PATTERN OBJECT '(PROPERTY VALUE ...))
;; Pattern as (PATTERN STRING) format ;; Multiple patterns - apply to all matches of all patterns
(tp-match-set '(PATTERN STRING) '(PROPERTY VALUE ...)) (tp-match-set '(PATTERN1 PATTERN2 ...) '(PROPERTY VALUE ...))
(tp-match-set '(PATTERN1 PATTERN2 ...) '(PROPERTY VALUE ...) OBJECT)
``` ```
Set properties on all occurrences of a string pattern. Set properties on all occurrences of a string pattern.
PATTERN can be a string (single pattern) or a list of strings (multiple patterns).
When multiple patterns are provided, each is matched and has properties applied.
**Examples:** **Examples:**
@ -552,9 +555,13 @@ Set properties on all occurrences of a string pattern.
(tp-match-set "o" "Hello World" '(face bold)) (tp-match-set "o" "Hello World" '(face bold))
;; => #("Hello World" 4 5 (face bold) 7 8 (face bold)) ;; => #("Hello World" 4 5 (face bold) 7 8 (face bold))
;; Using (PATTERN STRING) format ;; Multiple patterns - match both "world" and "Hello"
(tp-match-set '("world" "Hello world") '(face bold)) (tp-match-set '("world" "Hello") '(face bold))
;; => #("Hello world" 6 11 (face bold)) ;; Matches all occurrences of "world" AND all occurrences of "Hello"
;; Multiple patterns on string
(tp-match-set '("Hello" "world") '(face bold) "Hello world")
;; => #("Hello world" 0 5 (face bold) 6 11 (face bold))
``` ```
--- ---
@ -562,6 +569,7 @@ Set properties on all occurrences of a string pattern.
#### `tp-match-reset` - Match and Reset #### `tp-match-reset` - Match and Reset
Reset (completely replace) all properties on matches. Reset (completely replace) all properties on matches.
PATTERN can be a string or list of strings (multiple patterns).
```elisp ```elisp
(tp-match-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-match-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT)
@ -572,6 +580,10 @@ Reset (completely replace) all properties on matches.
```elisp ```elisp
(tp-match-reset "TODO" '(face warning)) (tp-match-reset "TODO" '(face warning))
;; Replaces ALL properties on matched text ;; Replaces ALL properties on matched text
;; Multiple patterns
(tp-match-reset '("TODO" "FIXME") '(face warning))
;; Replaces properties on all occurrences of "TODO" and "FIXME"
``` ```
--- ---
@ -579,6 +591,7 @@ Reset (completely replace) all properties on matches.
#### `tp-match-add` - Match and Add #### `tp-match-add` - Match and Add
Add/merge properties on matches with deep merge support. Add/merge properties on matches with deep merge support.
PATTERN can be a string or list of strings (multiple patterns).
```elisp ```elisp
(tp-match-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-match-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT)
@ -589,6 +602,10 @@ Add/merge properties on matches with deep merge support.
```elisp ```elisp
(tp-match-add "TODO" '(face (:underline t))) (tp-match-add "TODO" '(face (:underline t)))
;; Merges with existing properties ;; Merges with existing properties
;; Multiple patterns
(tp-match-add '("TODO" "FIXME") '(face (:underline t)))
;; Merges properties on all occurrences of "TODO" and "FIXME"
``` ```
--- ---
@ -596,14 +613,20 @@ Add/merge properties on matches with deep merge support.
#### `tp-regexp-set` - Match Regexp #### `tp-regexp-set` - Match Regexp
```elisp ```elisp
;; Buffer ;; Single regexp - Buffer
(tp-regexp-set PATTERN '(PROPERTY VALUE ...)) (tp-regexp-set PATTERN '(PROPERTY VALUE ...))
;; String or Buffer object ;; Single regexp - String or Buffer object
(tp-regexp-set PATTERN OBJECT '(PROPERTY VALUE ...)) (tp-regexp-set PATTERN OBJECT '(PROPERTY VALUE ...))
;; Multiple regexps - apply to all matches of all regexps
(tp-regexp-set '(REGEXP1 REGEXP2 ...) '(PROPERTY VALUE ...))
(tp-regexp-set '(REGEXP1 REGEXP2 ...) '(PROPERTY VALUE ...) OBJECT)
``` ```
Set properties on all matches of a regular expression. Set properties on all matches of a regular expression.
PATTERN can be a string (single regexp) or a list of strings (multiple regexps).
When multiple patterns are provided, each is matched and has properties applied.
**Examples:** **Examples:**
@ -614,6 +637,10 @@ Set properties on all matches of a regular expression.
;; On string ;; On string
(tp-regexp-set "[A-Z]+" "Hello WORLD" '(face bold)) (tp-regexp-set "[A-Z]+" "Hello WORLD" '(face bold))
;; => #("Hello WORLD" 6 11 (face bold)) ;; => #("Hello WORLD" 6 11 (face bold))
;; Multiple regexps - match both numbers and uppercase letters
(tp-regexp-set '("[0-9]+" "[A-Z]+") '(face bold) "abc 123 XYZ")
;; Matches "123" and "XYZ"
``` ```
--- ---
@ -621,6 +648,7 @@ Set properties on all matches of a regular expression.
#### `tp-regexp-reset` - Regexp and Reset #### `tp-regexp-reset` - Regexp and Reset
Reset (completely replace) all properties on regexp matches. Reset (completely replace) all properties on regexp matches.
PATTERN can be a string or list of strings (multiple regexps).
```elisp ```elisp
(tp-regexp-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-regexp-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT)
@ -631,6 +659,7 @@ Reset (completely replace) all properties on regexp matches.
#### `tp-regexp-add` - Regexp and Add #### `tp-regexp-add` - Regexp and Add
Add/merge properties on regexp matches with deep merge support. Add/merge properties on regexp matches with deep merge support.
PATTERN can be a string or list of strings (multiple regexps).
```elisp ```elisp
(tp-regexp-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-regexp-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT)

View File

@ -528,17 +528,20 @@ tp.el 所有函数按类别组织的完整概览:
#### `tp-match-set` - 匹配字符串 #### `tp-match-set` - 匹配字符串
```elisp ```elisp
;; 缓冲区 ;; 单个模式 - 缓冲区
(tp-match-set PATTERN '(PROPERTY VALUE ...)) (tp-match-set PATTERN '(PROPERTY VALUE ...))
;; 字符串或缓冲区对象 ;; 单个模式 - 字符串或缓冲区对象
(tp-match-set PATTERN OBJECT '(PROPERTY VALUE ...)) (tp-match-set PATTERN OBJECT '(PROPERTY VALUE ...))
;; 使用 (PATTERN STRING) 格式 ;; 多个模式 - 对所有模式的所有匹配应用属性
(tp-match-set '(PATTERN STRING) '(PROPERTY VALUE ...)) (tp-match-set '(PATTERN1 PATTERN2 ...) '(PROPERTY VALUE ...))
(tp-match-set '(PATTERN1 PATTERN2 ...) '(PROPERTY VALUE ...) OBJECT)
``` ```
在所有字符串模式匹配处设置属性。 在所有字符串模式匹配处设置属性。
PATTERN 可以是字符串(单个模式)或字符串列表(多个模式)。
当提供多个模式时,每个模式都会被匹配并应用属性。
**示例:** **示例:**
@ -551,9 +554,13 @@ tp.el 所有函数按类别组织的完整概览:
(tp-match-set "o" "Hello World" '(face bold)) (tp-match-set "o" "Hello World" '(face bold))
;; => #("Hello World" 4 5 (face bold) 7 8 (face bold)) ;; => #("Hello World" 4 5 (face bold) 7 8 (face bold))
;; 使用 (PATTERN STRING) 格式 ;; 多个模式 - 同时匹配 "world" 和 "Hello"
(tp-match-set '("world" "Hello world") '(face bold)) (tp-match-set '("world" "Hello") '(face bold))
;; => #("Hello world" 6 11 (face bold)) ;; 匹配所有 "world" 出现的位置和所有 "Hello" 出现的位置
;; 在字符串上使用多个模式
(tp-match-set '("Hello" "world") '(face bold) "Hello world")
;; => #("Hello world" 0 5 (face bold) 6 11 (face bold))
``` ```
--- ---
@ -561,6 +568,7 @@ tp.el 所有函数按类别组织的完整概览:
#### `tp-match-reset` - 匹配并重置 #### `tp-match-reset` - 匹配并重置
重置(完全替换)匹配处的所有属性。 重置(完全替换)匹配处的所有属性。
PATTERN 可以是字符串或字符串列表(多个模式)。
```elisp ```elisp
(tp-match-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-match-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT)
@ -571,6 +579,10 @@ tp.el 所有函数按类别组织的完整概览:
```elisp ```elisp
(tp-match-reset "TODO" '(face warning)) (tp-match-reset "TODO" '(face warning))
;; 替换匹配文本上的所有属性 ;; 替换匹配文本上的所有属性
;; 多个模式
(tp-match-reset '("TODO" "FIXME") '(face warning))
;; 替换所有 "TODO" 和 "FIXME" 出现位置的属性
``` ```
--- ---
@ -578,6 +590,7 @@ tp.el 所有函数按类别组织的完整概览:
#### `tp-match-add` - 匹配并添加 #### `tp-match-add` - 匹配并添加
在匹配处添加/合并属性,支持深度合并。 在匹配处添加/合并属性,支持深度合并。
PATTERN 可以是字符串或字符串列表(多个模式)。
```elisp ```elisp
(tp-match-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-match-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT)
@ -588,6 +601,10 @@ tp.el 所有函数按类别组织的完整概览:
```elisp ```elisp
(tp-match-add "TODO" '(face (:underline t))) (tp-match-add "TODO" '(face (:underline t)))
;; 与现有属性合并 ;; 与现有属性合并
;; 多个模式
(tp-match-add '("TODO" "FIXME") '(face (:underline t)))
;; 合并属性到所有 "TODO" 和 "FIXME" 出现的位置
``` ```
--- ---
@ -595,14 +612,20 @@ tp.el 所有函数按类别组织的完整概览:
#### `tp-regexp-set` - 匹配正则表达式 #### `tp-regexp-set` - 匹配正则表达式
```elisp ```elisp
;; 缓冲区 ;; 单个正则 - 缓冲区
(tp-regexp-set PATTERN '(PROPERTY VALUE ...)) (tp-regexp-set PATTERN '(PROPERTY VALUE ...))
;; 字符串或缓冲区对象 ;; 单个正则 - 字符串或缓冲区对象
(tp-regexp-set PATTERN OBJECT '(PROPERTY VALUE ...)) (tp-regexp-set PATTERN OBJECT '(PROPERTY VALUE ...))
;; 多个正则 - 对所有正则的所有匹配应用属性
(tp-regexp-set '(REGEXP1 REGEXP2 ...) '(PROPERTY VALUE ...))
(tp-regexp-set '(REGEXP1 REGEXP2 ...) '(PROPERTY VALUE ...) OBJECT)
``` ```
在所有正则表达式匹配处设置属性。 在所有正则表达式匹配处设置属性。
PATTERN 可以是字符串(单个正则)或字符串列表(多个正则)。
当提供多个模式时,每个模式都会被匹配并应用属性。
**示例:** **示例:**
@ -613,6 +636,10 @@ tp.el 所有函数按类别组织的完整概览:
;; 在字符串上 ;; 在字符串上
(tp-regexp-set "[A-Z]+" "Hello WORLD" '(face bold)) (tp-regexp-set "[A-Z]+" "Hello WORLD" '(face bold))
;; => #("Hello WORLD" 6 11 (face bold)) ;; => #("Hello WORLD" 6 11 (face bold))
;; 多个正则 - 同时匹配数字和大写字母
(tp-regexp-set '("[0-9]+" "[A-Z]+") '(face bold) "abc 123 XYZ")
;; 匹配 "123" 和 "XYZ"
``` ```
--- ---
@ -620,6 +647,7 @@ tp.el 所有函数按类别组织的完整概览:
#### `tp-regexp-reset` - 正则匹配并重置 #### `tp-regexp-reset` - 正则匹配并重置
重置(完全替换)正则匹配处的所有属性。 重置(完全替换)正则匹配处的所有属性。
PATTERN 可以是字符串或字符串列表(多个正则)。
```elisp ```elisp
(tp-regexp-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-regexp-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT)
@ -630,6 +658,7 @@ tp.el 所有函数按类别组织的完整概览:
#### `tp-regexp-add` - 正则匹配并添加 #### `tp-regexp-add` - 正则匹配并添加
在正则匹配处添加/合并属性,支持深度合并。 在正则匹配处添加/合并属性,支持深度合并。
PATTERN 可以是字符串或字符串列表(多个正则)。
```elisp ```elisp
(tp-regexp-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT) (tp-regexp-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT)

View File

@ -1124,13 +1124,32 @@ Returns list of (START END VALUE) intervals."
;;; Match Pattern Format Tests ;;; Match Pattern Format Tests
;;; ============================================================ ;;; ============================================================
(ert-deftest tp-test-match-set-pattern-string-format () (ert-deftest tp-test-match-set-multiple-patterns ()
"Test tp-match-set with (pattern string) format." "Test tp-match-set with multiple patterns (list of patterns)."
(let* ((str (copy-sequence "Hello world")) (tp-test-with-temp-buffer
(result (tp-match-set '("world" "Hello world") '(face bold)))) (insert "Hello world, Hello again")
;; Match both "world" and "Hello" - both should get properties applied
(let ((regions (tp-match-set '("world" "Hello") '(face bold))))
;; Should find 3 matches: "Hello", "world", "Hello"
(should (= (length regions) 3))
;; Check that "Hello" at position 1 has face bold
(should (eq (tp-at 1 'face) 'bold))
;; Check that "world" at position 7 has face bold
(should (eq (tp-at 7 'face) 'bold))
;; Check that "Hello" at position 14 has face bold
(should (eq (tp-at 14 'face) 'bold)))))
(ert-deftest tp-test-match-set-multiple-patterns-on-string ()
"Test tp-match-set with multiple patterns on string."
(let* ((str (copy-sequence "Hello world, Hello again"))
(result (tp-match-set '("world" "Hello") '(face bold) str)))
(should (stringp result)) (should (stringp result))
;; Check that "Hello" at position 0 has face bold
(should (eq (get-text-property 0 'face result) 'bold))
;; Check that "world" at position 6 has face bold
(should (eq (get-text-property 6 'face result) 'bold)) (should (eq (get-text-property 6 'face result) 'bold))
(should (null (get-text-property 0 'face result))))) ;; Check that "Hello" at position 13 has face bold
(should (eq (get-text-property 13 'face result) 'bold))))
(ert-deftest tp-test-match-reset () (ert-deftest tp-test-match-reset ()
"Test tp-match-reset completely replaces properties." "Test tp-match-reset completely replaces properties."
@ -1205,6 +1224,37 @@ Returns list of (START END VALUE) intervals."
(should (eq (get-text-property 12 'face result) 'italic)) (should (eq (get-text-property 12 'face result) 'italic))
(should (null (get-text-property 0 'face result)))))) (should (null (get-text-property 0 'face result))))))
(ert-deftest tp-test-regexp-set-multiple-patterns ()
"Test tp-regexp-set with multiple patterns (list of regexps)."
(tp-test-with-temp-buffer
(insert "abc 123 def 456 ghi")
;; Match both numbers and "abc" - all should get properties applied
(let ((regions (tp-regexp-set '("[0-9]+" "abc") '(face bold))))
;; Should find 3 matches: "abc", "123", "456"
(should (= (length regions) 3))
;; Check that "abc" at position 1 has face bold
(should (eq (tp-at 1 'face) 'bold))
;; Check that "123" at position 5 has face bold
(should (eq (tp-at 5 'face) 'bold))
;; Check that "456" at position 13 has face bold
(should (eq (tp-at 13 'face) 'bold))
;; Check that "def" does NOT have face bold
(should (null (tp-at 9 'face))))))
(ert-deftest tp-test-regexp-set-multiple-patterns-on-string ()
"Test tp-regexp-set with multiple patterns on string."
(let* ((str (copy-sequence "abc 123 def 456"))
(result (tp-regexp-set '("[0-9]+" "abc") '(face italic) str)))
(should (stringp result))
;; Check that "abc" at position 0 has face italic
(should (eq (get-text-property 0 'face result) 'italic))
;; Check that "123" at position 4 has face italic
(should (eq (get-text-property 4 'face result) 'italic))
;; Check that "456" at position 12 has face italic
(should (eq (get-text-property 12 'face result) 'italic))
;; Check that "def" does NOT have face italic
(should (null (get-text-property 8 'face result)))))
(ert-deftest tp-test-get-range-multiple-intervals () (ert-deftest tp-test-get-range-multiple-intervals ()
"Test tp-get returns all property intervals in a range." "Test tp-get returns all property intervals in a range."
(let ((str (copy-sequence "Hello World Hello"))) (let ((str (copy-sequence "Hello World Hello")))

115
tp.el
View File

@ -712,45 +712,59 @@ OBJECT defaults to current buffer."
;;; Match and regexp functions ;;; Match and regexp functions
(defun tp--match-apply (pattern properties apply-fn &optional object) (defun tp--match-apply-single (pattern properties apply-fn object)
"Internal function to apply APPLY-FN to matches of PATTERN. "Apply APPLY-FN to matches of single PATTERN in OBJECT.
PATTERN can be a string or (PATTERN STRING) for substring matching.
APPLY-FN is called with (START END PROPS OBJECT) for each match. APPLY-FN is called with (START END PROPS OBJECT) for each match.
Returns modified object or list of regions." Returns modified object or list of regions."
(let ((search-pattern pattern)
(search-object object))
;; Handle (PATTERN STRING) format
(when (and (listp pattern) (stringp (car pattern)) (stringp (cadr pattern)))
(setq search-pattern (car pattern)
search-object (cadr pattern)))
(cond (cond
;; String object ;; String object
((stringp search-object) ((stringp object)
(let ((pos 0)) (let ((pos 0))
(while (string-match (regexp-quote search-pattern) search-object pos) (while (string-match (regexp-quote pattern) object pos)
(let ((beg (match-beginning 0)) (let ((beg (match-beginning 0))
(end (match-end 0))) (end (match-end 0)))
(when properties (when properties
(funcall apply-fn beg end properties search-object)) (funcall apply-fn beg end properties object))
(setq pos (if (= beg end) (1+ beg) end)))) (setq pos (if (= beg end) (1+ beg) end))))
search-object)) object))
;; Buffer or nil (current buffer) ;; Buffer or nil (current buffer)
(t (t
(let ((buf (or search-object (current-buffer)))) (let ((buf (or object (current-buffer))))
(with-current-buffer buf (with-current-buffer buf
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(let (regions) (let (regions)
(while (search-forward search-pattern nil t) (while (search-forward pattern nil t)
(let ((beg (match-beginning 0)) (let ((beg (match-beginning 0))
(end (match-end 0))) (end (match-end 0)))
(when properties (when properties
(funcall apply-fn beg end properties buf)) (funcall apply-fn beg end properties buf))
(push (cons beg end) regions))) (push (cons beg end) regions)))
(nreverse regions))))))))) (nreverse regions))))))))
(defun tp--regexp-apply (pattern properties apply-fn &optional object) (defun tp--match-apply (pattern properties apply-fn &optional object)
"Internal function to apply APPLY-FN to regexp matches of PATTERN. "Internal function to apply APPLY-FN to matches of PATTERN.
PATTERN can be a string or a list of strings (multiple patterns).
When PATTERN is a list, each element is a pattern to match.
APPLY-FN is called with (START END PROPS OBJECT) for each match.
Returns modified object or list of regions."
(let ((patterns (if (listp pattern) pattern (list pattern))))
(cond
;; String object
((stringp object)
(dolist (p patterns)
(tp--match-apply-single p properties apply-fn object))
object)
;; Buffer or nil (current buffer)
(t
(let ((all-regions nil))
(dolist (p patterns)
(let ((regions (tp--match-apply-single p properties apply-fn object)))
(setq all-regions (append all-regions regions))))
all-regions)))))
(defun tp--regexp-apply-single (pattern properties apply-fn object)
"Apply APPLY-FN to regexp matches of single PATTERN in OBJECT.
APPLY-FN is called with (START END PROPS OBJECT) for each match. APPLY-FN is called with (START END PROPS OBJECT) for each match.
Returns modified object or list of regions." Returns modified object or list of regions."
(cond (cond
@ -779,6 +793,27 @@ Returns modified object or list of regions."
(push (cons beg end) regions))) (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.
PATTERN can be a string (single regexp) or a list of strings (multiple regexps).
When PATTERN is a list, each element is a regexp to match.
APPLY-FN is called with (START END PROPS OBJECT) for each match.
Returns modified object or list of regions."
(let ((patterns (if (listp pattern) pattern (list pattern))))
(cond
;; String object
((stringp object)
(dolist (p patterns)
(tp--regexp-apply-single p properties apply-fn object))
object)
;; Buffer or nil (current buffer)
(t
(let ((all-regions nil))
(dolist (p patterns)
(let ((regions (tp--regexp-apply-single p properties apply-fn object)))
(setq all-regions (append all-regions regions))))
all-regions)))))
(defun tp--parse-match-args (args) (defun tp--parse-match-args (args)
"Parse match/regexp function ARGS. "Parse match/regexp function ARGS.
Returns (OBJECT . PROPERTIES). Returns (OBJECT . PROPERTIES).
@ -824,16 +859,6 @@ Handles two calling conventions:
(setq properties (car properties))) (setq properties (car properties)))
(cons object properties))) (cons object properties)))
(defun tp--parse-pattern-format (pattern object)
"Parse PATTERN for (PATTERN STRING) format.
Returns (PARSED-PATTERN . OBJECT)."
(if (and (listp pattern) (stringp (car pattern)))
(cons (car pattern)
(if (stringp (cadr pattern))
(cadr pattern)
object))
(cons pattern object)))
(defun tp--deep-merge-apply (start end props obj) (defun tp--deep-merge-apply (start end props obj)
"Apply PROPS to OBJ from START to END with deep merge. "Apply PROPS to OBJ from START to END with deep merge.
Merges nested plists instead of replacing them." Merges nested plists instead of replacing them."
@ -866,32 +891,29 @@ This function supports multiple calling conventions:
(tp-match-set PATTERN PROPERTY VALUE ...) (tp-match-set PATTERN PROPERTY VALUE ...)
(tp-match-set PATTERN \\='(PROPERTY VALUE ...)) (tp-match-set PATTERN \\='(PROPERTY VALUE ...))
3. With pattern as (PATTERN STRING) to match within STRING: 3. Multiple patterns (list of patterns to match):
(tp-match-set \\='(\"world\" \"Hello world\") \\='(face bold)) (tp-match-set \\='(\"pattern1\" \"pattern2\" ...) \\='(PROPERTY VALUE ...))
(tp-match-set \\='(\"pattern1\" \"pattern2\" ...) \\='(PROPERTY VALUE ...) OBJECT)
PATTERN is the string to search for. PATTERN is a string (single pattern) or list of strings (multiple patterns).
Each pattern will be matched and have properties applied.
PROPERTIES is a plist of property-value pairs. PROPERTIES is a plist of property-value pairs.
Returns: Returns:
- For strings: the modified string - For strings: the modified string
- For buffers: list of (START . END) pairs for all matches." - For buffers: list of (START . END) pairs for all matches."
(let* ((parsed (tp--parse-match-args args)) (let* ((parsed (tp--parse-match-args args))
(object (car parsed)) (object (car parsed))
(properties (cdr parsed)) (properties (cdr parsed)))
(parsed-pattern (tp--parse-pattern-format pattern object)))
(setq pattern (car parsed-pattern)
object (cdr parsed-pattern))
(tp--match-apply pattern properties #'tp-set object))) (tp--match-apply pattern properties #'tp-set object)))
(defun tp-match-reset (pattern &rest args) (defun tp-match-reset (pattern &rest args)
"Reset (completely replace) properties on all occurrences of PATTERN. "Reset (completely replace) properties on all occurrences of PATTERN.
Same calling conventions as `tp-match-set'. Same calling conventions as `tp-match-set'.
PATTERN can be a string or list of strings (multiple patterns).
Unlike `tp-match-set', this completely replaces all existing properties." Unlike `tp-match-set', this completely replaces all existing properties."
(let* ((parsed (tp--parse-match-args args)) (let* ((parsed (tp--parse-match-args args))
(object (car parsed)) (object (car parsed))
(properties (cdr parsed)) (properties (cdr parsed)))
(parsed-pattern (tp--parse-pattern-format pattern object)))
(setq pattern (car parsed-pattern)
object (cdr parsed-pattern))
(tp--match-apply pattern properties (tp--match-apply pattern properties
(lambda (start end props obj) (lambda (start end props obj)
(set-text-properties start end props obj)) (set-text-properties start end props obj))
@ -900,13 +922,11 @@ Unlike `tp-match-set', this completely replaces all existing properties."
(defun tp-match-add (pattern &rest args) (defun tp-match-add (pattern &rest args)
"Add/update properties on all occurrences of PATTERN. "Add/update properties on all occurrences of PATTERN.
Same calling conventions as `tp-match-set'. Same calling conventions as `tp-match-set'.
PATTERN can be a string or list of strings (multiple patterns).
Unlike `tp-match-set', this deeply merges nested properties." Unlike `tp-match-set', this deeply merges nested properties."
(let* ((parsed (tp--parse-match-args args)) (let* ((parsed (tp--parse-match-args args))
(object (car parsed)) (object (car parsed))
(properties (cdr parsed)) (properties (cdr parsed)))
(parsed-pattern (tp--parse-pattern-format pattern object)))
(setq pattern (car parsed-pattern)
object (cdr parsed-pattern))
(tp--match-apply pattern properties #'tp--deep-merge-apply object))) (tp--match-apply pattern properties #'tp--deep-merge-apply object)))
(defun tp-regexp-set (pattern &rest args) (defun tp-regexp-set (pattern &rest args)
@ -923,7 +943,12 @@ This function supports multiple calling conventions:
(tp-regexp-set PATTERN PROPERTY VALUE ...) (tp-regexp-set PATTERN PROPERTY VALUE ...)
(tp-regexp-set PATTERN \\='(PROPERTY VALUE ...)) (tp-regexp-set PATTERN \\='(PROPERTY VALUE ...))
PATTERN is the regexp to search for. 3. Multiple patterns (list of regexps to match):
(tp-regexp-set \\='(\"regexp1\" \"regexp2\" ...) \\='(PROPERTY VALUE ...))
(tp-regexp-set \\='(\"regexp1\" \"regexp2\" ...) \\='(PROPERTY VALUE ...) OBJECT)
PATTERN is a string (single regexp) or list of strings (multiple regexps).
Each pattern will be matched and have properties applied.
PROPERTIES is a plist of property-value pairs. PROPERTIES is a plist of property-value pairs.
Returns: Returns:
- For strings: the modified string - For strings: the modified string
@ -936,6 +961,7 @@ Returns:
(defun tp-regexp-reset (pattern &rest args) (defun tp-regexp-reset (pattern &rest args)
"Reset (completely replace) properties on all regexp matches of PATTERN. "Reset (completely replace) properties on all regexp matches of PATTERN.
Same calling conventions as `tp-regexp-set'. Same calling conventions as `tp-regexp-set'.
PATTERN can be a string or list of strings (multiple regexps).
Unlike `tp-regexp-set', this completely replaces all existing properties." Unlike `tp-regexp-set', this completely replaces all existing properties."
(let* ((parsed (tp--parse-match-args args)) (let* ((parsed (tp--parse-match-args args))
(object (car parsed)) (object (car parsed))
@ -948,6 +974,7 @@ Unlike `tp-regexp-set', this completely replaces all existing properties."
(defun tp-regexp-add (pattern &rest args) (defun tp-regexp-add (pattern &rest args)
"Add/update properties on all regexp matches of PATTERN. "Add/update properties on all regexp matches of PATTERN.
Same calling conventions as `tp-regexp-set'. Same calling conventions as `tp-regexp-set'.
PATTERN can be a string or list of strings (multiple regexps).
Unlike `tp-regexp-set', this deeply merges nested properties." Unlike `tp-regexp-set', this deeply merges nested properties."
(let* ((parsed (tp--parse-match-args args)) (let* ((parsed (tp--parse-match-args args))
(object (car parsed)) (object (car parsed))