From e69b083088f3edd67831a42d3115cccec75437f6 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Tue, 3 Dec 2024 20:12:03 +0200 Subject: [PATCH] Add new keyword :continue-only to defvar-keymap for repeat-mode (bug#74140) * doc/lispref/keymaps.texi (Creating Keymaps): Add :continue-only to :repeat part of defvar-keymap. * lisp/keymap.el (defvar-keymap): Add support for new :repeat keyword :continue-only. * lisp/repeat.el (repeat-post-hook): The property 'repeat-continue-only' is handled as a list of repeat-maps. * test/lisp/repeat-tests.el (repeat-tests-repeat-map): Use new :repeat keyword :continue-only. (cherry picked from commit 69e1f787528eaf2f223c53a6ff518ba4f984bc17) --- doc/lispref/keymaps.texi | 7 ++++++- etc/NEWS | 9 ++++++--- lisp/keymap.el | 9 +++++++++ lisp/repeat.el | 8 ++++++-- test/lisp/repeat-tests.el | 11 ++++------- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 2f9529a2a18..87723720b1e 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -480,7 +480,8 @@ following values are available: This means all the commands in the keymap are repeatable, and is the most common usage. -@item (:enter (commands ...) :exit (commands ...) :hints ((command . "hint") ...)) +@item (:enter (commands ...) :exit (commands ...) +@itemx :continue-only (commands ...) :hints ((command . "hint") ...)) This specifies that the commands in the @code{:enter} list enter @code{repeat-mode}, and the commands in the @code{:exit} list exit repeat mode. @@ -495,6 +496,10 @@ If the @code{:exit} list is empty then no commands in the map exit useful if the keymap being defined contains a command that should not have the @code{repeat-map} property. +The @code{:continue-only'} list specifies the commands that should not +enter @code{repeat-mode}. These command should only continue the +already activated repeating sequence. + The @code{:hints} list can contain cons pairs where the @sc{car} is a command and the @sc{cdr} is a string that is displayed alongside of the repeatable key in the echo area. diff --git a/etc/NEWS b/etc/NEWS index 10f1f912de6..9985451e3fd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -814,10 +814,13 @@ provide a ':columns' spec, so that the number of columns and their widths can be determined. Columns widths can be set explicitly, or they will be calculated based on the window width. ++++ ** New symbol property 'repeat-continue-only' for 'repeat-mode'. -A command with this symbol property whose value is non-nil will not -activate the repeat map in 'repeat-mode', it will only continue the -already activated repeating sequence. +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-only' with a list of commands that +only continue the active repeating sequence. * Changes in Emacs 31.1 on Non-Free Operating Systems diff --git a/lisp/keymap.el b/lisp/keymap.el index abb293e7f23..4cb4d40635c 100644 --- a/lisp/keymap.el +++ b/lisp/keymap.el @@ -679,6 +679,7 @@ value can also be a property list with properties `:enter', `:exit' and `:hints', for example: :repeat (:enter (commands ...) :exit (commands ...) + :continue-only (commands ...) :hints ((command . \"hint\") ...)) `:enter' specifies the list of additional commands that only @@ -694,6 +695,10 @@ Specifying a list of commands is useful when those commands exist in this specific map, but should not have the `repeat-map' symbol property. +`:continue-only' specifies the list of commands that should not +enter `repeat-mode'. These command should only continue the +already activated repeating sequence. + `:hints' is a list of cons pairs where car is a command and cdr is a string that is displayed alongside of the repeatable key in the echo area. @@ -732,6 +737,10 @@ in the echo area. def) (dolist (def (plist-get repeat :enter)) (push `(put ',def 'repeat-map ',variable-name) props)) + (dolist (def (plist-get repeat :continue-only)) + (push `(put ',def 'repeat-continue-only + (cons ',variable-name (get ',def 'repeat-continue-only))) + props)) (while defs (pop defs) (setq def (pop defs)) diff --git a/lisp/repeat.el b/lisp/repeat.el index 6b0c69905d8..cea54b75868 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -504,8 +504,12 @@ See `describe-repeat-maps' for a list of all repeatable commands." (setq repeat-in-progress nil) (let ((map (repeat-get-map))) (when (and (repeat-check-map map) - (or (null (repeat--command-property 'repeat-continue-only)) - was-in-progress)) + (let ((continue-only (repeat--command-property 'repeat-continue-only))) + (or (null continue-only) + (and (or (not (consp continue-only)) + (memq (repeat--command-property 'repeat-map) + continue-only)) + was-in-progress)))) ;; Messaging (funcall repeat-echo-function map) diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el index c560a283039..d69d431146a 100644 --- a/test/lisp/repeat-tests.el +++ b/test/lisp/repeat-tests.el @@ -63,17 +63,15 @@ (defvar-keymap repeat-tests-repeat-map :doc "Keymap for repeating sequences." - :repeat ( :enter (repeat-tests-call-a) - :exit (repeat-tests-call-q)) + :repeat ( :enter (repeat-tests-call-a) + :continue-only (repeat-tests-call-o) + :exit (repeat-tests-call-q)) "a" 'ignore ;; for non-nil repeat-check-key only "c" 'repeat-tests-call-c "d" 'repeat-tests-call-d "C-M-o" 'repeat-tests-call-o "q" 'repeat-tests-call-q) -;; TODO: add new keyword ':continue-only (repeat-tests-call-o)' -(put 'repeat-tests-call-o 'repeat-continue-only t) - ;; Test using a variable instead of the symbol: (put 'repeat-tests-call-b 'repeat-map repeat-tests-repeat-map) @@ -228,8 +226,7 @@ ;; :continue-only ("C-M-o" . repeat-tests-bind-call-o) :exit - ("q" . repeat-tests-bind-call-q) - ) + ("q" . repeat-tests-bind-call-q)) ;; TODO: it seems there is no :entry, so need to do explicitly: (put 'repeat-tests-bind-call-a 'repeat-map 'repeat-tests-bind-keys-repeat-map) -- 2.39.2