diff options
Diffstat (limited to 'lisp/acdw.el')
-rw-r--r-- | lisp/acdw.el | 80 |
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. |
36 | FN is called with no arguments." | 33 | FN 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. |
82 | If OBJECT is already a list, return OBJECT itself. If it's | 79 | If OBJECT is already a list, return OBJECT itself. If it's |
83 | not a list, return a one-element list containing OBJECT." | 80 | not 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." | |||
130 | Each feature of FEATURES can also be a list of the arguments to | 127 | Each feature of FEATURES can also be a list of the arguments to |
131 | pass to `require', which see." | 128 | pass 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." | |||
189 | FN should return a point." | 204 | FN 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 | ||