From 55962fcaf4f2b02a79f2644916af9bdaa8dca608 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Fri, 3 Sep 2021 12:24:38 -0500 Subject: Add `clone-buffer-write-file' and sort --- lisp/acdw.el | 96 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/lisp/acdw.el b/lisp/acdw.el index ded65f8..8db7fea 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el @@ -50,6 +50,57 @@ ARG). When called with multiple arguments or a list, it returns ;; I don't prefix these because ... reasons. Honestly I probably should prefix ;; them. +;; Why isn't this a thing??? +(defmacro fbound-and-true-p (func) + "Return the value of function FUNC if it is bound, else nil." + `(and (fboundp ,func) ,func)) + +(defmacro when-unfocused (name &rest forms) + "Define a function NAME, executing FORMS, that fires when Emacs +is unfocused." + (declare (indent 1)) + (let ((func-name (intern (concat "when-unfocused-" (symbol-name name))))) + `(progn + (defun ,func-name () "Defined by `when-unfocused'." + (when (seq-every-p #'null + (mapcar #'frame-focus-state (frame-list))) + ,@forms)) + (add-function :after after-focus-change-function #',func-name)))) + +(defmacro with-eval-after-loads (files &rest body) + "Execute BODY after FILES are loaded. +This macro simplifies `with-eval-after-load' for multiple nested +features." + (declare (indent 1) (debug (form def-body))) + (waterfall-list 'with-eval-after-load files body)) + +(defmacro with-message (message &rest body) + "Execute BODY, messaging 'MESSAGE...' before and 'MESSAGE... Done.' after." + (declare (indent 1)) + ;; Wrap a progn inside a prog1 to return the return value of the body. + `(prog1 + (progn (message "%s..." ,message) + ,@body) + (message "%s... Done." ,message))) + +(defun clone-buffer-write-file (filename &optional confirm) + "Clone current buffer to a file named FILENAME and switch. +FILENAME and CONFIRM are passed directly to `write-file'." + (interactive ; stolen from `write-file' + (list (if buffer-file-name + (read-file-name "Write file: " + nil nil nil nil) + (read-file-name "Write file: " default-directory + (expand-file-name + (file-name-nondirectory (buffer-name)) + default-directory) + nil nil)) + (not current-prefix-arg))) + (let ((buf (clone-buffer nil nil))) + (with-current-buffer buf + (write-file filename confirm)) + (switch-to-buffer buf))) + (defun dos2unix (buffer) "Replace \r\n with \n in BUFFER." (interactive "*b") @@ -66,11 +117,6 @@ ARG). When called with multiple arguments or a list, it returns file nil))) -;; Why isn't this a thing??? -(defmacro fbound-and-true-p (func) - "Return the value of function FUNC if it is bound, else nil." - `(and (fboundp ,func) ,func)) - (defun kill-region-or-backward-word (arg) "Kill region if active, or backward word if not." (interactive "p") @@ -80,6 +126,12 @@ ARG). When called with multiple arguments or a list, it returns (paredit-backward-kill-word) (backward-kill-word arg)))) +(defun unfill-buffer (&optional buffer-or-name) + (with-current-buffer (or buffer-or-name (current-buffer)) + (save-excursion + (save-restriction + (unfill-region (point-min) (point-max)))))) + ;; https://www.emacswiki.org/emacs/UnfillRegion (defun unfill-region (start end) "Unfill a region defined by START and END positions." @@ -88,40 +140,6 @@ ARG). When called with multiple arguments or a list, it returns (emacs-lisp-docstring-fill-column t)) (fill-region start end))) -(defun unfill-buffer (&optional buffer-or-name) - (with-current-buffer (or buffer-or-name (current-buffer)) - (save-excursion - (save-restriction - (unfill-region (point-min) (point-max)))))) - -(defmacro when-unfocused (name &rest forms) - "Define a function NAME, executing FORMS, that fires when Emacs -is unfocused." - (declare (indent 1)) - (let ((func-name (intern (concat "when-unfocused-" (symbol-name name))))) - `(progn - (defun ,func-name () "Defined by `when-unfocused'." - (when (seq-every-p #'null - (mapcar #'frame-focus-state (frame-list))) - ,@forms)) - (add-function :after after-focus-change-function #',func-name)))) - -(defmacro with-message (message &rest body) - "Execute BODY, messaging 'MESSAGE...' before and 'MESSAGE... Done.' after." - (declare (indent 1)) - ;; Wrap a progn inside a prog1 to return the return value of the body. - `(prog1 - (progn (message "%s..." ,message) - ,@body) - (message "%s... Done." ,message))) - -(defmacro with-eval-after-loads (files &rest body) - "Execute BODY after FILES are loaded. -This macro simplifies `with-eval-after-load' for multiple nested -features." - (declare (indent 1) (debug (form def-body))) - (waterfall-list 'with-eval-after-load files body)) - (defun waterfall-list (car list rest) "Cons CAR with each element in LIST in a waterfall fashion, end with REST. For use with the `with-eval-after-loads' function." -- cgit 1.4.1-21-gabe81