0

I know the command isearch-forward-word, but there doesn't seem to be an isearch-replace-word. I'd like to search and replace every instance of a certain word in a buffer. For instance, search for every instance of i and replace with I.

I found this answer, which seems to allow a digit argument, but I just want to replace every instance in my buffer.

  • M-x replace-string RET gnu.org/software/emacs/manual/html_node/emacs/Replace.html It starts from wherever point is and works its way to the end of the buffer. If you want the whole buffer, then go to the top and call the function. Or, there are a few threads that wrap the replace-string in a save-excursion (or the equivalent thereof) that goes to the top and then returns point to where it was originally when the function ends. See also -- M-x query-replace -- gnu.org/software/emacs/manual/html_node/emacs/… – lawlist May 25 '15 at 18:40
  • This totally does not work at all. It replaces all instances of the characters, whether or not they constitute entire words. – incandescentman May 25 '15 at 18:44
  • You may also be interested in the multiple-cursors library that can select all occurrences in the buffer; or one + the next one going forward and so on; or one + the next one going backward and so on. github.com/magnars/multiple-cursors.el Multiple occurrences can be edited simultaneously. – lawlist May 25 '15 at 18:48
  • How about trying space I space with replace-string? That will get everything except for an occurrence at the beginning of a paragraph. – lawlist May 25 '15 at 18:52
  • That totally does not work either. Not all words have spaces before them or after them. Take a look at any of the sentences on this page and you'll realize this. – incandescentman May 25 '15 at 18:54
8

You don't need to define a separate function (command) for this. And even if you did define one, it need not use query-replace-regexp.

The standard command query-replace does just what you request, if you provide it with a prefix argument.

So just use C-u M-% to query-replace words.

C-h f query-replace tells you this (note the part in bold):

query-replace is an interactive compiled Lisp function in `replace.el'.

It is bound to M-%, <menu-bar> <edit> <replace> <query-replace>.

(query-replace FROM-STRING TO-STRING &optional DELIMITED START END BACKWARD)

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. For directions, type C-h at that time.

In Transient Mark mode, if the mark is active, operate on the contents of the region. Otherwise, operate from point to the end of the buffer.

Use M-n to pull the last incremental search string to the minibuffer that reads FROM-STRING, or invoke replacements from incremental search with a key sequence like C-s C-s M-% to use its current search string as the string to replace.

Matching is independent of case if case-fold-search is non-nil and FROM-STRING has no uppercase letters. Replacement transfers the case pattern of the old text to the new text, if case-replace and case-fold-search are non-nil and FROM-STRING has no uppercase letters. (Transferring the case pattern means that if the old text matched is all caps, or capitalized, then its replacement is upcased or capitalized.)

Ignore read-only matches if query-replace-skip-read-only is non-nil, ignore hidden matches if search-invisible is nil, and ignore more matches using isearch-filter-predicate.

If replace-lax-whitespace is non-nil, a space or spaces in the string to be replaced will match a sequence of whitespace chars defined by the regexp in search-whitespace-regexp.

Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace only matches surrounded by word boundaries. A negative prefix arg means replace backward.

Fourth and fifth arg START and END specify the region to operate on.

To customize possible responses, change the bindings in query-replace-map.


And if you insist that you want a separate command for this, then just do the obvious:

(defun q-r-word ()
  "Query-replace whole words."
  (interactive)
  (let ((current-prefix-arg  t))
    (call-interactively #'query-replace)))
4

Run query-replace-regexp with '\bi\b' as the query and 'I' as the replacement.


(Update to comment)

The function @lawlist linked to should work nicely if you want to replace all instances without questions. To still be prompted for each instance, below should do

(defun query-replace-word (word new-word)
  (interactive "sWord: \nsNew word: ")
  (query-replace-regexp (format "\\b%s\\b" word) new-word))

(Update in response to Drew's answer)

Doh. See Drew's better answer. I didn't know that this could be done with a prefix argument to query-replace.

  • Thanks, this works! Is it possible to define this as a function that automatically requests the search word and the replace word? – incandescentman May 25 '15 at 19:00
  • 2
    Find and Replace Whole Words (not substrings) in Emacs: stackoverflow.com/a/7353424/2112489 – lawlist May 25 '15 at 19:03
  • Yes, that works! – incandescentman May 25 '15 at 20:30
  • This does not work for me. Ubuntu 16.04 Emacs 25.3.2. It seems the "\b" doesn't work at all. – CodyChan May 2 '18 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.