Take the 2-minute tour ×

I use M-x query-replace on Emacs (M-%) quite often, and I like that I have the flexibility to choose between these options:

Spacebar               Replace text and find the next occurrence
Del                    Leave text as is and find the next occurrence
. (period)             Replace text, then stop looking for occurrences
! (exclamation point)  Replace all occurrences without asking
^ (caret)              Return the cursor to previously replaced text

Is there a way to:

  • Cycle back to the beginning of the document after we hit the end of the document?

  • Reverse the direction of the search-and-replace in the middle of the execution of the command.

share|improve this question
query-replace-string (and its regexp sibling) only go forward, you'd have to rewrite a big chunk of code to go backward. There's no option to wrap (there might be a package out there somewhere), but that's easy to work around: M-< (beginning-of-buffer), do the replacement, C-2 C-SPC (go back to the next-to-last mark set (by M-<)). –  Gilles Sep 16 '12 at 1:35
Interesting idea. Could be quite convenient. Ask the emacs gurus. They may like it enough, so they implement it. –  Tom Sep 16 '12 at 6:50
Probably you should change your post so not to make everyone confused: that's query-replace (As for your question, can't help you.) –  Emanuel Berg Sep 16 '12 at 9:26

1 Answer 1

up vote 2 down vote accepted

query-replace is a very important function, so I'm reluctant to change it globally. What I've done instead is to copy this to a new function, my-query-replace, which initially has the same behaviour. Then I advise this function to repeat the query-replace search at the beginning of the buffer once it reaches the end. This might be overly cautious - you could modify the advice to apply to query-replace instead of my-query-replace, and enable this behaviour globally.

;; copy the original query-replace-function 
(fset 'my-query-replace 'query-replace)

;; advise the new version to repeat the search after it 
;; finishes at the bottom of the buffer the first time:    
(defadvice my-query-replace 
  (around replace-wrap 
  "Execute a query-replace, wrapping to the top of the buffer 
   after you reach the bottom"
    (let ((start (point)))
      (ad-set-args 4 (list (point-min) start))

;; Turn on the advice    
(ad-activate 'my-query-replace)

Once you have evaluated this code, you can call the wrapped search with M-x my-query-replace, or bind it to something convenient for you:

(global-set-key "\C-cq" 'my-query-replace)
share|improve this answer

Your Answer


