I want to select some text somewhere in a buffer, call query-replace and then type (or paste from kill-ring) only the second argument, TO-STRING, (and make the selected text count as FROM-STRING).

I want a replacement to be performed within the entire buffer as well.


If you use library Replace+ (replace+.el) then you can just customize option search/replace-region-as-default-flag to non-nil. That gives you the region text as FROM text default, so you can just hit RET to accept that.

search/replace-region-as-default-flag is a variable defined in replace+.el.

Its value is nil


Non-nil means use the active region text as default for search/replace.

That is, if the region is currently active then use its text as the default input. All text properties are removed from the text.

Note that in this case the active region is not used to limit the search/replacement scope. But in that case you can of course just narrow the buffer temporarily to restrict the operation scope.

A non-nil value of this option takes precedence over the use of option search/replace-2nd-sel-as-default-flag. To give that option precedence over using the active region, you can set this option to nil and use region-or-non-nil-symbol-name-nearest-point as the value of option search/replace-default-fn.

You can customize this variable.

You can also use command toggle-search/replace-region-as-default anytime to toggle the option value.

But if you really want not to even have to hit RET to accept the region text then you'll need to write a command that uses that as the FROM arg to query-replace and then interactively reads the other args.

This should do that:

(defun my-q-r (from-string to-string
               &optional delimited start end backward region-noncontiguous-p)
  "Query-replace text of active region with text you're prompted for."
     (let* ((from (if (use-region-p)
              (buffer-substring (region-beginning) (region-end))
            (query-replace-read-from "Query replace" nil)))
        (to (if (consp from) (prog1 (cdr from) (setq from (car from)))
          (query-replace-read-to from "Query replace" nil))))
       (list from to
         (or (and current-prefix-arg (not (eq current-prefix-arg '-)))
         (and (plist-member (text-properties-at 0 from) 'isearch-regexp-function)
                      (get-text-property 0 'isearch-regexp-function from)))
         (and current-prefix-arg (eq current-prefix-arg '-))))))
  (query-replace from-string to-string delimited start end backward region-noncontiguous-p))
  • Thank you, sir. It'll replace only the following occurrences but I presume I just need to add the "jump to file start" somewhere. – achempion Mar 25 at 19:19
  • 1
    Yes. That's the case for query-replace commands. If you want, you can put this at the beginning of the code that defines the command: (goto-char (point-min)), after the interactive spec. – Drew Mar 25 at 20:10
M-w M-< M-% C-y RET <replacement> RET ! 

does the trick.

  • I want to be able to pass the <replacement> from my kill ring as well. – achempion Mar 25 at 19:13
  • 1
    You can have multiple kills in the kill-ring. C-y to yank the last killed and M-y to yank the previous ones. (info "(emacs) Yanking Early Kills"). You can also use registers (info "(emacs)registers"). – gigiair Mar 25 at 21:50
  • Yes, indeed, but this feature doesn't work with query-replace function (I'm using counsel-yank-pop for M-y binding). – achempion Mar 26 at 5:12

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.