106 lines
3.0 KiB
Markdown
106 lines
3.0 KiB
Markdown
# 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:
|
|
|
|
```lisp
|
|
(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`:
|
|
|
|
```lisp
|
|
(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`:
|
|
|
|
```lisp
|
|
(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:
|
|
|
|
```lisp
|
|
(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`:
|
|
|
|
```lisp
|
|
(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:
|
|
|
|
- [repeaters.el](https://github.com/mmarshall540/repeaters)
|