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

From: "Drew Adams" <[email-masked]>
Date: Tue, 19 Oct 2010 15:17:45 -0700

> > 3. Your current read-key fix for `repeat' does not work in Emacs 23,
> > whereas my fix using read-event does work.
> 
> I did not understand that from your answer and I'm very 
> surprised, since
> AFAIK this part of Emacs hasn't changed significantly.  In 
> any case I've
> only tested it under Emacs-23 (yup, that's a 3 there).
> 
> > But maybe I will be if I understand its advantages.  What was your
> > objection to the solution I provided using `read-event'?  You never
> > stated it, IIRC.
> 
> Your characterization of what works and what doesn't makes no sense to
> me (based on my understand of what the code does, and based on my
> tests), so I used the code that I know to work and I understand why.
> 
> Since you say it doesn't work for you, please follow my advice:
> 
>    Please confirm whether or not it fixes it
>    for you, and if it doesn't, please show me the values of
>    `repeat-repeat-char' and `evt' in the above test.
> 
> because without that info from your tests, I can't help you 
> much further.

I tried debugging it that way.  I added this just after the (let ((evt
(read-key))), that is BEFORE the `and' test of the `while':
(message "EVT: %S, R-R-CHAR: %S" evt repeat-repeat-char)

In my own Emacs setup (which has lots of stuff in it) `C-x p wheel-down' moves
correctly to the first bookmark, but then subsequent wheel-downs just start
scrolling the window.  IOW, `repeat' is exited immediately - there is no
repetition at all.

And because it exits immediately _no_ debug message appears in *Messages*.  That
tells me that it exited during `read-key', not because the event/key tested did
not match (`while' test = nil).  Apparently `read-key' itself exits out to the
`unwind-protect' protection code in this scenario.

I tried fiddling with `read-key-delay' but that didn't help. I used 3 bookmarks,
all in the same buffer, so there should be no switch-frame events interfering
anywhere.  I do use a standalone minibuffer in my setup, and that sometimes
causes `handle-switch-frame' events to happen in places one might not expect.
But I don't think that is happening here (we are not even using the minibuffer,
and everything should be taking place in the same frame).  Dunno what is causing
the problem.

In emacs -Q, however, with just the Bookmark+ files loaded, I do not see the
problem.  That is presumably what you are seeing.

The only way I see a problem then (without my setup) is if I rotate the wheel
more rapidly.  That is no doubt because it gets a `double-wheel-down' or
`triple-wheel-down' event instead of a `wheel-down' event.  I haven't bound
those events specifically to the bookmark-cycling command, but I could do so to
get around that (assuming that's the cause).  For the same reason, I can see
that same rapid-rotation problem with the fix I sent.  This rapid-rotation
behavior is not an issue, for me.

The issue is the behavior I see when I use my own setup, and I cannot begin to
pare things down from that setup to determine just what else might be involved.

Presumably the bad behavior has something to do with how `read-key' works -
something is apparently causing it to barf, but how `read-key' works is unclear
to me.  I hope that you (who wrote it) can figure out or guess what's happening
here.

I would have guessed that if there were a problem it would have occurred because
`read-key' did not return an event/key that matched - like the problem with the
original code and with the `read-char-exclusive' attempt I made first to fix it.
But no, it never even got to the `and' test of the `while': it seems to have
exited during `read-key'.

Perhaps you can suggest something I can do to determine what is happening that
causes it (presumably) to exit the `while' during the `read-key', jumping out to
the `unwind-protect'.  Is there some debug message I can put at the beginning of
the the `unwind-protect' protection code to see what happened?  Can I put some
debug stuff into `read-key'?

Coming back to my question -

I see no problems at all when I instead use the solution I sent, which uses
read-event instead of read-key.  It just works.

You still have not said anything about what's wrong with that solution.  If your
read-key solution worked I would not hesitate to say fine, let's go with it -
believe me.  But it doesn't.  If we can figure it out and fix it, I'm OK with
that.

I'm willing to try to help determine what's going wrong with the `read-key'
approach, if we can do that by just debugging the `repeat' code (as opposed to
my trying to narrow down my setup).

Again (coming back to my question), this is what I suggested:

(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))

It's pretty simple.  It also seems logical, and it says just what we want to be
done: if the event's components are all the same as before then repeat.  Dunno
why you have a problem with this.  What problems do you see with this approach?