summary refs log tree commit diff stats
path: root/lisp/pita.el
blob: ed67c9294adb42b47e09081903f83acccc9f68fe (plain)
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