From 50768c0addbcac9171269407f99c9c5738e5e891 Mon Sep 17 00:00:00 2001 From: Paul Nelson Date: Tue, 10 Jun 2025 09:21:52 +0200 Subject: [PATCH] Improve repeat-continue property handling * lisp/repeat.el (repeat-get-map-sym): Support 'repeat-continue' property value of t to continue any active repeat map (suggested by Karthik Chikmagalur ). Simplify logic so that repeat-continue does not interfere with repeat-map activation. (repeat-check-map): Allow commands with 'repeat-continue' property value of t to continue without checking the key. (repeat-mode): Update and tweak docstring. * lisp/bind-key.el (bind-keys-form): Update handling of ':continue-only' keyword: only add keymap to 'repeat-continue' if current value is a list. (bind-keys): Update documentation, mirroring bind-keys-form. * lisp/keymap.el (defvar-keymap): Update handling of ':continue' keyword: only add keymap to 'repeat-continue' if current value is a list. * test/lisp/repeat-tests.el (repeat-tests-continue) (repeat-tests-continue-another): Enable previously commented tests that now work correctly. * etc/NEWS: Update announcement of 'repeat-continue' (bug#78742). (cherry picked from commit 3a0def802cf576902faafde404d15f079786a2f8) --- lisp/bind-key.el | 15 ++++++++------- lisp/keymap.el | 6 ++++-- lisp/repeat.el | 29 +++++++++++++++++++---------- test/lisp/repeat-tests.el | 12 ++++++------ 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/lisp/bind-key.el b/lisp/bind-key.el index 27865415c58..2303f9399fd 100644 --- a/lisp/bind-key.el +++ b/lisp/bind-key.el @@ -404,13 +404,11 @@ function symbol (unquoted)." ;; repeat-map is non-nil, map is always ;; non-nil (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)))) + `((let ((cur (get ,fun 'repeat-continue))) + (when (and (listp cur) + (not (memq ',repeat-map cur))) + (put ,fun 'repeat-continue + (append cur (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))) @@ -448,6 +446,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 diff --git a/lisp/keymap.el b/lisp/keymap.el index dc9bd9a8e20..a0048817cfa 100644 --- a/lisp/keymap.el +++ b/lisp/keymap.el @@ -746,8 +746,10 @@ in the echo area. (dolist (def (plist-get repeat :enter)) (push `(put ',def 'repeat-map ',variable-name) props)) (dolist (def (plist-get repeat :continue)) - (push `(put ',def 'repeat-continue - (cons ',variable-name (get ',def 'repeat-continue))) + (push `(let ((val (get ',def 'repeat-continue))) + (when (listp val) + (put ',def 'repeat-continue + (cons ',variable-name val)))) props)) (while defs (pop defs) diff --git a/lisp/repeat.el b/lisp/repeat.el index 9a4336424be..191e335ae24 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -425,9 +425,18 @@ the map can't be set on the command symbol property `repeat-map'.") When Repeat mode is enabled, certain commands bound to multi-key sequences can be repeated by typing a single key, after typing the full key sequence once. -The commands which can be repeated like that are those whose symbol - has the property `repeat-map' which specifies a keymap of single -keys for repeating. + +The commands that can be repeated in this way are those whose symbols +have the `repeat-map' property, which specifies a keymap of single keys +for repeating. + +Normally, invoking a command outside that keymap terminates the +repeating sequence. However, if the command's `repeat-continue' +property is non-nil, it may instead continue the current repeating +sequence: if the property is a list of keymaps, then the command +continues when the current repeat map is in the list; if the property is +t, the command always continues the sequence. + See `describe-repeat-maps' for a list of all repeatable commands." :global t :group 'repeat (if (not repeat-mode) @@ -458,12 +467,11 @@ See `describe-repeat-maps' for a list of all repeatable commands." (when repeat-mode (let ((map-sym (or repeat-map (repeat--command-property 'repeat-map))) (continue (repeat--command-property 'repeat-continue))) - (when continue - (if repeat-in-progress - (when (and (consp continue) - (memq repeat-in-progress continue)) - (setq map-sym repeat-in-progress)) - (setq map-sym nil))) + (when (and repeat-in-progress + (or (eq continue t) + (and (consp continue) + (memq repeat-in-progress continue)))) + (setq map-sym repeat-in-progress)) map-sym))) (defun repeat-get-map (map) @@ -495,7 +503,8 @@ See `describe-repeat-maps' for a list of all repeatable commands." (eq (when-let ((win (active-minibuffer-window))) (window-buffer win)) (cdr repeat--prev-mb))) - (repeat-check-key last-command-event map))) + (or (eq (repeat--command-property 'repeat-continue) t) + (repeat-check-key last-command-event map)))) (defun repeat-pre-hook () "Function run before commands to handle repeatable keys." diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el index f96d8df2ebd..6bf9badf31d 100644 --- a/test/lisp/repeat-tests.el +++ b/test/lisp/repeat-tests.el @@ -224,9 +224,9 @@ "C-M-e c z" '((1 e)) "cz") ;; 'C-M-o' should also activate - ;; (repeat-tests--check - ;; "C-M-o c z" - ;; '((1 o) (1 c)) "z") + (repeat-tests--check + "C-M-o c z" + '((1 o) (1 c)) "z") ))) (ert-deftest repeat-tests-continue-another () @@ -246,9 +246,9 @@ "C-M-e t z" '((1 e)) "tz") ;; 'C-M-u' should also activate - ;; (repeat-tests--check - ;; "C-M-u t z" - ;; '((1 u) (1 t)) "z") + (repeat-tests--check + "C-M-u t z" + '((1 u) (1 t)) "z") ;; 'C-M-o' shared with another map should continue current map (repeat-tests--check "C-M-s t C-M-o C-M-o t z" -- 2.39.5