3

Sometimes I need to change a variable name in the code from foo to bar. I do it using query-replace-regexp. Then I would do some other stuff and I might regret my decision and want to change it back from bar to foo. If I do query-replace-regexp, it will show by default the last replacement performed (default foo -> bar). My question is, is there a quick way to tell Emacs I want the reverse order of the default? Otherwise one would need to type the whole thing again.

Edit: The default replacement is the last replacement (default foo -> bar). What I want now is the opposite: bar to foo. Basically, I want to undo the replacement. Not always can I use the undo feature since I may have a very long history after many other edits.

7
  • You should use the "refactor variable name" feature in your language mode to do this, most likely. Commented Sep 26, 2016 at 12:17
  • 2
    You don't need to "type the whole thing again". Use the command history to pick the previous two options, one at a time, in the opposite order. Commented Sep 26, 2016 at 13:16
  • 1
    Also, this probably makes less sense for query-replace-regexp than it does for plain old query-replace as your query and replace strings can have capture groups and backrefs in the prior that wouldn't make sense to reverse. Commented Sep 26, 2016 at 13:18
  • @phils: Please consider posting that as an answer. Commented Sep 26, 2016 at 13:41
  • The default replacement is the last replacement (default foo -> bar). What I want now is the opposite: bar to foo. Basically, I want to undo the replacement. Not always can I use the undo feature since I may have a very long history after many other edits. Commented Sep 26, 2016 at 14:10

2 Answers 2

3

When you use query-replace, M-p retrieves the default, which is foo -> bar. That is, it puts foo -> bar in the minibuffer.

You can edit that text in the minibuffer. In particular, you can move backward a word (or a sexp), using M-b (or C-M-b), and then use M-t (or C-M-t) to transpose the two words (sexps) there, giving you bar -> foo. (Then hit RET.)

The point is that once you have retrieved a previously used input, or the default input, you can edit it in the minibuffer.

(Normally, in Emacs, it is M-n that retrieves the default value. In this case it is M-p (which (IMHO) is an aberration).)


Wrt accessing previously entered input: You can cycle, by repeating M-p, but you can also search directly, using M-r. If the input you want to retrieve was not very recent, then M-r can be quicker than cycling.

Sign up to request clarification or add additional context in comments.

2 Comments

This transpose doesn't work for things like an IP, because of the periods
@JasonHunter: "The point is that once you have retrieved a previously used input, or the default input, you can edit it in the minibuffer."
1

This is probably a horrible way of doing this, but you could create a function like the following and bind it to another key. It seems to work in this specific case but there are tons of other things that this doesn't handle as is (such as the prefix argument).

(defun so-undo-last-query-replace ()
  (interactive)
  (let ((query-replace-defaults (list (cons (cdar query-replace-defaults)
                                            (caar query-replace-defaults)))))
    (call-interactively 'query-replace)))

1 Comment

this actually looked like it would work, because it set it up correctly, but it doesn't actually change the words

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.