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).
This commit is contained in:
Paul Nelson 2025-02-22 23:12:41 +01:00 committed by Juri Linkov
parent 3de9994b9e
commit 85a9b916db
4 changed files with 36 additions and 27 deletions

View file

@ -1653,8 +1653,9 @@ will be calculated based on the window width.
A command with this symbol property whose value is a list of repeat
maps will not activate the repeat map in 'repeat-mode'. It will only
continue the already activated repeating sequence. Also 'defvar-keymap'
supports a new keyword ':continue' with a list of commands that
only continue the active repeating sequence.
supports a new keyword ':continue' with a list of commands that only
continue the active repeating sequence, and the 'use-package' and
'bind-keys' macros supports a similar keyword ':continue-only'.
** New function 'completion-table-with-metadata'.
It offers a more concise way to create a completion table with metadata.

View file

@ -290,6 +290,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
@ -325,11 +328,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)))
@ -348,7 +348,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"))
@ -369,14 +369,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
@ -401,9 +401,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

View file

@ -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)))

View file

@ -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"