-
-
Notifications
You must be signed in to change notification settings - Fork 106
/
consult-kmacro.el
91 lines (77 loc) · 3.44 KB
/
consult-kmacro.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
;;; consult-kmacro.el --- Provides the command `consult-kmacro' -*- lexical-binding: t -*-
;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Provides the command `consult-kmacro'. This is an extra package,
;; to allow lazy loading of kmacro.el. The `consult-kmacro' command
;; is autoloaded.
;;; Code:
(require 'consult)
(require 'kmacro)
(eval-when-compile (require 'subr-x))
(defvar consult-kmacro--history nil)
(defun consult-kmacro--candidates ()
"Return alist of kmacros and indices."
(thread-last
;; List of macros
(append (and last-kbd-macro (list (kmacro-ring-head))) kmacro-ring)
;; Emacs 29 uses OClosures. I like OClosures but it would have been better
;; if public APIs wouldn't change like that.
(mapcar (lambda (x)
(static-if (> emacs-major-version 28)
(list (kmacro--keys x) (kmacro--counter x) (kmacro--format x) x)
`(,@x ,x))))
;; Filter mouse clicks
(seq-remove (lambda (x) (seq-some #'mouse-event-p (car x))))
;; Format macros
(mapcar (pcase-lambda (`(,keys ,counter ,format ,km))
(propertize
(format-kbd-macro keys 1)
'consult--candidate km
'consult-kmacro--annotation
;; If the counter is 0 and the counter format is its default,
;; then there is a good chance that the counter isn't actually
;; being used. This can only be wrong when a user
;; intentionally starts the counter with a negative value and
;; then increments it to 0.
(cond
((not (equal format "%d")) ;; show counter for non-default format
(format " (counter=%d, format=%s) " counter format))
((/= counter 0) ;; show counter if non-zero
(format " (counter=%d)" counter))))))
(delete-dups)))
;;;###autoload
(defun consult-kmacro (arg)
"Run a chosen keyboard macro.
With prefix ARG, run the macro that many times.
Macros containing mouse clicks are omitted."
(interactive "p")
(let ((km (consult--read
(or (consult-kmacro--candidates)
(user-error "No keyboard macros defined"))
:prompt "Keyboard macro: "
:category 'consult-kmacro
:require-match t
:sort nil
:history 'consult-kmacro--history
:annotate
(lambda (cand)
(get-text-property 0 'consult-kmacro--annotation cand))
:lookup #'consult--lookup-candidate)))
;; Kmacros are lambdas (oclosures) on Emacs 29
(funcall (static-if (> emacs-major-version 28)
km
(kmacro-lambda-form km))
arg)))
(provide 'consult-kmacro)
;;; consult-kmacro.el ends here