I have this loop:

(catch 'QUIT
      (search-forward-regexp "\\([^\n\\]\\(?:\\\\\\\\\\)*\\|^\\(?:\\\\\\\\\\)+\\)%.*\n"
                 nil t)
          (let ((b (make-marker))
        (e (make-marker))
        (set-marker b (match-beginning 0))
        (set-marker e (point))

        (setq MatchedStringOverlay (make-overlay b e))
          (overlay-put MatchedStringOverlay 'face '(:background "OliveDrab1"))
          (setq ACTION (read-char "Options:
- [y] erase string and the corresponding \"newline\"
- [l] erase string keeping the corresponding \"newline\"
- [n] skip
- [q] quit:
           ((char-equal ACTION ?y)
            (replace-match "\\1"))
           ((char-equal ACTION ?l)
            (replace-match "\\1\n"))
           ((char-equal ACTION ?n)
           ((char-equal ACTION ?q)
            (throw 'QUIT nil))
          (remove-overlays b e))

It work fine for my purposes but it would be better if I could get this behaviour: Let's say I chose the [y] option, I'd like to perform the replacement but "pause" the loop until the [y] key is released. The best would be if, while pressing [y] I could undo the action pressing another key (e.g. [u]).

I'm, obviously, not asking you to write the code for me, but I'd like to know if it is possible to get what I figured out and, if so, what to look at.

EDIT. I figured out a simpler way to get way to get what I need, buy using lowcase or Uppercase version of char but I'm also interested to learn about events.

  • 1
    I don't know about key depress actions except for the mouse, but one idea could be to have a second loop that asks if you are sure, and it can have a timer with a default action if nothing is pressed. org-capture, I believe, has this loop that I'm thinking of and I use it in a few places -- essentially, if an invalid key is pressed (e.g., a list of no no's) then a second loop begins. read-char-exclusive has an optional timer, but I'd need to see if just read-char offers the same feature. See (while (not (member pressed allowed-keys)) in org-capture.el.
    – lawlist
    Jun 22, 2017 at 22:17

1 Answer 1


Release of a keyboard key is not an event that is detected by Emacs. (But release of a mouse button is an event seen by Emacs.)

Maybe change from reading and acting on a single character to acting on two keys, separately: Act on the first key by doing what you describe first: "perform the replacement but "pause" the loop until" the second key is pressed. Act on the second key to confirm the real action and continue the loop.

  • I've got the same idea after understanding that the behaviour I was looking for is not possible to achieve in emacs. Jun 23, 2017 at 15:21

Your Answer

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

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