From 96b0f0b62d5684ebd36a4e3713e9ceaa9681557e Mon Sep 17 00:00:00 2001
From: Paul Nelson <ultrono@gmail.com>
Date: Thu, 31 Oct 2024 13:55:49 +0100
Subject: [PATCH] Add :continue-only directive to bind-keys and use-package

* lisp/bind-key.el (bind-key--make-continue-alias): New function.
(bind-keys-form): Use it.  Add :continue-only binding.

* lisp/use-package/use-package-bind-key.el
(use-package-normalize-binder): Add check for :continue-only.
---
 lisp/bind-key.el                         | 28 ++++++++++++++++--------
 lisp/use-package/use-package-bind-key.el |  5 ++---
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/lisp/bind-key.el b/lisp/bind-key.el
index 780314fecbd..16a4b46160a 100644
--- a/lisp/bind-key.el
+++ b/lisp/bind-key.el
@@ -266,6 +266,10 @@ bind-key*
   "Similar to `bind-key', but overrides any mode-specific bindings."
   `(bind-key ,key-name ,command override-global-map ,predicate))
 
+(defun bind-key--make-continue-alias (cmd map)
+  "Make an alias for CMD that can continue MAP but not enter it."
+  (intern (concat (symbol-name cmd) "|" (symbol-name map))))
+
 (defun bind-keys-form (args keymap)
   "Bind multiple keys at once.
 
@@ -290,6 +294,10 @@ bind-keys-form
                          same behavior as if no special keyword had
                          been used (that is, the command is bound, and
                          it's `repeat-map' property set)
+:continue-only BINDINGS - Within the scope of `:repeat-map' will bind an
+                         alias of the command in the repeat map, but not
+                         set the `repeat-map' property of the original
+                         command.
 :filter FORM           - optional form to determine when bindings apply
 
 The rest of the arguments are conses of keybinding string and a
@@ -325,11 +333,8 @@ bind-keys-form
                                          override-global-map))))
                    (setq repeat-map (cadr args))
                    (setq map repeat-map))
-                  ((eq :continue (car args))
-                   (setq repeat-type :continue
-                         arg-change-func 'cdr))
-                  ((eq :exit (car args))
-                   (setq repeat-type :exit
+                  ((memq (car args) '(:continue :continue-only :exit))
+                   (setq repeat-type (car args)
                          arg-change-func 'cdr))
                   ((eq :prefix (car args))
                    (setq prefix (cadr args)))
@@ -348,7 +353,7 @@ bind-keys-form
 
     (when repeat-type
       (unless repeat-map
-        (error ":continue and :exit require specifying :repeat-map")))
+        (error ":continue(-only) and :exit require specifying :repeat-map")))
 
     (when (and menu-name (not prefix))
       (error "If :menu-name is supplied, :prefix must be too"))
@@ -401,9 +406,14 @@ bind-keys-form
                           ;; Only needed in this branch, since when
                           ;; repeat-map is non-nil, map is always
                           ;; non-nil
-                          `(,@(when (and repeat-map (not (eq repeat-type :exit)))
-                                `((put ,fun 'repeat-map ',repeat-map)))
-                            (bind-key ,(car form) ,fun ,map ,filter))
+                          (if (eq repeat-type :continue-only)
+                              (let ((alias (bind-key--make-continue-alias (cdr form) map)))
+                                `((defalias ',alias ,fun)
+                                  (put ',alias 'repeat-map ',map)
+                                  (bind-key ,(car form) ',alias ,map ,filter)))
+                            `(,@(when (and repeat-map (not (eq repeat-type :exit)))
+                                  `((put ,fun 'repeat-map ',repeat-map)))
+                              (bind-key ,(car form) ,fun ,map ,filter)))
                         `((bind-key ,(car form) ,fun nil ,filter))))))
                 first))
          (when next
diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el
index 18c3f29cf34..9733127413b 100644
--- a/lisp/use-package/use-package-bind-key.el
+++ b/lisp/use-package/use-package-bind-key.el
@@ -88,14 +88,13 @@ use-package-normalize-binder
          ;;   :filter SEXP
          ;;   :menu-name STRING
          ;;   :package SYMBOL
-	 ;;   :continue and :exit are used within :repeat-map
+	 ;;   :continue(-only) and :exit are used within :repeat-map
          ((or (and (eq x :map) (symbolp (cadr arg)))
               (and (eq x :prefix) (stringp (cadr arg)))
               (and (eq x :prefix-map) (symbolp (cadr arg)))
               (and (eq x :prefix-docstring) (stringp (cadr arg)))
 	      (and (eq x :repeat-map) (symbolp (cadr arg)))
-	      (eq x :continue)
-	      (eq x :exit)
+	      (memq x '(:continue :continue-only :exit))
               (and (eq x :repeat-docstring) (stringp (cadr arg)))
               (eq x :filter)
               (and (eq x :menu-name) (stringp (cadr arg)))
-- 
2.39.3 (Apple Git-145)

