;;; 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