Reputation: 1977
Using query-replace
, the minibuffer says this (having saved the previous arguments):
Query replace (default FROM -> TO)
is there a command to swap the args? To get this:
Query replace (default TO -> FROM)
Upvotes: 4
Views: 389
Reputation: 788
I use this:
;; Redefine `query-replace-read-from' to add a custom keymap when
;; replacing strings. Now, C-u ENTER does the reverse suggested
;; replacement.
(defvar query-replace-keymap
(let ((map (make-sparse-keymap)))
(set-keymap-parent map minibuffer-local-map)
(define-key map [remap exit-minibuffer]
(lambda ()
(interactive)
(if (and current-prefix-arg query-replace-defaults)
(setq query-replace-defaults
(cons
(cdr query-replace-defaults)
(car query-replace-defaults))))
(exit-minibuffer)))
map))
(defun query-replace-read-from (prompt regexp-flag)
"Query and return the `from' argument of a query-replace operation.
The return value can also be a pair (FROM . TO) indicating that the user
wants to replace FROM with TO."
(if query-replace-interactive
(car (if regexp-flag regexp-search-ring search-ring))
(let* ((history-add-new-input nil)
(query-replace-defaults query-replace-defaults)
(prompt
(if query-replace-defaults
(format "%s (default %s -> %s): " prompt
(query-replace-descr (car query-replace-defaults))
(query-replace-descr (cdr query-replace-defaults)))
(format "%s: " prompt)))
(from
;; The save-excursion here is in case the user marks and copies
;; a region in order to specify the minibuffer input.
;; That should not clobber the region for the query-replace itself.
(save-excursion
(if regexp-flag
(read-regexp prompt nil query-replace-from-history-variable)
(read-from-minibuffer
prompt nil query-replace-keymap nil query-replace-from-history-variable
(car (if regexp-flag regexp-search-ring search-ring)) t)))))
(if (and (zerop (length from)) query-replace-defaults)
(cons (car query-replace-defaults)
(query-replace-compile-replacement
(cdr query-replace-defaults) regexp-flag))
(add-to-history query-replace-from-history-variable from nil t)
;; Warn if user types \n or \t, but don't reject the input.
(and regexp-flag
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from)
(let ((match (match-string 3 from)))
(cond
((string= match "\\n")
(message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead"))
((string= match "\\t")
(message "Note: `\\t' here doesn't match a tab; to do that, just type TAB")))
(sit-for 2)))
from))))
Upvotes: 1
Reputation: 4804
(defun swap-query-replace-defaults ()
"Swap the initial expressions offered by `query-replace'. "
(interactive)
(let* ((erg query-replace-defaults)
(first (car erg))
(second (cdr erg)))
(setq query-replace-defaults (cons second first))
(when (interactive-p) (message "%s" query-replace-defaults))
query-replace-defaults))
Made a feature-request:
http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00102.html
Upvotes: 1
Reputation: 30699
AFAIK, nothing out of the box does that for you. But IMHO you don't need that.
All you need to do is use M-p
. Use it once to get the last TO
you used. Then repeat M-p
a couple times to get the last FROM
you used. Very quick.
After that, you can use C-x ESC ESC
(or C-x M-:
or C-x M-ESC
), possibly followed by M-p
, to repeat either combination (TO -> FROM
or FROM -> TO
).
Upvotes: 3