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
|
;;; pita.el --- wrappers making emacs less of a PITA -*- lexical-binding: t -*-
;; 🥙
;;; utils
(defun walk-tree-replace (tree find replace)
(let ((r nil))
(dolist (form tree)
(push (cond ((eq find form) replace)
((listp form)
(walk-tree-replace form find replace))
(t form))
r))
(reverse r)))
;;; crux advices
;; these should all go :before the function they're advising.
(defun with-region-or-buffer (&rest _)
(interactive (if mark-active
(list (region-beginning) (region-end))
(list (point-min) (point-max)))))
(defun with-region-or-line (&rest _)
(interactive (if mark-active
(list (region-beginning) (region-end))
(list (line-beginning-position) (line-end-position)))))
(defun with-region-or-to-eol (&rest _)
(interactive (if mark-active
(list (region-beginning) (region-end))
(list (point) (line-end-position)))))
;;; wrappers
(defmacro with-message (msg &rest body)
(declare (indent 1))
(when (listp msg)
(setq msg (apply #'format (car msg) (cdr msg))))
(when (string-match "[[:alnum:]]\\'" msg)
(setq msg (concat msg "...")))
(let ((m (gensym))
(r (gensym)))
`(let ((,m ,msg)
(,r nil))
(condition-case e
(setq r (progn (message ,m) ,@body))
(:success (message "%s done" ,m) r)
(t (signal (car e) (cdr e)))))))
(defmacro with-pr (msg &rest body)
(declare (indent 1))
(when (listp msg)
(setq msg (apply #'format (car msg) (cdr msg))))
(when (string-match "[[:alnum:]]\\'" msg)
(setq msg (concat msg "...")))
(let ((pr (gensym))
(m (gensym)))
`(let* ((,m ,msg)
(,pr (unless (minibufferp)
(make-progress-reporter ,m))))
,@(or (and pr (walk-tree-replace body '@ `(progress-reporter-update ,pr)))
body)
(and ,pr (progress-reporter-done ,pr)))))
;;; wrapper advice
(provide 'pita)
;;; pita.el ends here
|