summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--init.el6
-rw-r--r--lisp/+kmacro.el69
2 files changed, 75 insertions, 0 deletions
diff --git a/init.el b/init.el index 961e90a..196792b 100644 --- a/init.el +++ b/init.el
@@ -288,6 +288,12 @@
288 (ibuffer-auto-mode +1) 288 (ibuffer-auto-mode +1)
289 (ibuffer-switch-to-saved-filter-groups "default")))) 289 (ibuffer-switch-to-saved-filter-groups "default"))))
290 290
291(setup kmacro
292 (:also-load +kmacro)
293 (with-eval-after-load '+kmacro
294 (+kmacro-recording-indicator-mode +1)
295 (+kmacro-block-undo-mode +1)))
296
291(setup magit 297(setup magit
292 ;; This setup is weird because of dependency issues 298 ;; This setup is weird because of dependency issues
293 (:straight (transient :host github :repo "magit/transient" :branch "master") 299 (:straight (transient :host github :repo "magit/transient" :branch "master")
diff --git a/lisp/+kmacro.el b/lisp/+kmacro.el new file mode 100644 index 0000000..2b2916f --- /dev/null +++ b/lisp/+kmacro.el
@@ -0,0 +1,69 @@
1;;; +kmacro.el -*- lexical-binding: t; -*-
2
3;;; Commentary:
4
5;; Many of these come from this Reddit thread:
6;; https://old.reddit.com/r/emacs/comments/rlli0u/whats_your_favorite_defadvice/
7
8;;; Code:
9
10(require 'kmacro)
11
12;; Indicate when a kmacro is being recorded in the mode-line
13
14(defface +kmacro-modeline nil
15 "Face when kmacro is active")
16
17(set-face-attribute '+kmacro-modeline nil
18 :background "Firebrick"
19 :box '(:line-width -1 :color "salmon"
20 :style released-button))
21
22(defun +kmacro-change-mode-line (&rest _)
23 "Remap the mode-line face when recording a kmacro."
24 (add-to-list 'face-remapping-alist '(mode-line . +kmacro-modeline)))
25
26(defun +kmacro-restore-mode-line (&rest _)
27 "Restore the mode-line face after kmacro is done recording."
28 (setf face-remapping-alist
29 (assoc-delete-all 'mode-line face-remapping-alist)))
30
31(define-minor-mode +kmacro-recording-indicator-mode
32 "Change the mode-line's face when recording a kmacro."
33 :lighter ""
34 :global t
35 (if +kmacro-recording-indicator-mode
36 (progn
37 (advice-add #'kmacro-start-macro :before #'+kmacro-change-mode-line)
38 (advice-add #'kmacro-keyboard-quit :after #'+kmacro-restore-mode-line)
39 (advice-add #'kmacro-end-macro :after #'+kmacro-restore-mode-line))
40 (+kmacro-restore-mode-line)
41 (advice-remove #'kmacro-start-macro #'+kmacro-change-mode-line)
42 (advice-remove #'kmacro-keyboard-quit #'+kmacro-restore-mode-line)
43 (advice-remove #'kmacro-end-macro #'+kmacro-restore-mode-line)))
44
45;; Undo keyboard macros in a single bound (like vi!)
46
47(defun +kmacro-block-undo (fn &rest args)
48 (let ((marker (prepare-change-group)))
49 (unwind-protect (apply fn args)
50 (undo-amalgamate-change-group marker))))
51
52(define-minor-mode +kmacro-block-undo-mode
53 "Undo kmacros all at once (like vi)."
54 :global t
55 :lighter " KUndo"
56 (if +kmacro-block-undo-mode
57 (dolist (fn '(kmacro-call-macro
58 kmacro-exec-ring-item
59 dot-mode-execute
60 apply-macro-to-region-lines))
61 (advice-add fn :around #'+kmacro-block-undo))
62 (dolist (fn '(kmacro-call-macro
63 kmacro-exec-ring-item
64 dot-mode-execute
65 apply-macro-to-region-lines))
66 (advice-remove fn #'+kmacro-block-undo))))
67
68(provide '+kmacro)
69;;; +kmacro.el ends here