* lisp/repeat.el (repeat-get-map-sym): Support 'repeat-continue'
property value of t to continue any active repeat map (suggested
by Karthik Chikmagalur <karthikchikmagalur@gmail.com>).
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)
;; 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)))
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
(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)
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)
(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)
(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."
"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 ()
"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"