diff options
author | Kévin Le Gouguec <kevin.legouguec@gmail.com> | 2022-09-11 19:55:01 +0200 |
---|---|---|
committer | Lars Ingebrigtsen <larsi@gnus.org> | 2022-09-11 19:55:36 +0200 |
commit | d8f392bccd46cdb238ec96964f220ffb9d81cc44 (patch) | |
tree | e848ea4af2352a30411d4fe5ef1797fc87e87441 | |
parent | cba83d989359d667e52dad4e0e9eadf6f77cc38f (diff) | |
download | emacs-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.el | 38 | ||||
-rw-r--r-- | test/lisp/subr-tests.el | 32 |
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-"))) |