Subject: bug#6256: 24.0.50; read-event in `repeat' command

From: "Drew Adams" <[email-masked]>
Date: Sat, 3 Jul 2010 14:24:23 -0700

> > I take it back.  `read-char-exclusive' is not the right 
> > fix, because not all keyboard events are character events.
> > Hitting the key `left', for instance, does not work.
> 
> I think the real answer is that both read-event and 
> read-char-exclusive are the wrong answer.  A better answer
> would be to have some way to change the way the next key is
> handled.  Something like a `next-key-map', kind of like the
> overriding maps, except that it would be automatically reset
> before running a command (and it would not disable the other
> keymaps, only take precedence over them).
> 
> Basically calling read-event and friends and then putting it
> back onto the unread-command-events list is almost always
> wrong in one way or another (e.g. it postpones running
> post-command-hook).

I don't really understand the code very well, I admit.  You obviously understand
it and have an idea for how to improve things in a big way.  It's not clear that
that improvement is soon forthcoming, however.  I assume that it might not be
trivial or that you are busy doing other things.

While waiting for the ideal fix, can we at least improve this incrementally to
enable `repeat' to work as I would expect it to wrt, say, mouse events?

For example, suppose I do this:

(defun repeat-command (command)
  (let ((repeat-previous-repeated-command  command)
        (repeat-message-function           'ignore)
        (last-repeatable-command           'repeat))
    (repeat nil)))

(defun foo-repeat (arg)
  (interactive "P")
  (repeat-command 'foo)) 

(define-key my-map (vector (list mouse-wheel-up-event)) 'foo-repeat)

And suppose `my-map' is bound to `C-x p'.  I would like for `C-x p' followed by
repeated mouse-wheel-up events to repeat command `foo'.

That does not happen, however, because of this restrictive `eq' test in the
definition of function `repeat':

(while (eq (read-event) repeat-repeat-char)
  (repeat repeat-arg))

The event read will be something like this, for the wheel action:

(wheel-down (#<window 8 on foo.el> 2051 (118 . 176) 158455015 nil
            2051 (59 . 40) nil (26 . 2) (2 . 4)))

I would think that we would want to change the test to this, or similar:

(while (let ((evt  (read-event)))
         (and (equal (event-basic-type evt) (event-basic-type
repeat-repeat-char))
              (equal (event-modifiers evt)  (event-modifiers
repeat-repeat-char))))
  (repeat repeat-arg))

And that seems to work OK.  What do you think - is it reasonable to do that?  It
seems like a win, to me (nothing lost, something gained).  But perhaps I'm
missing something.

It seems to me that what we want is to check whether the same user event
occurred, and for complex events such as mouse events we would typically just
want the same event type with the same modifiers.

Please let me know what you think.