summary refs log tree commit diff stats
path: root/lisp/acdw.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/acdw.el')
-rw-r--r--lisp/acdw.el80
1 files changed, 49 insertions, 31 deletions
diff --git a/lisp/acdw.el b/lisp/acdw.el index 6e298b2..75e1755 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el
@@ -1,7 +1,5 @@
1;;; acdw.el -- bits and bobs -*- lexical-binding: t; -*- 1;;; acdw.el -- bits and bobs -*- lexical-binding: t; -*-
2;; by C. Duckworth <acdw@acdw.net> 2;; by C. Duckworth <acdw@acdw.net>
3(provide 'acdw)
4
5(require 'cl-lib) 3(require 'cl-lib)
6 4
7;;; Define both a directory and a function expanding to a file in that directory 5;;; Define both a directory and a function expanding to a file in that directory
@@ -30,7 +28,6 @@ the filesystem, unless INHIBIT-MKDIR is non-nil."
30 28
31;;; Evaluating things after other things 29;;; Evaluating things after other things
32 30
33
34(defun eval-after-init (fn) 31(defun eval-after-init (fn)
35 "Evaluate FN after inititation, or now if Emacs is initialized. 32 "Evaluate FN after inititation, or now if Emacs is initialized.
36FN is called with no arguments." 33FN is called with no arguments."
@@ -78,12 +75,12 @@ Convenience wrapper around `define-key'."
78(unless (fboundp 'ensure-list) 75(unless (fboundp 'ensure-list)
79 ;; Just in case we're using an old version of Emacs. 76 ;; Just in case we're using an old version of Emacs.
80 (defun ensure-list (object) 77 (defun ensure-list (object)
81 "Return OBJECT as a list. 78 "Return OBJECT as a list.
82If OBJECT is already a list, return OBJECT itself. If it's 79If OBJECT is already a list, return OBJECT itself. If it's
83not a list, return a one-element list containing OBJECT." 80not a list, return a one-element list containing OBJECT."
84 (if (listp object) 81 (if (listp object)
85 object 82 object
86 (list object)))) 83 (list object))))
87 84
88(defun add-to-list* (lists &rest things) 85(defun add-to-list* (lists &rest things)
89 "Add THINGS to LISTS. 86 "Add THINGS to LISTS.
@@ -130,8 +127,8 @@ without any separator."
130Each feature of FEATURES can also be a list of the arguments to 127Each feature of FEATURES can also be a list of the arguments to
131pass to `require', which see." 128pass to `require', which see."
132 (condition-case e 129 (condition-case e
133 (dolist (feature features) 130 (dolist (feature features)
134 (apply #'require (ensure-list feature))) 131 (apply #'require (ensure-list feature)))
135 (:success (mapcar (lambda (f) (car (ensure-list f))) features)) 132 (:success (mapcar (lambda (f) (car (ensure-list f))) features))
136 (t (signal (car e) (cdr e))))) 133 (t (signal (car e) (cdr e)))))
137 134
@@ -153,22 +150,33 @@ pass to `require', which see."
153 (add-hook 'before-save-hook #',internal-name nil :local)) 150 (add-hook 'before-save-hook #',internal-name nil :local))
154 (add-hook ',hook #',external-name)))) 151 (add-hook ',hook #',external-name))))
155 152
156(defmacro setq-local-hook (hook &rest args) 153(defmacro setq-local-hook (hooks &rest args)
157 "Run `setq-local' on ARGS when running HOOK." 154 "Run `setq-local' on ARGS when running HOOKs."
155 ;; FIXME: this is pretty messy, i think...
156 ;; The settings should be stored in an alist so that they can be deduplicated
158 (declare (indent 1)) 157 (declare (indent 1))
159 (let ((fn (intern (format "%s-setq-local" hook)))) 158 `(progn
160 (when (and (fboundp fn) 159 ,@(cl-loop for hook in (ensure-list hooks)
161 (functionp fn)) 160 collect
162 (setf args (append (function-get fn 'setq-local-hook-settings) args))) 161 (let ((fn (intern (format "%s-setq-local" hook))))
163 (unless (and (< 0 (length args)) 162 (when (and (fboundp fn)
164 (zerop (mod (length args) 2))) 163 (functionp fn))
165 (user-error "Wrong number of arguments: %S" (length args))) 164 (setf args (append (function-get fn 'setq-local-hook-settings) args)))
166 `(progn 165 (unless (and (< 0 (length args))
167 (defun ,fn () 166 (zerop (mod (length args) 2)))
168 ,(format "Set local variables after `%s'." hook) 167 (user-error "Wrong number of arguments: %S" (length args)))
169 (setq-local ,@args)) 168 `(progn
170 (function-put ',fn 'setq-local-hook-settings ',args) 169 (defun ,fn ()
171 (add-hook ',hook #',fn)))) 170 ,(format "Set local variables after `%s'." hook)
171 (setq-local ,@args))
172 (function-put ',fn 'setq-local-hook-settings ',args)
173 (dolist (buf (buffer-list))
174 (with-current-buffer buf
175 (when (derived-mode-p
176 ',(intern (replace-regexp-in-string
177 "-hook" "" (format "%s" hook))))
178 (,fn))))
179 (add-hook ',hook #',fn))))))
172 180
173(defmacro with-message (message &rest body) 181(defmacro with-message (message &rest body)
174 "Execute BODY, with MESSAGE. 182 "Execute BODY, with MESSAGE.
@@ -182,6 +190,13 @@ If body executes without errors, MESSAGE...Done will be displayed."
182 (:success (message "%s...done" ,msg)) 190 (:success (message "%s...done" ,msg))
183 (t (signal (car e) (cdr e))))))) 191 (t (signal (car e) (cdr e)))))))
184 192
193(defmacro either (&rest clauses)
194 "Return the first of CLAUSES that returns non-nil."
195 (let* ((this (gensym "either")))
196 (unless (null clauses)
197 `(let* ((,this ,(car clauses)))
198 (if ,this ,this (either ,@(cdr clauses)))))))
199
185;; https://emacs.stackexchange.com/a/39324/37239 200;; https://emacs.stackexchange.com/a/39324/37239
186;; XXX: This shit don't work rn 201;; XXX: This shit don't work rn
187(defun ignore-invisible-overlays (fn) 202(defun ignore-invisible-overlays (fn)
@@ -189,13 +204,13 @@ If body executes without errors, MESSAGE...Done will be displayed."
189FN should return a point." 204FN should return a point."
190 (let ((overlay nil) 205 (let ((overlay nil)
191 (point nil)) 206 (point nil))
192 (setq point (and (funcall fn) (point))) 207 (setq point (and (funcall fn) (point)))
193 (setq overlay (car (overlays-at (point)))) 208 (setq overlay (car (overlays-at (point))))
194 (while (and overlay (member 'invisible (overlay-properties overlay))) 209 (while (and overlay (member 'invisible (overlay-properties overlay)))
195 (goto-char (overlay-end overlay)) 210 (goto-char (overlay-end overlay))
196 (setq point (and (funcall fn) (point))) 211 (setq point (and (funcall fn) (point)))
197 (setq overlay (car (overlays-at (point))))) 212 (setq overlay (car (overlays-at (point)))))
198 point)) 213 point))
199 214
200;;; Extras 215;;; Extras
201;; Trying to avoid a whole install of crux ... 216;; Trying to avoid a whole install of crux ...
@@ -217,3 +232,6 @@ When called with prefix ARG, unconditionally switch buffer."
217 (if (or arg (one-window-p)) 232 (if (or arg (one-window-p))
218 (switch-to-buffer (other-buffer) nil t) 233 (switch-to-buffer (other-buffer) nil t)
219 (other-window 1))) 234 (other-window 1)))
235
236(provide 'acdw)
237;;; acdw.el ends here