(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)))
(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
(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)
(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."
(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
(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
'((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
'((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"
;; 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
"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"))))
+
\f
(require 'use-package)