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.el119
1 files changed, 116 insertions, 3 deletions
diff --git a/lisp/acdw.el b/lisp/acdw.el index a05295c..3b178db 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el
@@ -2,6 +2,9 @@
2 2
3;;; Code: 3;;; Code:
4 4
5(require 'cl-lib)
6(require 'seq)
7
5(defmacro defdir (name directory &optional docstring makedir) 8(defmacro defdir (name directory &optional docstring makedir)
6 "Define a variable and a function NAME expanding to DIRECTORY. 9 "Define a variable and a function NAME expanding to DIRECTORY.
7DOCSTRING is applied to the variable; its default is DIRECTORY's 10DOCSTRING is applied to the variable; its default is DIRECTORY's
@@ -22,9 +25,9 @@ be created."
22 (make-directory (file-name-directory file-name) :parents)) 25 (make-directory (file-name-directory file-name) :parents))
23 file-name)) 26 file-name))
24 ,(if makedir 27 ,(if makedir
25 `(make-directory ,directory :parents) 28 `(make-directory ,directory :parents)
26 `(unless (file-exists-p ,directory) 29 `(unless (file-exists-p ,directory)
27 (warn "Directory `%s' doesn't exist." ,directory))))) 30 (warn "Directory `%s' doesn't exist." ,directory)))))
28 31
29(defun choose-executable (&rest programs) 32(defun choose-executable (&rest programs)
30 "Return the first of PROGRAMS that exists in the system's $PATH. 33 "Return the first of PROGRAMS that exists in the system's $PATH.
@@ -85,6 +88,17 @@ If `:separator' is the first of STRINGS, the next string will be
85used as a separator." 88used as a separator."
86 (++concat #'format strings)) 89 (++concat #'format strings))
87 90
91(defun list-append-removing-duplicates (&rest lists)
92 "Append LISTS, removing duplicates from the result.
93Any keyword arguments to `cl-remove-duplicates' should come
94before the LISTS."
95 (let (cl-remove-duplicates-args)
96 (while (keywordp (car lists))
97 (push (pop lists) cl-remove-duplicates-args)
98 (push (pop lists) cl-remove-duplicates-args))
99 (apply #'cl-remove-duplicates (apply #'append lists)
100 (nreverse cl-remove-duplicates-args))))
101
88(defun mapc-buffers (func &optional predicate) 102(defun mapc-buffers (func &optional predicate)
89 "Map FUNC over buffers matching PREDICATE. 103 "Map FUNC over buffers matching PREDICATE.
90Both FUNC and PREDICATE will be executed with no arguments and in 104Both FUNC and PREDICATE will be executed with no arguments and in
@@ -125,6 +139,83 @@ each buffer."
125 (progress-reporter-done ,prog))))) 139 (progress-reporter-done ,prog)))))
126 140
127 141
142
143;;; Ispell in .dir-locals
144
145;; Let Emacs know a list of strings is safe
146(defun +ispell-safe-local-p (list)
147 (and (listp list)
148 (seq-every-p #'stringp list)))
149
150;; Can I instruct ispell to insert LocalWords in a different file?
151;; https://emacs.stackexchange.com/q/31396/2264
152
153;; How can I move all my file-local LocalWords to .dir-locals.el?
154;; https://emacs.stackexchange.com/q/31419
155
156;; Adapted from ispell.el:ispell-buffer-local-words
157(defun +ispell-buffer-local-words-list ()
158 (let (words)
159 (or ispell-buffer-local-name
160 (setf ispell-buffer-local-name (buffer-name)))
161 (save-excursion
162 (goto-char (point-min))
163 (while (search-forward ispell-words-keyword nil t)
164 (let ((end (point-at-eol))
165 (ispell-casechars (ispell-get-casechars))
166 string)
167 (while (re-search-forward " *\\([^ ]+\\)" end t)
168 (setf string (match-string-no-properties 1))
169 (if (and (< 1 (length string))
170 (equal 0 (string-match ispell-casechars string)))
171 (push string words))))))
172 words))
173
174;;;###autoload
175(defun +ispell-move-buffer-words-to-dir-locals (&optional arg)
176 "Move the current buffer-local words to .dir-locals.el.
177This function prompts the user to save .dir-locals.el, unless
178prefix ARG is non-nil; then it just saves them."
179 (interactive "P")
180 (unless (buffer-file-name)
181 (user-error "Buffer not attached to file"))
182 (hack-dir-local-variables)
183 (let ((print-level nil)
184 (print-length nil))
185 (when-let ((new-words (cl-remove-if
186 (lambda (el) (eq el '\.\.\.)) ; XXX: NO IDEA
187 ; where this came from
188 (list-append-removing-duplicates
189 :test #'string=
190 ispell-buffer-session-localwords
191 (alist-get 'ispell-buffer-session-localwords
192 dir-local-variables-alist)
193 (alist-get 'ispell-buffer-session-localwords
194 file-local-variables-alist)
195 (+ispell-buffer-local-words-list)))))
196 (save-excursion
197 (add-dir-local-variable
198 major-mode
199 'ispell-buffer-session-localwords
200 (setf ispell-buffer-session-localwords
201 new-words))
202 (when (or arg
203 (y-or-n-p "Save .dir-locals.el?"))
204 (save-buffer))
205 (bury-buffer))
206 (or ispell-buffer-local-name
207 (setf ispell-buffer-local-name (buffer-name)))
208 (save-excursion
209 (goto-char (point-min))
210 (while (search-forward ispell-words-keyword nil t)
211 (delete-region (point-at-bol) (1+ (point-at-eol))))))))
212
213;;;###autoload
214(defun +ispell-move-buffer-words-to-dir-locals-hook ()
215 "Convenience function for binding to a hook."
216 (+ispell-move-buffer-words-to-dir-locals t))
217
218
128;;; Comment-or-uncomment-sexp 219;;; Comment-or-uncomment-sexp
129;; from https://endlessparentheses.com/a-comment-or-uncomment-sexp-command.html 220;; from https://endlessparentheses.com/a-comment-or-uncomment-sexp-command.html
130 221
@@ -214,5 +305,27 @@ With a prefix argument N, (un)comment that many sexps."
214 (dotimes (_ (or n 1)) 305 (dotimes (_ (or n 1))
215 (+lisp-comment-sexp--raw)))) 306 (+lisp-comment-sexp--raw))))
216 307
308
309;;; Random shit
310
311(defun insert-iso-date (&optional arg)
312 "Insert current date formatted ISO-8601 style.
313When called with \\[universal-argument] \\[insert-iso-date],
314include the time. When called with \\[universal-argument]
315\\[universal-argument] \\[insert-iso-date], prompt the user for the
316`format-time-string' format to use."
317 (interactive "P")
318 (insert (format-time-string (pcase arg
319 ('nil "%F")
320 ('(4) "%FT%T%z")
321 (_ (read-string "Time format: "))))))
322
323(defun unfill-paragraph ()
324 "Unfill the current paragraph."
325 (interactive)
326 (let ((fill-column most-positive-fixnum)
327 (fill-paragraph-function nil))
328 (fill-paragraph)))
329
217(provide 'acdw) 330(provide 'acdw)
218;;; acdw.el ends here 331;;; acdw.el ends here