Subject: bug#4081: closed (Re: bug#10459: Overlay keymaps ignored until point is moved when overlay is created from timer)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 05 Oct 2014 01:22:04 +0000

Your bug report

#10459: Overlay keymap and timers

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
10459: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10459
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#10459: Overlay keymaps ignored until point is moved when overlay is created from timer
From: Dmitry Gutov <[email-masked]>
To: Toby Cubitt <[email-masked]>
Cc: [email-masked], Stefan Monnier <[email-masked]>
Date: Sun, 05 Oct 2014 05:21:25 +0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Version: 24.4

> On Sun, Jan 08, 2012 at 10:52:54PM -0500, Stefan Monnier wrote:
>> Yes, this is a known limitation: the set of active keymaps is computed
>> before waiting for the next key sequence.

This has been fixed around the start of 24.4 development: the set of
keymaps is recomputed at the start of a key sequence.

The examples in this and merged bugs work for me now. Please feel free
to reopen if you see a case where the problem's not fixed.

Subject: Overlay keymap and timers
From: Mihai Bazon <[email-masked]>
To: [email-masked]
Date: Sat, 8 Aug 2009 12:24:51 +0300

Hi folks,

I identified a possible bug, just wondering if there's a known
workaround.  Please CC me in any reply as I'm not subscribed to the
list.

Short description
=================

    When creating overlays in a function called by run-with-timer,
    their keymap becomes available only *after* some key has been
    pressed.

Sample code
===========

    (setq counter 0)
    (setq my-keymap (make-sparse-keymap))
    (define-key my-keymap (kbd "M-n") 
      (lambda()
        (interactive)
        (message "Got it %s!" (setq counter (+ counter 1)))))
    
    (defun my-highlight ()
      (interactive)
      (save-excursion
        (beginning-of-buffer)
        (while (search-forward-regexp "\\<overlay\\>" nil t)
          (let ((overlay (make-overlay (- (point) 7) (point))))
            (overlay-put overlay 'face 'highlight)
            (overlay-put overlay 'evaporate t)
            ;; using 'local-map doesn't make any difference
            (overlay-put overlay 'keymap my-keymap)
            (overlay-put overlay 'my-property t)))))
    
    (defun my-highlight-with-timer ()
      (interactive)
      (run-with-timer 0.5 nil 'my-highlight))
    
    (defun my-highlight-clear ()
      (interactive)
      (remove-overlays (point-min) (point-max) 'my-property t))

Eval this code, then type "overlay" in some buffer and move the caret
somewhere in the middle of the word.

* Case 1.  M-x my-highlight.  The word gets colored.  If you press M-n,
  it will display "Got it 1!" in the minibuffer -- works as expected.

Now clear it with M-x my-highlight-clear.

* Case 2.  M-x my-highlight-with-timer.  After half a second, the word
  gets colored.  If we immediately press M-n now, we get "M-n is 
  undefined". However, pressing M-n a second time works.

Clear it again with my-highlight-clear.

* Case 3.  M-x my-highlight-with-timer, then press some key such as C-f
  (make sure the cursor doesn't leave the overlay).  Then pressing M-n
  works as expected.

My guess is that the keymap becomes active the moment a key is released
(?) (or in some post-command-hook?) and the cursor is within the
overlay.  So if set without a timer, it gets a chance to be activated
straight away, but with a timer there isn't any key release to trigger
it so it becomes active only after some key has been pressed.

Not sure if this is a bug, but it's sure annoying and I've no idea how
to work around it.  Any help is appreciated.

Cheers,
-Mihai