diff options
| author | Kévin Le Gouguec | 2022-09-11 19:55:01 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-09-11 19:55:36 +0200 |
| commit | d8f392bccd46cdb238ec96964f220ffb9d81cc44 (patch) | |
| tree | e848ea4af2352a30411d4fe5ef1797fc87e87441 | |
| parent | cba83d989359d667e52dad4e0e9eadf6f77cc38f (diff) | |
| download | emacs-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.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." | |||
| 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-"))) |