Search and replace, by M-% and !, is done from current position to the end of the buffer. How can I do it for the entire buffer? Thanks.
-
2I suggest changing the title to "search and replace entire buffer". Globally could also be referring to entire projects. – Malabarba Sep 25 '14 at 16:01
-
3This is one area where Vim/Evil is hard to beat: `:%s/foo/bar` – shosti Sep 25 '14 at 18:31
-
@shosti: Actually, I think your method requires more keystrokes. Just sayin' ;-) – nispio Sep 25 '14 at 20:13
7 Answers
I don't see that supported while still retaining your starting position. (I don't see a way to wrap to the beginning of the buffer when search reaches the end.)
Your best bet is using M-< to go to the start of the buffer, then do the query-replace
, when you're done press C-uC-spaceC-uC-space to jump back to your starting point.

- 2,635
- 1
- 16
- 27

- 12,332
- 2
- 41
- 62
-
1This works when `transient-mark-mode` is on. Otherwise `C-SPC C-SPC` will temporarily enable `transient-mark-mode` – nispio Sep 25 '14 at 16:43
-
5No need to set the mark manually with C-SPC. M-< (and many other commands that potentially "move point a long way") does it for you. – Mathias Dahl Sep 25 '14 at 18:45
You can follow the following steps:
C-x h
— Select the whole buffer orM-<
- Go to the top of the bufferM-%
— Initiatequery-replace
!
— Force replace allC-u C-SPC C-u C-SPC
— Move back to your starting position

- 21,702
- 4
- 53
- 89

- 25,203
- 3
- 74
- 179
You could add the following command to your emacs initialization file, and bind it to the keystroke of your choice.
(defun replace-regexp-entire-buffer (pattern replacement)
"Perform regular-expression replacement throughout buffer."
(interactive
(let ((args (query-replace-read-args "Replace" t)))
(setcdr (cdr args) nil) ; remove third value returned from query---args
args))
(save-excursion
(goto-char (point-min))
(while (re-search-forward pattern nil t)
(replace-match replacement))))

- 1,406
- 12
- 13
You can add this to your init.el
file to update the behavior of M-%
to to replace the word in the entire buffer by default:
(defun my/query-replace (from-string to-string &optional delimited start end)
"Replace some occurrences of FROM-STRING with TO-STRING. As each match is
found, the user must type a character saying what to do with it. This is a
modified version of the standard `query-replace' function in `replace.el',
This modified version defaults to operating on the entire buffer instead of
working only from POINT to the end of the buffer. For more information, see
the documentation of `query-replace'"
(interactive
(let ((common
(query-replace-read-args
(concat "Query replace"
(if current-prefix-arg " word" "")
(if (and transient-mark-mode mark-active) " in region" ""))
nil)))
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (and transient-mark-mode mark-active)
(region-beginning)
(buffer-end -1))
(if (and transient-mark-mode mark-active)
(region-end)
(buffer-end 1)))))
(perform-replace from-string to-string t nil delimited nil nil start end))
;; Replace the default key mapping
(define-key esc-map "%" 'my/query-replace)
And to get the same behavior from query-replace-regexp
:
(defun my/query-replace-regexp (regexp to-string &optional delimited start end)
"Replace some things after point matching REGEXP with TO-STRING. As each
match is found, the user must type a character saying what to do with
it. This is a modified version of the standard `query-replace-regexp'
function in `replace.el', This modified version defaults to operating on the
entire buffer instead of working only from POINT to the end of the
buffer. For more information, see the documentation of `query-replace-regexp'"
(interactive
(let ((common
(query-replace-read-args
(concat "Query replace"
(if current-prefix-arg " word" "")
" regexp"
(if (and transient-mark-mode mark-active) " in region" ""))
t)))
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (and transient-mark-mode mark-active)
(region-beginning)
(buffer-end -1))
(if (and transient-mark-mode mark-active)
(region-end)
(buffer-end 1)))))
(perform-replace regexp to-string t t delimited nil nil start end))
;; Replace the default key mapping
(define-key esc-map [?\C-%] 'my/query-replace-regexp)

- 8,175
- 2
- 35
- 73
If you use Icicles then you can search-and-replace over the entire buffer (or multiple buffers or files or bookmark targets).
And unlike query-replace
(e.g. C-x h M-%
):
You can navigate the matches in any order.
Replacement is on demand: you need not visit each match and answer whether or not to replace it.

- 75,699
- 9
- 109
- 225
-
-
@alper: Thanks; corrected. Emacs Wiki changed from http to https, and added an `emacs/` subdir. – Drew Feb 06 '20 at 16:00
This is the solution I'm currently using, it start from the begining of the buffer and will go back to old point after replacing.
(defun query-replace-region-or-from-top ()
"If marked, query-replace for the region, else for the whole buffer (start from the top)"
(interactive)
(progn
(let ((orig-point (point)))
(if (use-region-p)
(call-interactively 'query-replace)
(save-excursion
(goto-char (point-min))
(call-interactively 'query-replace)))
(message "Back to old point.")
(goto-char orig-point))))
(bind-key* "M-%" 'query-replace-region-or-from-top)

- 2,599
- 1
- 19
- 33
-
-
-
1@alper use `(let ((case-fold-search nil))` check https://stackoverflow.com/a/5346418/1528712 – CodyChan Oct 04 '21 at 15:24
My very simple but effective variant, which just advises both query-replace
and query-replace-regexp
to start replacing from the top of the buffer if region is not active. Otherwise, replace in the region only.
So this doesn't need new keybinds - just continue to use M-% and M-C-%.
(defun jj/goto-top-if-no-region (orig-func &rest args)
"if region is not active, go to the buffer start"
(save-excursion
(when (not (use-region-p))
(goto-char (point-min)))
(apply orig-func args)))
(advice-add 'query-replace :around #'jj/goto-top-if-no-region)
(advice-add 'query-replace-regexp :around #'jj/goto-top-if-no-region)

- 153
- 6