2

I wonder what is wrong with the following code?

(defvar my-forward-word-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "n") 'forward-word)
    (define-key map (kbd "p") 'my-backward-word)
    map))

(defvar my-backward-word-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "p") 'backward-word)
    (define-key map (kbd "n") 'my-forward-word)
    map))

(defun my-forward-word ()
  (interactive)
  (set-transient-map my-forward-word-map t))

(defun my-backward-word ()
  (interactive)
  (set-transient-map my-backward-word-map t))

(global-set-key (kbd "M-n") 'my-forward-word)
(global-set-key (kbd "M-p") 'my-backward-word)

There is a buffer with the text: |Hello world. | - this is cursor.

I press M-n, n. I get Hello| world as I expected.

Then I press p, p. I get |Hello world as was previously. And that's fine.

But when I press n again nothing happens i.e. cursor doesn't change its position no matter how many time I press n.

After n and n I expected to get Hello| world.

What's wrong?

$ emacs --version
GNU Emacs 24.4.1

1 Answer 1

1

It looks like a bug, to me. Adding some debug message calls, I see that the first n (after p p), correctly calls my-forward-word, but the second n then is interpreted in my-backward-word-map, not in my-forward-word-map.

IOW, the call in my-forward-word of (set-transient-map my-forward-word-map t) seems to have no effect.

(And you get the same behavior if you bind M-n instead of n and M-p instead of p, in the transient maps; IOW, if you try to use only M-n and M-p.)

Unless someone points out something we're missing, you might consider filing a bug report: M-x report-emacs-bug.


Yes, I'd say that it is definitely a bug. I just tried it in Emacs 24.3, for which the function was named set-temporary-overlay-map instead of set-transient-map, and there it works. So this is apparently a regression, introduced in Emacs 24.4.

Please file a bug report.

13
  • I don't think it's a bug. The second arg to set-transient-map (which is t here) means to keep the map active as long as the user hits keys in the map, so we end up activing both maps and then activating them commulatively, which is not going to work right.
    – Stefan
    Commented Mar 29, 2015 at 4:30
  • @Stefan If this is not explained anywhere, then it's at least a documentation bug.
    – Malabarba
    Commented Mar 29, 2015 at 10:41
  • It is explained in the docstring, AFAIK.
    – Stefan
    Commented Mar 29, 2015 at 14:23
  • @Stefan. I see. t meaning keep is of course documented. But activating the map (hence both maps apparently, in this case) seems quite a different verb from setting the transient map. Apparently now that phrase means activating a transient map*? So there can be more than one "transient" map? And in that case this seems like an incompatible change, which presumably should have been documented in the NEWS for Emacs 24.4. Emacs 24.3 does not behave this way, in any case. Could you perhaps give a use case for multiple active transient maps?
    – Drew
    Commented Mar 29, 2015 at 14:28
  • Typical case for having multiple transient maps: the above example with M-n n C-u 5 n. The C-u now uses set-transient-map.
    – Stefan
    Commented Mar 29, 2015 at 14:34

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.