Update tp-forward-do/tp-backward-do docs and tests for "last match only" behavior
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
parent
ed8baf3970
commit
47b6505d51
28
README.md
28
README.md
@ -885,11 +885,10 @@ Search forward/backward N times for text with PROPERTY.
|
|||||||
(tp-backward-do FUNCTION PROPERTY &optional VALUE OBJECT POINT N)
|
(tp-backward-do FUNCTION PROPERTY &optional VALUE OBJECT POINT N)
|
||||||
```
|
```
|
||||||
|
|
||||||
Search forward/backward N times for text with PROPERTY and apply FUNCTION to matched text.
|
Search forward/backward N times for text with PROPERTY and apply FUNCTION **only to the last match**.
|
||||||
|
|
||||||
- **FUNCTION** receives the matched text as its only argument. The return value
|
- **FUNCTION** receives the matched text as its first argument. Optionally, FUNCTION can accept two additional arguments: START and END, representing the start and end positions of the match. The return value of FUNCTION replaces the matched text in the string or buffer.
|
||||||
of FUNCTION replaces the matched text in the string or buffer.
|
- **N** is the number of searches, defaulting to 1. The function searches N times but only applies FUNCTION to the last (Nth) match found.
|
||||||
- **N** is the number of searches, defaulting to 1.
|
|
||||||
- **OBJECT** can be a buffer or string; nil defaults to current buffer.
|
- **OBJECT** can be a buffer or string; nil defaults to current buffer.
|
||||||
- **POINT** is the starting position for search; for buffers nil means current point,
|
- **POINT** is the starting position for search; for buffers nil means current point,
|
||||||
for strings nil means 0 (forward) or end of string (backward).
|
for strings nil means 0 (forward) or end of string (backward).
|
||||||
@ -898,7 +897,7 @@ Search forward/backward N times for text with PROPERTY and apply FUNCTION to mat
|
|||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```elisp
|
```elisp
|
||||||
;; Upcase matched text in buffer (starting from current point)
|
;; Upcase only the last (2nd) match in buffer
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert "hello world test")
|
(insert "hello world test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
@ -906,17 +905,17 @@ Search forward/backward N times for text with PROPERTY and apply FUNCTION to mat
|
|||||||
(goto-char 1)
|
(goto-char 1)
|
||||||
(tp-forward-do #'upcase 'marker nil nil nil 2)
|
(tp-forward-do #'upcase 'marker nil nil nil 2)
|
||||||
(buffer-string))
|
(buffer-string))
|
||||||
;; => "HELLO world TEST"
|
;; => "hello world TEST" ; Only the 2nd match is upcased
|
||||||
|
|
||||||
;; Upcase matched text in string (starting from position 0)
|
;; Upcase only the last (2nd) match in string
|
||||||
(let ((my-string (copy-sequence "hello world hello")))
|
(let ((my-string (copy-sequence "hello world hello")))
|
||||||
(tp-set 0 5 '(marker t) my-string)
|
(tp-set 0 5 '(marker t) my-string)
|
||||||
(tp-set 12 17 '(marker t) my-string)
|
(tp-set 12 17 '(marker t) my-string)
|
||||||
(tp-forward-do #'upcase 'marker nil my-string nil 2)
|
(tp-forward-do #'upcase 'marker nil my-string nil 2)
|
||||||
my-string)
|
my-string)
|
||||||
;; => "HELLO world HELLO"
|
;; => "hello world HELLO" ; Only the 2nd match is upcased
|
||||||
|
|
||||||
;; Start search from specific position
|
;; Start search from specific position (only 1 match found and transformed)
|
||||||
(let ((my-string (copy-sequence "hello world hello")))
|
(let ((my-string (copy-sequence "hello world hello")))
|
||||||
(tp-set 0 5 '(marker t) my-string)
|
(tp-set 0 5 '(marker t) my-string)
|
||||||
(tp-set 12 17 '(marker t) my-string)
|
(tp-set 12 17 '(marker t) my-string)
|
||||||
@ -924,17 +923,18 @@ Search forward/backward N times for text with PROPERTY and apply FUNCTION to mat
|
|||||||
my-string)
|
my-string)
|
||||||
;; => "hello world HELLO" ; Only matches from position 6 onward
|
;; => "hello world HELLO" ; Only matches from position 6 onward
|
||||||
|
|
||||||
;; Custom transformation
|
;; Using function with start and end parameters
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert "hello world test")
|
(insert "hello world test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
|
(tp-set 13 17 '(marker t))
|
||||||
(goto-char 1)
|
(goto-char 1)
|
||||||
(tp-forward-do
|
(tp-forward-do
|
||||||
(lambda (text)
|
(lambda (text start end)
|
||||||
(concat "[" text "]"))
|
(format "[%d-%d]%s" start end text))
|
||||||
'marker nil nil nil 1)
|
'marker nil nil nil 2)
|
||||||
(buffer-string))
|
(buffer-string))
|
||||||
;; => "[hello] world test"
|
;; => "hello world [13-17]test" ; Only the last match is transformed
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
27
README_CN.md
27
README_CN.md
@ -884,10 +884,10 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
|
|||||||
(tp-backward-do FUNCTION PROPERTY &optional VALUE OBJECT POINT N)
|
(tp-backward-do FUNCTION PROPERTY &optional VALUE OBJECT POINT N)
|
||||||
```
|
```
|
||||||
|
|
||||||
向前/向后搜索 N 次具有 PROPERTY 的文本,并对匹配的文本应用 FUNCTION。
|
向前/向后搜索 N 次具有 PROPERTY 的文本,**仅对最后一次匹配应用 FUNCTION**。
|
||||||
|
|
||||||
- **FUNCTION** 接收匹配到的文本作为唯一参数。FUNCTION 的返回值将替换字符串或缓冲区中的匹配文本。
|
- **FUNCTION** 接收匹配到的文本作为第一个参数。可选地,FUNCTION 可以接受两个额外的参数:START 和 END,表示匹配的起始和结束位置。FUNCTION 的返回值将替换字符串或缓冲区中的匹配文本。
|
||||||
- **N** 是搜索次数,默认为 1。
|
- **N** 是搜索次数,默认为 1。该函数会搜索 N 次,但仅对找到的最后(第 N 次)匹配应用 FUNCTION。
|
||||||
- **OBJECT** 可以是缓冲区或字符串;nil 默认为当前缓冲区。
|
- **OBJECT** 可以是缓冲区或字符串;nil 默认为当前缓冲区。
|
||||||
- **POINT** 是搜索的起始位置;对于缓冲区 nil 表示当前位置,对于字符串 nil 表示 0(向前)或字符串末尾(向后)。
|
- **POINT** 是搜索的起始位置;对于缓冲区 nil 表示当前位置,对于字符串 nil 表示 0(向前)或字符串末尾(向后)。
|
||||||
- 返回成功匹配的数量。
|
- 返回成功匹配的数量。
|
||||||
@ -895,7 +895,7 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
|
|||||||
**示例:**
|
**示例:**
|
||||||
|
|
||||||
```elisp
|
```elisp
|
||||||
;; 将缓冲区中匹配的文本转为大写(从当前位置开始)
|
;; 仅将最后一次(第 2 次)匹配的文本转为大写
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert "hello world test")
|
(insert "hello world test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
@ -903,17 +903,17 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
|
|||||||
(goto-char 1)
|
(goto-char 1)
|
||||||
(tp-forward-do #'upcase 'marker nil nil nil 2)
|
(tp-forward-do #'upcase 'marker nil nil nil 2)
|
||||||
(buffer-string))
|
(buffer-string))
|
||||||
;; => "HELLO world TEST"
|
;; => "hello world TEST" ; 仅第 2 次匹配被转为大写
|
||||||
|
|
||||||
;; 将字符串中匹配的文本转为大写(从位置 0 开始)
|
;; 仅将最后一次(第 2 次)匹配的文本转为大写
|
||||||
(let ((my-string (copy-sequence "hello world hello")))
|
(let ((my-string (copy-sequence "hello world hello")))
|
||||||
(tp-set 0 5 '(marker t) my-string)
|
(tp-set 0 5 '(marker t) my-string)
|
||||||
(tp-set 12 17 '(marker t) my-string)
|
(tp-set 12 17 '(marker t) my-string)
|
||||||
(tp-forward-do #'upcase 'marker nil my-string nil 2)
|
(tp-forward-do #'upcase 'marker nil my-string nil 2)
|
||||||
my-string)
|
my-string)
|
||||||
;; => "HELLO world HELLO"
|
;; => "hello world HELLO" ; 仅第 2 次匹配被转为大写
|
||||||
|
|
||||||
;; 从特定位置开始搜索
|
;; 从特定位置开始搜索(仅找到 1 次匹配并转换)
|
||||||
(let ((my-string (copy-sequence "hello world hello")))
|
(let ((my-string (copy-sequence "hello world hello")))
|
||||||
(tp-set 0 5 '(marker t) my-string)
|
(tp-set 0 5 '(marker t) my-string)
|
||||||
(tp-set 12 17 '(marker t) my-string)
|
(tp-set 12 17 '(marker t) my-string)
|
||||||
@ -921,17 +921,18 @@ Emacs 的 `text-property-search-forward` 和 `text-property-search-backward` 的
|
|||||||
my-string)
|
my-string)
|
||||||
;; => "hello world HELLO" ; 只处理位置 6 之后的匹配
|
;; => "hello world HELLO" ; 只处理位置 6 之后的匹配
|
||||||
|
|
||||||
;; 自定义转换
|
;; 使用带有 start 和 end 参数的函数
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert "hello world test")
|
(insert "hello world test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
|
(tp-set 13 17 '(marker t))
|
||||||
(goto-char 1)
|
(goto-char 1)
|
||||||
(tp-forward-do
|
(tp-forward-do
|
||||||
(lambda (text)
|
(lambda (text start end)
|
||||||
(concat "[" text "]"))
|
(format "[%d-%d]%s" start end text))
|
||||||
'marker nil nil nil 1)
|
'marker nil nil nil 2)
|
||||||
(buffer-string))
|
(buffer-string))
|
||||||
;; => "[hello] world test"
|
;; => "hello world [13-17]test" ; 仅最后一次匹配被转换
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
98
tp-tests.el
98
tp-tests.el
@ -643,22 +643,23 @@
|
|||||||
(should (equal (cadr matches) '(0 5 t))))))
|
(should (equal (cadr matches) '(0 5 t))))))
|
||||||
|
|
||||||
(ert-deftest tp-test-forward-do ()
|
(ert-deftest tp-test-forward-do ()
|
||||||
"Test tp-forward-do applies function to matched text."
|
"Test tp-forward-do applies function only to the last match."
|
||||||
(tp-test-with-temp-buffer
|
(tp-test-with-temp-buffer
|
||||||
(insert "hello World test")
|
(insert "hello World test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
(tp-set 13 17 '(marker t))
|
(tp-set 13 17 '(marker t))
|
||||||
(goto-char 1)
|
(goto-char 1)
|
||||||
(skip-unless (fboundp 'text-property-search-forward))
|
(skip-unless (fboundp 'text-property-search-forward))
|
||||||
;; Test that function receives text and can transform it
|
;; Test that function is applied only to the last (2nd) match
|
||||||
(let ((count (tp-forward-do #'upcase 'marker nil nil nil 2)))
|
(let ((count (tp-forward-do #'upcase 'marker nil nil nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check that text was upcased
|
;; First match should NOT be upcased
|
||||||
(should (equal (buffer-substring 1 6) "HELLO"))
|
(should (equal (buffer-substring 1 6) "hello"))
|
||||||
|
;; Only the last (2nd) match should be upcased
|
||||||
(should (equal (buffer-substring 13 17) "TEST")))))
|
(should (equal (buffer-substring 13 17) "TEST")))))
|
||||||
|
|
||||||
(ert-deftest tp-test--forward-do ()
|
(ert-deftest tp-test--forward-do ()
|
||||||
"Test tp--forward-do applies function to matches (internal API)."
|
"Test tp--forward-do applies function only to the last match (internal API)."
|
||||||
(tp-test-with-temp-buffer
|
(tp-test-with-temp-buffer
|
||||||
(insert "Hello World Test")
|
(insert "Hello World Test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
@ -670,25 +671,28 @@
|
|||||||
(lambda (match obj)
|
(lambda (match obj)
|
||||||
(push (prop-match-beginning match) result))
|
(push (prop-match-beginning match) result))
|
||||||
'marker nil nil nil 2)
|
'marker nil nil nil 2)
|
||||||
(should (= (length result) 2)))))
|
;; Only the last match should be processed
|
||||||
|
(should (= (length result) 1))
|
||||||
|
(should (= (car result) 13)))))
|
||||||
|
|
||||||
(ert-deftest tp-test-backward-do ()
|
(ert-deftest tp-test-backward-do ()
|
||||||
"Test tp-backward-do applies function to matched text."
|
"Test tp-backward-do applies function only to the last match."
|
||||||
(tp-test-with-temp-buffer
|
(tp-test-with-temp-buffer
|
||||||
(insert "hello World test")
|
(insert "hello World test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
(tp-set 13 17 '(marker t))
|
(tp-set 13 17 '(marker t))
|
||||||
(goto-char 18)
|
(goto-char 18)
|
||||||
(skip-unless (fboundp 'text-property-search-backward))
|
(skip-unless (fboundp 'text-property-search-backward))
|
||||||
;; Test that function receives text and can transform it
|
;; Test that function is applied only to the last (2nd) match
|
||||||
(let ((count (tp-backward-do #'upcase 'marker nil nil nil 2)))
|
(let ((count (tp-backward-do #'upcase 'marker nil nil nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check that text was upcased
|
;; Only the last (2nd) match should be upcased
|
||||||
(should (equal (buffer-substring 1 6) "HELLO"))
|
(should (equal (buffer-substring 1 6) "HELLO"))
|
||||||
(should (equal (buffer-substring 13 17) "TEST")))))
|
;; First match (searched backward) should NOT be upcased
|
||||||
|
(should (equal (buffer-substring 13 17) "test")))))
|
||||||
|
|
||||||
(ert-deftest tp-test--backward-do ()
|
(ert-deftest tp-test--backward-do ()
|
||||||
"Test tp--backward-do applies function to matches (internal API)."
|
"Test tp--backward-do applies function only to the last match (internal API)."
|
||||||
(tp-test-with-temp-buffer
|
(tp-test-with-temp-buffer
|
||||||
(insert "Hello World Test")
|
(insert "Hello World Test")
|
||||||
(tp-set 1 6 '(marker t))
|
(tp-set 1 6 '(marker t))
|
||||||
@ -700,29 +704,33 @@
|
|||||||
(lambda (match obj)
|
(lambda (match obj)
|
||||||
(push (prop-match-beginning match) result))
|
(push (prop-match-beginning match) result))
|
||||||
'marker nil nil nil 2)
|
'marker nil nil nil 2)
|
||||||
(should (= (length result) 2)))))
|
;; Only the last match should be processed
|
||||||
|
(should (= (length result) 1))
|
||||||
|
(should (= (car result) 1)))))
|
||||||
|
|
||||||
(ert-deftest tp-test-forward-do-on-string ()
|
(ert-deftest tp-test-forward-do-on-string ()
|
||||||
"Test tp-forward-do works on string objects."
|
"Test tp-forward-do applies only to the last match on string objects."
|
||||||
(let ((str (copy-sequence "hello World hello")))
|
(let ((str (copy-sequence "hello World hello")))
|
||||||
(tp-set 0 5 '(marker t) str)
|
(tp-set 0 5 '(marker t) str)
|
||||||
(tp-set 12 17 '(marker t) str)
|
(tp-set 12 17 '(marker t) str)
|
||||||
(let ((count (tp-forward-do #'upcase 'marker nil str nil 2)))
|
(let ((count (tp-forward-do #'upcase 'marker nil str nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check that text was upcased
|
;; First match should NOT be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "hello"))
|
||||||
|
;; Only the last (2nd) match should be upcased
|
||||||
(should (equal (substring str 12 17) "HELLO")))))
|
(should (equal (substring str 12 17) "HELLO")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-backward-do-on-string ()
|
(ert-deftest tp-test-backward-do-on-string ()
|
||||||
"Test tp-backward-do works on string objects."
|
"Test tp-backward-do applies only to the last match on string objects."
|
||||||
(let ((str (copy-sequence "hello World hello")))
|
(let ((str (copy-sequence "hello World hello")))
|
||||||
(tp-set 0 5 '(marker t) str)
|
(tp-set 0 5 '(marker t) str)
|
||||||
(tp-set 12 17 '(marker t) str)
|
(tp-set 12 17 '(marker t) str)
|
||||||
(let ((count (tp-backward-do #'upcase 'marker nil str nil 2)))
|
(let ((count (tp-backward-do #'upcase 'marker nil str nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check that text was upcased
|
;; Only the last (2nd) match should be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "HELLO"))
|
||||||
(should (equal (substring str 12 17) "HELLO")))))
|
;; First match (searched backward) should NOT be upcased
|
||||||
|
(should (equal (substring str 12 17) "hello")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-forward-do-with-point ()
|
(ert-deftest tp-test-forward-do-with-point ()
|
||||||
"Test tp-forward-do with point parameter."
|
"Test tp-forward-do with point parameter."
|
||||||
@ -751,7 +759,7 @@
|
|||||||
(should (equal (substring str 12 17) "hello")))))
|
(should (equal (substring str 12 17) "hello")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-forward-do-with-start-end ()
|
(ert-deftest tp-test-forward-do-with-start-end ()
|
||||||
"Test tp-forward-do passes optional start and end to function."
|
"Test tp-forward-do passes optional start and end to function for last match only."
|
||||||
(let ((str (copy-sequence "hello World hello"))
|
(let ((str (copy-sequence "hello World hello"))
|
||||||
(starts nil)
|
(starts nil)
|
||||||
(ends nil))
|
(ends nil))
|
||||||
@ -764,15 +772,15 @@
|
|||||||
(upcase txt))
|
(upcase txt))
|
||||||
'marker nil str nil 2)))
|
'marker nil str nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check positions were passed correctly
|
;; Check only the last match positions were passed
|
||||||
(should (equal (sort starts #'<) '(0 12)))
|
(should (equal starts '(12)))
|
||||||
(should (equal (sort ends #'<) '(5 17)))
|
(should (equal ends '(17)))
|
||||||
;; Check text was upcased
|
;; Only the last match should be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "hello"))
|
||||||
(should (equal (substring str 12 17) "HELLO")))))
|
(should (equal (substring str 12 17) "HELLO")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-forward-do-with-start-only ()
|
(ert-deftest tp-test-forward-do-with-start-only ()
|
||||||
"Test tp-forward-do passes start when function accepts 2 args."
|
"Test tp-forward-do passes start to function for last match only when function accepts 2 args."
|
||||||
(let ((str (copy-sequence "hello World hello"))
|
(let ((str (copy-sequence "hello World hello"))
|
||||||
(starts nil))
|
(starts nil))
|
||||||
(tp-set 0 5 '(marker t) str)
|
(tp-set 0 5 '(marker t) str)
|
||||||
@ -783,24 +791,25 @@
|
|||||||
(upcase txt))
|
(upcase txt))
|
||||||
'marker nil str nil 2)))
|
'marker nil str nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check start positions were passed correctly
|
;; Check only the last match start position was passed
|
||||||
(should (equal (sort starts #'<) '(0 12)))
|
(should (equal starts '(12)))
|
||||||
;; Check text was upcased
|
;; Only the last match should be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "hello"))
|
||||||
(should (equal (substring str 12 17) "HELLO")))))
|
(should (equal (substring str 12 17) "HELLO")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-forward-do-backward-compat ()
|
(ert-deftest tp-test-forward-do-backward-compat ()
|
||||||
"Test tp-forward-do works with single-argument functions (backward compat)."
|
"Test tp-forward-do applies only to last match with single-argument functions."
|
||||||
(let ((str (copy-sequence "hello World hello")))
|
(let ((str (copy-sequence "hello World hello")))
|
||||||
(tp-set 0 5 '(marker t) str)
|
(tp-set 0 5 '(marker t) str)
|
||||||
(tp-set 12 17 '(marker t) str)
|
(tp-set 12 17 '(marker t) str)
|
||||||
;; Use #'upcase which only takes one argument
|
;; Use #'upcase which only takes one argument
|
||||||
(tp-forward-do #'upcase 'marker nil str nil 2)
|
(tp-forward-do #'upcase 'marker nil str nil 2)
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
;; Only the last match should be upcased
|
||||||
|
(should (equal (substring str 0 5) "hello"))
|
||||||
(should (equal (substring str 12 17) "HELLO"))))
|
(should (equal (substring str 12 17) "HELLO"))))
|
||||||
|
|
||||||
(ert-deftest tp-test-backward-do-with-start-end ()
|
(ert-deftest tp-test-backward-do-with-start-end ()
|
||||||
"Test tp-backward-do passes optional start and end to function."
|
"Test tp-backward-do passes optional start and end to function for last match only."
|
||||||
(let ((str (copy-sequence "hello World hello"))
|
(let ((str (copy-sequence "hello World hello"))
|
||||||
(starts nil)
|
(starts nil)
|
||||||
(ends nil))
|
(ends nil))
|
||||||
@ -813,15 +822,15 @@
|
|||||||
(upcase txt))
|
(upcase txt))
|
||||||
'marker nil str nil 2)))
|
'marker nil str nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check positions were passed correctly
|
;; Check only the last match positions were passed
|
||||||
(should (equal (sort starts #'<) '(0 12)))
|
(should (equal starts '(0)))
|
||||||
(should (equal (sort ends #'<) '(5 17)))
|
(should (equal ends '(5)))
|
||||||
;; Check text was upcased
|
;; Only the last match should be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "HELLO"))
|
||||||
(should (equal (substring str 12 17) "HELLO")))))
|
(should (equal (substring str 12 17) "hello")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-backward-do-with-start-only ()
|
(ert-deftest tp-test-backward-do-with-start-only ()
|
||||||
"Test tp-backward-do passes start when function accepts 2 args."
|
"Test tp-backward-do passes start to function for last match only when function accepts 2 args."
|
||||||
(let ((str (copy-sequence "hello World hello"))
|
(let ((str (copy-sequence "hello World hello"))
|
||||||
(starts nil))
|
(starts nil))
|
||||||
(tp-set 0 5 '(marker t) str)
|
(tp-set 0 5 '(marker t) str)
|
||||||
@ -832,21 +841,22 @@
|
|||||||
(upcase txt))
|
(upcase txt))
|
||||||
'marker nil str nil 2)))
|
'marker nil str nil 2)))
|
||||||
(should (= count 2))
|
(should (= count 2))
|
||||||
;; Check start positions were passed correctly
|
;; Check only the last match start position was passed
|
||||||
(should (equal (sort starts #'<) '(0 12)))
|
(should (equal starts '(0)))
|
||||||
;; Check text was upcased
|
;; Only the last match should be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "HELLO"))
|
||||||
(should (equal (substring str 12 17) "HELLO")))))
|
(should (equal (substring str 12 17) "hello")))))
|
||||||
|
|
||||||
(ert-deftest tp-test-backward-do-backward-compat ()
|
(ert-deftest tp-test-backward-do-backward-compat ()
|
||||||
"Test tp-backward-do works with single-argument functions (backward compat)."
|
"Test tp-backward-do applies only to last match with single-argument functions."
|
||||||
(let ((str (copy-sequence "hello World hello")))
|
(let ((str (copy-sequence "hello World hello")))
|
||||||
(tp-set 0 5 '(marker t) str)
|
(tp-set 0 5 '(marker t) str)
|
||||||
(tp-set 12 17 '(marker t) str)
|
(tp-set 12 17 '(marker t) str)
|
||||||
;; Use #'upcase which only takes one argument
|
;; Use #'upcase which only takes one argument
|
||||||
(tp-backward-do #'upcase 'marker nil str nil 2)
|
(tp-backward-do #'upcase 'marker nil str nil 2)
|
||||||
|
;; Only the last match should be upcased
|
||||||
(should (equal (substring str 0 5) "HELLO"))
|
(should (equal (substring str 0 5) "HELLO"))
|
||||||
(should (equal (substring str 12 17) "HELLO"))))
|
(should (equal (substring str 12 17) "hello"))))
|
||||||
|
|
||||||
(ert-deftest tp-test-search-on-string ()
|
(ert-deftest tp-test-search-on-string ()
|
||||||
"Test tp-search finds all matching properties in a string."
|
"Test tp-search finds all matching properties in a string."
|
||||||
|
|||||||
24
tp.el
24
tp.el
@ -1023,7 +1023,7 @@ Returns the number of successful matches."
|
|||||||
matches)))))
|
matches)))))
|
||||||
|
|
||||||
(defun tp-forward-do (function property &optional value object point n)
|
(defun tp-forward-do (function property &optional value object point n)
|
||||||
"Search forward N times for text with PROPERTY and apply FUNCTION to each match.
|
"Search forward N times for text with PROPERTY and apply FUNCTION only to the last match.
|
||||||
|
|
||||||
FUNCTION receives the matched text as its first argument. Optionally,
|
FUNCTION receives the matched text as its first argument. Optionally,
|
||||||
FUNCTION can accept two additional arguments: START and END, representing
|
FUNCTION can accept two additional arguments: START and END, representing
|
||||||
@ -1032,7 +1032,8 @@ it receives (TEXT START). If it accepts 3 or more arguments, it receives
|
|||||||
(TEXT START END). The return value of FUNCTION replaces the matched text
|
(TEXT START END). The return value of FUNCTION replaces the matched text
|
||||||
in the string or buffer.
|
in the string or buffer.
|
||||||
|
|
||||||
N is the number of searches, defaulting to 1.
|
N is the number of searches, defaulting to 1. The function searches N times
|
||||||
|
but only applies FUNCTION to the last (Nth) match found.
|
||||||
VALUE is the optional value to match.
|
VALUE is the optional value to match.
|
||||||
OBJECT can be a buffer or string; nil defaults to current buffer.
|
OBJECT can be a buffer or string; nil defaults to current buffer.
|
||||||
POINT is the starting position for search; for buffers nil means current point,
|
POINT is the starting position for search; for buffers nil means current point,
|
||||||
@ -1046,14 +1047,15 @@ If the replacement is shorter, only that portion will be replaced.
|
|||||||
If the replacement is longer, it will be truncated.
|
If the replacement is longer, it will be truncated.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
;; Upcase all matched text
|
;; Upcase only the last (2nd) match
|
||||||
(setq my-string (copy-sequence \"hello world hello\"))
|
(setq my-string (copy-sequence \"hello world hello\"))
|
||||||
(tp-set 0 5 \\='(marker t) my-string)
|
(tp-set 0 5 \\='(marker t) my-string)
|
||||||
(tp-set 12 17 \\='(marker t) my-string)
|
(tp-set 12 17 \\='(marker t) my-string)
|
||||||
(tp-forward-do #\\='upcase \\='marker nil my-string nil 3)
|
(tp-forward-do #\\='upcase \\='marker nil my-string nil 2)
|
||||||
|
;; => \"hello world HELLO\" - only the 2nd match is upcased
|
||||||
;; Use start and end positions
|
;; Use start and end positions
|
||||||
(tp-forward-do (lambda (txt start end) (format \"[%d-%d]%s\" start end txt))
|
(tp-forward-do (lambda (txt start end) (format \"[%d-%d]%s\" start end txt))
|
||||||
\\='marker nil my-string nil 3)"
|
\\='marker nil my-string nil 2)"
|
||||||
(let ((arity (func-arity function)))
|
(let ((arity (func-arity function)))
|
||||||
(tp--forward-do
|
(tp--forward-do
|
||||||
(lambda (match obj)
|
(lambda (match obj)
|
||||||
@ -1137,7 +1139,7 @@ Returns the number of successful matches."
|
|||||||
matches)))))
|
matches)))))
|
||||||
|
|
||||||
(defun tp-backward-do (function property &optional value object point n)
|
(defun tp-backward-do (function property &optional value object point n)
|
||||||
"Search backward N times for text with PROPERTY and apply FUNCTION to each match.
|
"Search backward N times for text with PROPERTY and apply FUNCTION only to the last match.
|
||||||
|
|
||||||
FUNCTION receives the matched text as its first argument. Optionally,
|
FUNCTION receives the matched text as its first argument. Optionally,
|
||||||
FUNCTION can accept two additional arguments: START and END, representing
|
FUNCTION can accept two additional arguments: START and END, representing
|
||||||
@ -1146,7 +1148,8 @@ it receives (TEXT START). If it accepts 3 or more arguments, it receives
|
|||||||
(TEXT START END). The return value of FUNCTION replaces the matched text
|
(TEXT START END). The return value of FUNCTION replaces the matched text
|
||||||
in the string or buffer.
|
in the string or buffer.
|
||||||
|
|
||||||
N is the number of searches, defaulting to 1.
|
N is the number of searches, defaulting to 1. The function searches N times
|
||||||
|
but only applies FUNCTION to the last (Nth) match found.
|
||||||
VALUE is the optional value to match.
|
VALUE is the optional value to match.
|
||||||
OBJECT can be a buffer or string; nil defaults to current buffer.
|
OBJECT can be a buffer or string; nil defaults to current buffer.
|
||||||
POINT is the starting position for search; for buffers nil means current point,
|
POINT is the starting position for search; for buffers nil means current point,
|
||||||
@ -1160,14 +1163,15 @@ If the replacement is shorter, only that portion will be replaced.
|
|||||||
If the replacement is longer, it will be truncated.
|
If the replacement is longer, it will be truncated.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
;; Upcase all matched text
|
;; Upcase only the last (2nd) match
|
||||||
(setq my-string (copy-sequence \"hello world hello\"))
|
(setq my-string (copy-sequence \"hello world hello\"))
|
||||||
(tp-set 0 5 \\='(marker t) my-string)
|
(tp-set 0 5 \\='(marker t) my-string)
|
||||||
(tp-set 12 17 \\='(marker t) my-string)
|
(tp-set 12 17 \\='(marker t) my-string)
|
||||||
(tp-backward-do #\\='upcase \\='marker nil my-string nil 3)
|
(tp-backward-do #\\='upcase \\='marker nil my-string nil 2)
|
||||||
|
;; => \"hello world HELLO\" - only the 2nd (last) match is upcased
|
||||||
;; Use start and end positions
|
;; Use start and end positions
|
||||||
(tp-backward-do (lambda (txt start end) (format \"[%d-%d]%s\" start end txt))
|
(tp-backward-do (lambda (txt start end) (format \"[%d-%d]%s\" start end txt))
|
||||||
\\='marker nil my-string nil 3)"
|
\\='marker nil my-string nil 2)"
|
||||||
(let ((arity (func-arity function)))
|
(let ((arity (func-arity function)))
|
||||||
(tp--backward-do
|
(tp--backward-do
|
||||||
(lambda (match obj)
|
(lambda (match obj)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user