0

I have this function:

(defun my-replacements ()
  (interactive)
  (query-replace "foo" "bar" nil (point-min) (point-max))
  (query-replace "baz" "quz" nil (point-min) (point-max))
  (query-replace "fred" "thud" nil (point-min) (point-max)))

If I run it and accidentally type, for example, 'k' during one of the replacements, the function is interrupted, skipping all the remaining replacements.

I know that query-replace accepts only events binded in the query-replace-map and from the manual I know that:

Aside from this, any other character exits the query-replace, and is then reread as part of a key sequence. Thus, if you type C-k, it exits the query-replace and then kills to end of line. In particular, C-g simply exits the query-replace.

I would like to circumvent this behavior by ensuring that events not defined in the query-replace-map are simply ignored. Is there a way to achieve this?

I thought it could be done with a macro, e.g.:

(with-ignore-qr-unbinded-events
  MY CODE HERE)

but I have no idea how to do it.

As a feature request, I would like to add an optional argument to the function so that I can have control over this behavior. Does it make sense to you?

Edit. I just realized that a better idea would be using a variable to control this feature I request.

1 Answer 1

1

Try this ...

(defvar my-do-nothing-map
  (let ((map (make-keymap)))
    (set-char-table-range (nth 1 map) t 'ignore)
    map))

(set-keymap-parent query-replace-map my-do-nothing-map)

The proposed solution involves creating a custom keymap called my-do-nothing-map. This keymap is configured so that all keyboard events have no associated action, meaning they are ignored.

  1. Creation of my-do-nothing-map: A custom keymap named my-do-nothing-map is created using the function make-keymap. This keymap serves as a container for key bindings.

  2. Setting Up the Keymap: Within this custom keymap, the function set-char-table-range is used to set a default action for all keyboard events. The 'ignore value is assigned to every key, indicating that no action should be taken when any key is pressed.

  3. Inheritance from query-replace-map: The keymap my-do-nothing-map is set as the parent of query-replace-map using the function set-keymap-parent. This means that when Emacs looks for a key binding in query-replace-map and does not find one, it will then check my-do-nothing-map for a binding. Since all keys in my-do-nothing-map are configured to be ignored, Emacs effectively skips handling any unbound keys during the execution of query-replace.

In summary, this solution ensures that during the execution of query-replace, any unintended key presses that are not explicitly bound in query-replace-map are ignored, preventing premature interruption of the function due to accidental keystrokes.

C-g still works!

3
  • Beautiful! Could you please add a short (or long...) explanation of your code, please?
    – Gabriele
    Commented Feb 24 at 7:48
  • I added an explanation of what your code does.
    – Gabriele
    Commented Feb 28 at 12:41
  • I approved your edits. Thanks.
    – mxnt
    Commented Feb 29 at 14:22

Your Answer

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

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