From: Juri Linkov Date: Tue, 18 May 2021 21:02:42 +0000 (+0300) Subject: * lisp/repeat.el (repeat-exit-timeout): New defcustom (bug#48472). X-Git-Tag: emacs-28.0.90~2420 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0fa959db203f9d6c2d09cb1e026b5b99a5274e79;p=emacs.git * lisp/repeat.el (repeat-exit-timeout): New defcustom (bug#48472). (repeat-exit-timer): New variable. (repeat-post-hook): Run idle timer with an "exit function" returned from set-transient-map. Suggested by Gustavo Barros . (repeat-echo-message): Remove own previous message when input arg is nil. * lisp/window.el (display-buffer-override-next-command): Return exitfun. --- diff --git a/lisp/repeat.el b/lisp/repeat.el index b7118cc7f95..46c880d0dde 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -338,10 +338,22 @@ recently executed command not bound to an input event\"." "Key that stops the modal repeating of keys in sequence. For example, you can set it to like `isearch-exit'." :type '(choice (const :tag "No special key to exit repeating sequence" nil) - (key-sequence :tag "Key that exits repeating sequence")) + (key-sequence :tag "Key that exits repeating sequence")) :group 'convenience :version "28.1") +(defcustom repeat-exit-timeout nil + "Break the repetition chain of keys after specified timeout. +When a number, exit the repeat mode after idle time of the specified +number of seconds." + :type '(choice (const :tag "No timeout to exit repeating sequence" nil) + (number :tag "Timeout in seconds to exit repeating")) + :group 'convenience + :version "28.1") + +(defvar repeat-exit-timer nil + "Timer activated after the last key typed in the repeating key sequence.") + (defcustom repeat-keep-prefix t "Keep the prefix arg of the previous command." :type 'boolean @@ -420,16 +432,32 @@ When Repeat mode is enabled, and the command symbol has the property named (setq prefix-arg current-prefix-arg)) (setq repeat-in-progress t) - (set-transient-map map)))))) + (let ((exitfun (set-transient-map map))) + + (when repeat-exit-timer + (cancel-timer repeat-exit-timer) + (setq repeat-exit-timer nil)) + + (when repeat-exit-timeout + (setq repeat-exit-timer + (run-with-idle-timer + repeat-exit-timeout nil + (lambda () + (setq repeat-in-progress nil) + (funcall exitfun) + (funcall repeat-echo-function nil))))))))))) (setq repeat-map nil) (when (and was-in-progress (not repeat-in-progress)) + (when repeat-exit-timer + (cancel-timer repeat-exit-timer) + (setq repeat-exit-timer nil)) (funcall repeat-echo-function nil)))) -(defun repeat-echo-message-string (map) +(defun repeat-echo-message-string (keymap) "Return a string with a list of repeating keys." (let (keys) - (map-keymap (lambda (key _) (push key keys)) map) + (map-keymap (lambda (key _) (push key keys)) keymap) (format-message "Repeat with %s%s" (mapconcat (lambda (key) (key-description (vector key))) @@ -439,21 +467,23 @@ When Repeat mode is enabled, and the command symbol has the property named (key-description repeat-exit-key)) "")))) -(defun repeat-echo-message (map) +(defun repeat-echo-message (keymap) "Display available repeating keys in the echo area." - (when map - (let ((mess (repeat-echo-message-string map))) - (if (current-message) - (message "%s [%s]" (current-message) mess) - (message mess))))) + (if keymap + (let ((mess (repeat-echo-message-string keymap))) + (if (current-message) + (message "%s [%s]" (current-message) mess) + (message mess))) + (when (string-prefix-p "Repeat with " (current-message)) + (message nil)))) (defvar repeat-echo-mode-line-string (propertize "[Repeating...] " 'face 'mode-line-emphasis) "String displayed in the mode line in repeating mode.") -(defun repeat-echo-mode-line (map) +(defun repeat-echo-mode-line (keymap) "Display the repeat indicator in the mode line." - (if map + (if keymap (unless (assq 'repeat-in-progress mode-line-modes) (add-to-list 'mode-line-modes (list 'repeat-in-progress repeat-echo-mode-line-string))) diff --git a/lisp/window.el b/lisp/window.el index 026cde5901c..5a307136662 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8634,7 +8634,9 @@ meaning of these values in `window--display-buffer'. Optional `post-function' is called after the buffer is displayed in the window; the function takes two arguments: an old and new window. Optional string argument `echo' can be used to add a prefix to the -command echo keystrokes that should describe the current prefix state." +command echo keystrokes that should describe the current prefix state. +This returns an \"exit function\", which can be called with no argument +to deactivate this overriding action." (let* ((old-window (or (minibuffer-selected-window) (selected-window))) (new-window nil) (minibuffer-depth (minibuffer-depth)) @@ -8676,7 +8678,8 @@ command echo keystrokes that should describe the current prefix state." (add-hook 'post-command-hook clearfun) (when echofun (add-hook 'prefix-command-echo-keystrokes-functions echofun)) - (push action (car display-buffer-overriding-action)))) + (push action (car display-buffer-overriding-action)) + exitfun)) (defun set-window-text-height (window height)