From 30b25af3a73d76268d51e2a3726a4607c0cdcc27 Mon Sep 17 00:00:00 2001 From: Paul Nelson Date: Sat, 22 Feb 2025 23:12:41 +0100 Subject: [PATCH] Add :continue-only directive to bind-keys and use-package * lisp/bind-key.el (bind-keys-form): Add :continue-only binding. Fix indentation. * lisp/use-package/use-package-bind-key.el (use-package-normalize-binder): Add check for :continue-only. * test/lisp/repeat-tests.el (repeat-tests-bind-keys): Enable (and correct) test for :continue-only (bug#74140). (cherry picked from commit 85a9b916db126add5a5e2bf4b2b9531ab998cad4) --- lisp/bind-key.el | 43 ++++++++++++++---------- lisp/use-package/use-package-bind-key.el | 7 ++-- test/lisp/repeat-tests.el | 8 ++--- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/lisp/bind-key.el b/lisp/bind-key.el index e5256368eaa..27865415c58 100644 --- a/lisp/bind-key.el +++ b/lisp/bind-key.el @@ -292,6 +292,9 @@ Accepts keyword arguments: 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 make + the command continue but not enter the repeat + map, via the `repeat-continue' property :filter FORM - optional form to determine when bindings apply The rest of the arguments are conses of keybinding string and a @@ -327,11 +330,8 @@ function symbol (unquoted)." 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))) @@ -350,7 +350,7 @@ function symbol (unquoted)." (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")) @@ -371,14 +371,14 @@ function symbol (unquoted)." (cl-flet ((wrap (map bindings) - (if (and map pkg (not (memq map '(global-map - override-global-map)))) - `((if (boundp ',map) - ,(macroexp-progn bindings) - (eval-after-load - ,(if (symbolp pkg) `',pkg pkg) - ',(macroexp-progn bindings)))) - bindings))) + (if (and map pkg (not (memq map '(global-map + override-global-map)))) + `((if (boundp ',map) + ,(macroexp-progn bindings) + (eval-after-load + ,(if (symbolp pkg) `',pkg pkg) + ',(macroexp-progn bindings)))) + bindings))) (append (when prefix-map @@ -403,9 +403,18 @@ function symbol (unquoted)." ;; 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) + `((unless (memq ',repeat-map + (or (get ,fun 'repeat-continue) + '())) + (put ,fun 'repeat-continue + (append (or (get ,fun 'repeat-continue) + '()) + (list ',repeat-map)))) + (bind-key ,(car form) ,fun ,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 396a1b3a2a1..19dc7e71f7a 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -88,14 +88,13 @@ deferred until the prefix key sequence is pressed." ;; :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) + (and (eq x :repeat-map) (symbolp (cadr arg))) + (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))) diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el index 8e564b3e081..bfa838d383b 100644 --- a/test/lisp/repeat-tests.el +++ b/test/lisp/repeat-tests.el @@ -269,7 +269,7 @@ ("C-M-a" . repeat-tests-bind-call-a) ("C-M-o" . repeat-tests-bind-call-o) :repeat-map repeat-tests-bind-keys-repeat-map - :continue + :continue-only ("c" . repeat-tests-bind-call-c) ;; :continue ("C-M-o" . repeat-tests-bind-call-o) @@ -287,9 +287,9 @@ "C-M-a c C-M-o c z" '((1 a) (1 c) (1 o) (1 c)) "z") ;; 'C-M-o' should not activate - ;; (repeat-tests--check - ;; "C-M-o c z" - ;; '((1 o)) "cz") + (repeat-tests--check + "C-M-o c z" + '((1 o)) "cz") ;; 'q' should exit (repeat-tests--check "C-M-a c q c" -- 2.39.5