Easily define repeat-maps for Emacs.
Go to file
Case Duckworth 578c540e12 Fix quoting bugs (merge) 2021-09-07 18:25:10 -05:00
README.md Fix typo 2021-09-07 18:10:08 -05:00
define-repeat-map.el Fix quoting bugs (merge) 2021-09-07 18:25:10 -05:00

README.md

define-repeat-map.el

Easily define repeat-maps

Emacs 28 comes built-in with repeat.el (which see), which allows users to define their own maps to repeat common commands easily. This package attempts to make the definition of those maps a one-sexp affair, through the macro `define-repeat-map'. See its docstring for details.

The problem

Most of the time, defining a repeat-map and adding commands to keys is a multi-step affair, involving something like the following:

(defvar other-window-repeat-map (make-sparse-keymap)
      "A map for repeating `other-window' keys.")
    
(define-key other-window-repeat-map "o" #'other-window)

(put 'other-window 'repeat-map 'other-window-repeat-map))

With more keys, it gets more complex; there has to be a better way!

Enter define-repeat-map

With this macro, you can easily define these maps, and bind keys to them, using only one form. The code above looks like this with define-repeat-map:

(define-repeat-map other-window
    ("o" other-window))

Which isn't so much more convenient, but the convenience compounds with more complex maps. For example, here's a snippet from my init.el, pre-define-repeat-map:

(defalias 'forward-word-with-case 'forward-word
  "Alias for `forward-word' for use in `case-repeat-map'.")
(defalias 'backward-word-with-case 'backward-word
  "Alias for `backward-word for use in `case-repeat-map'.")

(defvar case-repeat-map
  (let ((map (make-sparse-keymap)))
    (define-key map "c" #'capitalize-word)
    (define-key map "u" #'upcase-word)
    (define-key map "l" #'downcase-word)
    ;; movement
    (define-key map "f" #'forward-word-with-case)
    (define-key map "b" #'backward-word-with-case)
    map)
  "A map to repeat word-casing commands.  For use with `repeat-mode'.")
  
(dolist (command '(capitalize-word
                   capitalize-dwim
                   upcase-word
                   upcase-dwim
                   downcase-word
                   downcase-dwim
                   forward-word-with-case
                   backward-word-with-case))
  (put command 'repeat-map 'case-repeat-map))

And here it is using this macro:

(define-repeat-map case
  ("c" capitalize-word
   "u" upcase-word
   "l" downcase-word)
  (:continue "f" forward-word
             "b" backward-word)
  (:enter downcase-dwim
          upcase-dwim
          capitalize-dwim))

Much easier, in this author's humble opinion.

Install

This package is not currently on MELPA or anywhere, so either git clone this repo and add it to your load-path and require it, or use some other installation method.

I use straight.el:

(straight-use-package
 '(define-repeat-map
   :host nil
   :repo "https://tildegit.org/acdw/define-repeat-map.el"))

Similar packages

I've found one other package that tries to simplify repeat-map definition, but it's not quite as flexible as this. In fact, that's why I wrote define-repeat-map. But here's the other: