[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 9232c985ef3 1/3: Improve support of property repeat-continue-only
From: |
Juri Linkov |
Subject: |
master 9232c985ef3 1/3: Improve support of property repeat-continue-only in repeat-mode (bug#74140) |
Date: |
Tue, 17 Dec 2024 13:59:44 -0500 (EST) |
branch: master
commit 9232c985ef3d874755b0cbf4399fcc7077c308b5
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>
Improve support of property repeat-continue-only in repeat-mode (bug#74140)
* lisp/repeat.el (repeat-get-map): Add optional arg 'rep-map'.
Move the check for 'repeat-continue-only' from 'repeat-pre-hook'.
Improve its logic to check if the current map 'repeat-in-progress'
exists in the list from the 'repeat-continue-only' property.
(repeat-post-hook): Set 'repeat-in-progress' to the symbol
from the property 'repeat-map'.
* test/lisp/repeat-tests.el (repeat-tests-another-repeat-map):
Add new keymap to test multiple parallel repeat-maps.
(repeat-tests-continue-another): New test that uses commands
from 'repeat-tests-another-repeat-map' shared with
'repeat-tests-repeat-map'.
---
lisp/repeat.el | 66 ++++++++++++++++++++++++-----------------------
test/lisp/repeat-tests.el | 63 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 88 insertions(+), 41 deletions(-)
diff --git a/lisp/repeat.el b/lisp/repeat.el
index 45888d9db08..2328c05a652 100644
--- a/lisp/repeat.el
+++ b/lisp/repeat.el
@@ -453,10 +453,17 @@ See `describe-repeat-maps' for a list of all repeatable
commands."
(and (symbolp real-this-command)
(get real-this-command property))))
-(defun repeat-get-map ()
+(defun repeat-get-map (&optional rep-map)
"Return a transient map for keys repeatable after the current command."
(when repeat-mode
- (let ((rep-map (or repeat-map (repeat--command-property 'repeat-map))))
+ (let ((rep-map (or rep-map repeat-map (repeat--command-property
'repeat-map)))
+ (continue-only (repeat--command-property 'repeat-continue-only)))
+ (when continue-only
+ (if repeat-in-progress
+ (when (and (consp continue-only)
+ (memq repeat-in-progress continue-only))
+ (setq rep-map repeat-in-progress))
+ (setq rep-map nil)))
(when rep-map
(when (and (symbolp rep-map) (boundp rep-map))
(setq rep-map (symbol-value rep-map)))
@@ -501,37 +508,32 @@ See `describe-repeat-maps' for a list of all repeatable
commands."
(defun repeat-post-hook ()
"Function run after commands to set transient keymap for repeatable keys."
- (let ((was-in-progress repeat-in-progress))
+ (let* ((was-in-progress repeat-in-progress)
+ (map-sym (or repeat-map (repeat--command-property 'repeat-map)))
+ (map (repeat-get-map map-sym)))
(setq repeat-in-progress nil)
- (let ((map (repeat-get-map)))
- (when (and (repeat-check-map map)
- (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)
-
- ;; Adding an exit key
- (when repeat-exit-key
- (setq map (copy-keymap map))
- (define-key map (if (key-valid-p repeat-exit-key)
- (kbd repeat-exit-key)
- repeat-exit-key)
- 'ignore))
-
- (setq repeat-in-progress t)
- (repeat--clear-prev)
- (let ((exitfun (set-transient-map map)))
- (setq repeat--transient-exitfun exitfun)
-
- (let* ((prop (repeat--command-property 'repeat-exit-timeout))
- (timeout (unless (eq prop 'no) (or prop
repeat-exit-timeout))))
- (when timeout
- (setq repeat-exit-timer
- (run-with-idle-timer timeout nil #'repeat-exit)))))))
+ (when (repeat-check-map map)
+ ;; Messaging
+ (funcall repeat-echo-function map)
+
+ ;; Adding an exit key
+ (when repeat-exit-key
+ (setq map (copy-keymap map))
+ (define-key map (if (key-valid-p repeat-exit-key)
+ (kbd repeat-exit-key)
+ repeat-exit-key)
+ 'ignore))
+
+ (setq repeat-in-progress map-sym)
+ (repeat--clear-prev)
+ (let ((exitfun (set-transient-map map)))
+ (setq repeat--transient-exitfun exitfun)
+
+ (let* ((prop (repeat--command-property 'repeat-exit-timeout))
+ (timeout (unless (eq prop 'no) (or prop repeat-exit-timeout))))
+ (when timeout
+ (setq repeat-exit-timer
+ (run-with-idle-timer timeout nil #'repeat-exit))))))
(setq repeat-map nil)
(setq repeat--prev-mb (cons (minibuffer-depth) current-minibuffer-command))
diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el
index d69d431146a..4039a84c4d3 100644
--- a/test/lisp/repeat-tests.el
+++ b/test/lisp/repeat-tests.el
@@ -24,8 +24,8 @@
(require 'ert)
(require 'repeat)
-;; Key mnemonics: a - Activate (enter, also b), c - Continue (also d),
-;; o - continue-Only (not activate), q - Quit (exit)
+;; Key mnemonics: a - Activate (enter, also b, s), c - Continue (also d, t),
+;; o - continue-Only (not activate, also u), q - Quit (exit)
(defvar repeat-tests-calls nil)
@@ -53,13 +53,37 @@
(interactive "p")
(push `(,arg q) repeat-tests-calls))
+(defun repeat-tests-call-s (&optional arg)
+ (interactive "p")
+ (push `(,arg s) repeat-tests-calls))
+
+(defun repeat-tests-call-t (&optional arg)
+ (interactive "p")
+ (push `(,arg t) repeat-tests-calls))
+
+(defun repeat-tests-call-u (&optional arg)
+ (interactive "p")
+ (push `(,arg u) repeat-tests-calls))
+
;; Global keybindings
-(defvar-keymap repeat-tests-map
+(defvar-keymap repeat-tests-global-map
:doc "Keymap for keys that initiate repeating sequences."
"C-x w a" 'repeat-tests-call-a
"C-M-a" 'repeat-tests-call-a
"C-M-b" 'repeat-tests-call-b
- "C-M-o" 'repeat-tests-call-o)
+ "C-M-o" 'repeat-tests-call-o
+ "C-M-s" 'repeat-tests-call-s
+ "C-M-u" 'repeat-tests-call-u)
+
+(defvar-keymap repeat-tests-another-repeat-map
+ :doc "Keymap for repeating other sequences."
+ :repeat ( :enter (repeat-tests-call-s)
+ :continue-only (repeat-tests-call-o
+ repeat-tests-call-u))
+ "s" 'ignore ;; for non-nil repeat-check-key only
+ "t" 'repeat-tests-call-t
+ "C-M-o" 'repeat-tests-call-o
+ "C-M-u" 'repeat-tests-call-u)
(defvar-keymap repeat-tests-repeat-map
:doc "Keymap for repeating sequences."
@@ -99,7 +123,7 @@
(should (equal (buffer-string) inserted)))
(ert-deftest repeat-tests-check-key ()
- (with-repeat-mode repeat-tests-map
+ (with-repeat-mode repeat-tests-global-map
(let ((repeat-echo-function 'ignore))
(let ((repeat-check-key t))
(repeat-tests--check
@@ -131,7 +155,7 @@
(put 'repeat-tests-call-b 'repeat-check-key nil))))))
(ert-deftest repeat-tests-exit-command ()
- (with-repeat-mode repeat-tests-map
+ (with-repeat-mode repeat-tests-global-map
(let ((repeat-echo-function 'ignore))
;; 'c' doesn't continue since 'q' exited
(repeat-tests--check
@@ -139,7 +163,7 @@
'((1 a) (1 c) (1 d) (1 q)) "c"))))
(ert-deftest repeat-tests-exit-key ()
- (with-repeat-mode repeat-tests-map
+ (with-repeat-mode repeat-tests-global-map
(let ((repeat-echo-function 'ignore))
(let ((repeat-exit-key nil))
(repeat-tests--check
@@ -151,7 +175,7 @@
'((1 a) (1 c) (1 d) (1 c)) "z")))))
(ert-deftest repeat-tests-keep-prefix ()
- (with-repeat-mode repeat-tests-map
+ (with-repeat-mode repeat-tests-global-map
(let ((repeat-echo-function 'ignore))
(repeat-tests--check
"C-x w a c d c z"
@@ -179,7 +203,7 @@
;; TODO: :tags '(:expensive-test) for repeat-exit-timeout
(ert-deftest repeat-tests-continue-only ()
- (with-repeat-mode repeat-tests-map
+ (with-repeat-mode repeat-tests-global-map
(let ((repeat-echo-function 'ignore)
(repeat-check-key nil))
;; 'C-M-o' used as continue-only
@@ -191,6 +215,27 @@
"C-M-o c z"
'((1 o)) "cz"))))
+(ert-deftest repeat-tests-continue-another ()
+ (with-repeat-mode repeat-tests-global-map
+ (let ((repeat-echo-function 'ignore)
+ (repeat-check-key nil))
+ ;; First test without 'C-M-O'
+ (repeat-tests--check
+ "C-M-s t t z"
+ '((1 s) (1 t) (1 t)) "z")
+ ;; 'C-M-u' used as continue-only
+ (repeat-tests--check
+ "C-M-s t C-M-u t z"
+ '((1 s) (1 t) (1 u) (1 t)) "z")
+ ;; 'C-M-u' should not activate
+ (repeat-tests--check
+ "C-M-u t z"
+ '((1 u)) "tz")
+ ;; 'C-M-o' shared with another map should continue current map
+ (repeat-tests--check
+ "C-M-s t C-M-o t C-M-o t z"
+ '((1 s) (1 t) (1 o) (1 t) (1 o) (1 t)) "z"))))
+
(require 'use-package)