summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@gmail.com>2022-09-11 19:55:01 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2022-09-11 19:55:36 +0200
commitd8f392bccd46cdb238ec96964f220ffb9d81cc44 (patch)
treee848ea4af2352a30411d4fe5ef1797fc87e87441
parentcba83d989359d667e52dad4e0e9eadf6f77cc38f (diff)
downloademacs-d8f392bccd46cdb238ec96964f220ffb9d81cc44.tar.gz
Restrict replace-*-in-region to the bounds defined by caller
* lisp/subr.el (replace-string-in-region, replace-regexp-in-region): Narrow to region before iterating over matches, instead of giving a bound to the search functions. * test/lisp/subr-tests.el (test-replace-string-in-region): Add regression tests (bug#57733).
-rw-r--r--lisp/subr.el38
-rw-r--r--test/lisp/subr-tests.el32
2 files changed, 51 insertions, 19 deletions
diff --git a/lisp/subr.el b/lisp/subr.el
index 686189e69b8..8769fec2b95 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -4219,15 +4219,17 @@ Comparisons and replacements are done with fixed case."
(error "End after end of buffer"))
(setq end (point-max)))
(save-excursion
- (let ((matches 0)
- (case-fold-search nil))
- (goto-char start)
- (while (search-forward string end t)
- (delete-region (match-beginning 0) (match-end 0))
- (insert replacement)
- (setq matches (1+ matches)))
- (and (not (zerop matches))
- matches))))
+ (goto-char start)
+ (save-restriction
+ (narrow-to-region start end)
+ (let ((matches 0)
+ (case-fold-search nil))
+ (while (search-forward string nil t)
+ (delete-region (match-beginning 0) (match-end 0))
+ (insert replacement)
+ (setq matches (1+ matches)))
+ (and (not (zerop matches))
+ matches)))))
(defun replace-regexp-in-region (regexp replacement &optional start end)
"Replace REGEXP with REPLACEMENT in the region from START to END.
@@ -4254,14 +4256,16 @@ REPLACEMENT can use the following special elements:
(error "End after end of buffer"))
(setq end (point-max)))
(save-excursion
- (let ((matches 0)
- (case-fold-search nil))
- (goto-char start)
- (while (re-search-forward regexp end t)
- (replace-match replacement t)
- (setq matches (1+ matches)))
- (and (not (zerop matches))
- matches))))
+ (goto-char start)
+ (save-restriction
+ (narrow-to-region start end)
+ (let ((matches 0)
+ (case-fold-search nil))
+ (while (re-search-forward regexp nil t)
+ (replace-match replacement t)
+ (setq matches (1+ matches)))
+ (and (not (zerop matches))
+ matches)))))
(defun yank-handle-font-lock-face-property (face start end)
"If `font-lock-defaults' is nil, apply FACE as a `face' property.
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 4310b7291ad..30117132101 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -968,7 +968,21 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
(insert "Foo bar zot foobar")
(should (= (replace-string-in-region "Foo" "new" (point-min))
1))
- (should (equal (buffer-string) "new bar zot foobar"))))
+ (should (equal (buffer-string) "new bar zot foobar")))
+
+ (with-temp-buffer
+ (insert "foo bar baz")
+ (should (= (replace-string-in-region "ba" "quux corge grault" (point-min))
+ 2))
+ (should (equal (buffer-string)
+ "foo quux corge graultr quux corge graultz")))
+
+ (with-temp-buffer
+ (insert "foo bar bar")
+ (should (= (replace-string-in-region " bar" "" (point-min) 8)
+ 1))
+ (should (equal (buffer-string)
+ "foo bar"))))
(ert-deftest test-replace-regexp-in-region ()
(with-temp-buffer
@@ -991,7 +1005,21 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
(insert "Foo bar zot foobar")
(should (= (replace-regexp-in-region "Fo+" "new" (point-min))
1))
- (should (equal (buffer-string) "new bar zot foobar"))))
+ (should (equal (buffer-string) "new bar zot foobar")))
+
+ (with-temp-buffer
+ (insert "foo bar baz")
+ (should (= (replace-regexp-in-region "ba." "quux corge grault" (point-min))
+ 2))
+ (should (equal (buffer-string)
+ "foo quux corge grault quux corge grault")))
+
+ (with-temp-buffer
+ (insert "foo bar bar")
+ (should (= (replace-regexp-in-region " bar" "" (point-min) 8)
+ 1))
+ (should (equal (buffer-string)
+ "foo bar"))))
(ert-deftest test-with-existing-directory ()
(let ((dir (make-temp-name "/tmp/not-exist-")))