Subject: Re: bug#9406: 24.0.50; Use M-p/M-n to navigate through the kill ring

From: Stefan Monnier <[email-masked]>
Date: Wed, 31 Aug 2011 09:01:04 -0400

Basically it would amount to moving the M-y binding to M-p but only if
used immediately after C-y, and to add a M-n binding to the same command
but that cycles in the other direction.

That doesn't sound like a bad idea, although of course it will annoy
a few users in a few corner cases (e.g. I have M-n and M-p bound in
smerge-mode).  So we might prefer to have it as an option.

> I'm not an expert in Emacs' internals, but I think that one way of
> implementing this would be as a minor mode, that would be activated by
> C-y (like Isearch is activated by C-s), and deactivated by "anything
> else" (distinct from M-p M-n and M-y*).

I use the function below to do these kinds of things.  I didn't find the
time to install it for Emacs-24.1, tho.
You should be able to get this working fairly cleanly with an
after-advice on `yank' which uses that set-temporary-overlay-map.

> (*) The behavior of M-y would remain the same, obviously, for old-timers.

Actually one of the benefits of your proposal is that it opens up the
possibility of freeing the M-y binding.

        Stefan

(defun set-temporary-overlay-map (map &optional keep-pred)
  (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map"))
         (overlaysym (make-symbol "t"))
         (alist (list (cons overlaysym map)))
         (clearfun
          ;; FIXME: Use lexical-binding.
          `(lambda ()
             (unless ,(cond ((null keep-pred) nil)
                            ((eq t keep-pred)
                             `(eq this-command
                                  (lookup-key ',map
                                              (this-command-keys-vector))))
                            (t `(funcall ',keep-pred)))
               (remove-hook 'pre-command-hook ',clearfunsym)
               (setq emulation-mode-map-alists
                     (delq ',alist emulation-mode-map-alists))))))
    (set overlaysym overlaysym)
    (fset clearfunsym clearfun)
    (add-hook 'pre-command-hook clearfunsym)
    ;; FIXME: That's the keymaps with highest precedence, except for
    ;; the `keymap' text-property ;-(
    (push alist emulation-mode-map-alists)))