From: Juri Linkov <juri@linkov.net>
To: 46515@debbugs.gnu.org
Subject: bug#46515: Repeat mode
Date: Sun, 14 Feb 2021 20:27:08 +0200 [thread overview]
Message-ID: <87pn12o74z.fsf@mail.linkov.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 412 bytes --]
Tags: patch
Like discussed in bug#12572, bug#15234 and recently in
https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00139.html
here is a patch that provides an opt-in feature for easy-to-repeat
key sequences:
C-x u u u - undo sequences
C-x o o o - switch windows
C-x right left right left - next/previous buffer switching
M-g n n n p p p - next-error navigation
C-x { { { } } } - window resizing
...
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: repeat-mode.patch --]
[-- Type: text/x-diff, Size: 4760 bytes --]
diff --git a/lisp/repeat.el b/lisp/repeat.el
index 795577c93f..1b31963d22 100644
--- a/lisp/repeat.el
+++ b/lisp/repeat.el
@@ -329,6 +329,39 @@ repeat-message
;;;;; ************************* EMACS CONTROL ************************* ;;;;;
+\f
+;;; repeat-mode
+
+(defcustom repeat-exit-key [return] ; like `isearch-exit'
+ "Key that stops the modal repeating of keys in sequence."
+ :type '(choice (const :tag "No special key to exit repeat sequence" nil)
+ (key-sequence :tag "Key that exits repeat sequence"))
+ :group 'convenience
+ :version "28.1")
+
+;;;###autoload
+(define-minor-mode repeat-mode
+ "Toggle Repeat mode.
+When Repeat mode is enabled, and the command symbol has the property named
+`repeat-map', this map is activated temporarily for the next command."
+ :global t :group 'convenience
+ (if (not repeat-mode)
+ (remove-hook 'post-command-hook 'repeat-post-hook)
+ (add-hook 'post-command-hook 'repeat-post-hook)))
+
+(defun repeat-post-hook ()
+ "Function run after commands to set transient keymap."
+ (when repeat-mode
+ (let ((repeat-map (and (symbolp this-command)
+ (get this-command 'repeat-map))))
+ (when repeat-map
+ (when (boundp repeat-map)
+ (setq repeat-map (symbol-value repeat-map)))
+ (let ((map (copy-keymap repeat-map)))
+ (when repeat-exit-key
+ (define-key map repeat-exit-key 'ignore))
+ (set-transient-map map))))))
+
(provide 'repeat)
;;; repeat.el ends here
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 2f4bab11cf..70ddd9d9ba 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -950,6 +950,12 @@ global-map
;; Richard said that we should not use C-x <uppercase letter> and I have
;; no idea whereas to bind it. Any suggestion welcome. -stef
;; (define-key ctl-x-map "U" 'undo-only)
+(defvar undo-repeat-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "u" 'undo)
+ map)
+ "Keymap to repeat undo `C-x u u' sequences. Used in `repeat-mode'.")
+(put 'undo 'repeat-map 'undo-repeat-map)
(define-key esc-map "!" 'shell-command)
(define-key esc-map "|" 'shell-command-on-region)
@@ -964,6 +970,17 @@ ctl-x-map
(define-key global-map [XF86Back] 'previous-buffer)
(put 'previous-buffer :advertised-binding [?\C-x left])
+(defvar next-buffer-repeat-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [right] 'next-buffer)
+ (define-key map [C-right] 'next-buffer)
+ (define-key map [left] 'previous-buffer)
+ (define-key map [C-left] 'previous-buffer)
+ map)
+ "Keymap to repeat next-buffer key sequences. Used in `repeat-mode'.")
+(put 'next-buffer 'repeat-map 'next-buffer-repeat-map)
+(put 'previous-buffer 'repeat-map 'next-buffer-repeat-map)
+
(let ((map minibuffer-local-map))
(define-key map "\en" 'next-history-element)
(define-key map [next] 'next-history-element)
@@ -1036,6 +1053,17 @@ global-map
(define-key ctl-x-map "`" 'next-error)
+(defvar next-error-repeat-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "n" 'next-error)
+ (define-key map "\M-n" 'next-error)
+ (define-key map "p" 'previous-error)
+ (define-key map "\M-p" 'previous-error)
+ map)
+ "Keymap to repeat next-error key sequences. Used in `repeat-mode'.")
+(put 'next-error 'repeat-map 'next-error-repeat-map)
+(put 'previous-error 'repeat-map 'next-error-repeat-map)
+
(defvar goto-map (make-sparse-keymap)
"Keymap for navigation commands.")
(define-key esc-map "g" goto-map)
diff --git a/lisp/window.el b/lisp/window.el
index 2d0a73b426..d1a0f80da9 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -10252,6 +10252,30 @@ ctl-x-4-map
(define-key ctl-x-4-map "1" 'same-window-prefix)
(define-key ctl-x-4-map "4" 'other-window-prefix)
+(defvar other-window-repeat-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "o" 'other-window)
+ map)
+ "Keymap to repeat other-window key sequences. Used in `repeat-mode'.")
+
+(put 'other-window 'repeat-map 'other-window-repeat-map)
+
+(defvar resize-window-repeat-map
+ (let ((map (make-sparse-keymap)))
+ ;; Standard keys:
+ (define-key map "^" 'enlarge-window)
+ (define-key map "}" 'enlarge-window-horizontally)
+ (define-key map "{" 'shrink-window-horizontally)
+ ;; Additional keys:
+ (define-key map "v" 'shrink-window)
+ map)
+ "Keymap to repeat window resizing commands. Used in `repeat-mode'.")
+
+(put 'enlarge-window 'repeat-map 'resize-window-repeat-map)
+(put 'enlarge-window-horizontally 'repeat-map 'resize-window-repeat-map)
+(put 'shrink-window-horizontally 'repeat-map 'resize-window-repeat-map)
+(put 'shrink-window 'repeat-map 'resize-window-repeat-map)
+
(provide 'window)
;;; window.el ends here
next reply other threads:[~2021-02-14 18:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-14 18:27 Juri Linkov [this message]
2021-02-14 23:59 ` bug#46515: Repeat mode Matt Armstrong
2021-02-15 9:17 ` Juri Linkov
2021-02-15 17:04 ` Juri Linkov
2021-02-16 16:49 ` Matt Armstrong
2021-02-17 18:05 ` Juri Linkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pn12o74z.fsf@mail.linkov.net \
--to=juri@linkov.net \
--cc=46515@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).