aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKévin Le Gouguec2022-09-11 19:55:01 +0200
committerLars Ingebrigtsen2022-09-11 19:55:36 +0200
commitd8f392bccd46cdb238ec96964f220ffb9d81cc44 (patch)
treee848ea4af2352a30411d4fe5ef1797fc87e87441
parentcba83d989359d667e52dad4e0e9eadf6f77cc38f (diff)
downloademacs-d8f392bccd46cdb238ec96964f220ffb9d81cc44.tar.gz
emacs-d8f392bccd46cdb238ec96964f220ffb9d81cc44.zip
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."
4219 (error "End after end of buffer")) 4219 (error "End after end of buffer"))
4220 (setq end (point-max))) 4220 (setq end (point-max)))
4221 (save-excursion 4221 (save-excursion
4222 (let ((matches 0) 4222 (goto-char start)
4223 (case-fold-search nil)) 4223 (save-restriction
4224 (goto-char start) 4224 (narrow-to-region start end)
4225 (while (search-forward string end t) 4225 (let ((matches 0)
4226 (delete-region (match-beginning 0) (match-end 0)) 4226 (case-fold-search nil))
4227 (insert replacement) 4227 (while (search-forward string nil t)
4228 (setq matches (1+ matches))) 4228 (delete-region (match-beginning 0) (match-end 0))
4229 (and (not (zerop matches)) 4229 (insert replacement)
4230 matches)))) 4230 (setq matches (1+ matches)))
4231 (and (not (zerop matches))
4232 matches)))))
4231 4233
4232(defun replace-regexp-in-region (regexp replacement &optional start end) 4234(defun replace-regexp-in-region (regexp replacement &optional start end)
4233 "Replace REGEXP with REPLACEMENT in the region from START to END. 4235 "Replace REGEXP with REPLACEMENT in the region from START to END.
@@ -4254,14 +4256,16 @@ REPLACEMENT can use the following special elements:
4254 (error "End after end of buffer")) 4256 (error "End after end of buffer"))
4255 (setq end (point-max))) 4257 (setq end (point-max)))
4256 (save-excursion 4258 (save-excursion
4257 (let ((matches 0) 4259 (goto-char start)
4258 (case-fold-search nil)) 4260 (save-restriction
4259 (goto-char start) 4261 (narrow-to-region start end)
4260 (while (re-search-forward regexp end t) 4262 (let ((matches 0)
4261 (replace-match replacement t) 4263 (case-fold-search nil))
4262 (setq matches (1+ matches))) 4264 (while (re-search-forward regexp nil t)
4263 (and (not (zerop matches)) 4265 (replace-match replacement t)
4264 matches)))) 4266 (setq matches (1+ matches)))
4267 (and (not (zerop matches))
4268 matches)))))
4265 4269
4266(defun yank-handle-font-lock-face-property (face start end) 4270(defun yank-handle-font-lock-face-property (face start end)
4267 "If `font-lock-defaults' is nil, apply FACE as a `face' property. 4271 "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."
968 (insert "Foo bar zot foobar") 968 (insert "Foo bar zot foobar")
969 (should (= (replace-string-in-region "Foo" "new" (point-min)) 969 (should (= (replace-string-in-region "Foo" "new" (point-min))
970 1)) 970 1))
971 (should (equal (buffer-string) "new bar zot foobar")))) 971 (should (equal (buffer-string) "new bar zot foobar")))
972
973 (with-temp-buffer
974 (insert "foo bar baz")
975 (should (= (replace-string-in-region "ba" "quux corge grault" (point-min))
976 2))
977 (should (equal (buffer-string)
978 "foo quux corge graultr quux corge graultz")))
979
980 (with-temp-buffer
981 (insert "foo bar bar")
982 (should (= (replace-string-in-region " bar" "" (point-min) 8)
983 1))
984 (should (equal (buffer-string)
985 "foo bar"))))
972 986
973(ert-deftest test-replace-regexp-in-region () 987(ert-deftest test-replace-regexp-in-region ()
974 (with-temp-buffer 988 (with-temp-buffer
@@ -991,7 +1005,21 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
991 (insert "Foo bar zot foobar") 1005 (insert "Foo bar zot foobar")
992 (should (= (replace-regexp-in-region "Fo+" "new" (point-min)) 1006 (should (= (replace-regexp-in-region "Fo+" "new" (point-min))
993 1)) 1007 1))
994 (should (equal (buffer-string) "new bar zot foobar")))) 1008 (should (equal (buffer-string) "new bar zot foobar")))
1009
1010 (with-temp-buffer
1011 (insert "foo bar baz")
1012 (should (= (replace-regexp-in-region "ba." "quux corge grault" (point-min))
1013 2))
1014 (should (equal (buffer-string)
1015 "foo quux corge grault quux corge grault")))
1016
1017 (with-temp-buffer
1018 (insert "foo bar bar")
1019 (should (= (replace-regexp-in-region " bar" "" (point-min) 8)
1020 1))
1021 (should (equal (buffer-string)
1022 "foo bar"))))
995 1023
996(ert-deftest test-with-existing-directory () 1024(ert-deftest test-with-existing-directory ()
997 (let ((dir (make-temp-name "/tmp/not-exist-"))) 1025 (let ((dir (make-temp-name "/tmp/not-exist-")))