diff options
-rw-r--r-- | basics.el | 17 | ||||
-rw-r--r-- | init.el | 121 | ||||
-rw-r--r-- | lisp/acdw-mail.el | 24 | ||||
-rw-r--r-- | lisp/acdw.el | 119 |
4 files changed, 260 insertions, 21 deletions
diff --git a/basics.el b/basics.el index 428dcd1..68cdc2a 100644 --- a/basics.el +++ b/basics.el | |||
@@ -560,12 +560,23 @@ N spaces." | |||
560 | :hook | 560 | :hook |
561 | (embark-collect-mode . consult-preview-at-point-mode)) | 561 | (embark-collect-mode . consult-preview-at-point-mode)) |
562 | 562 | ||
563 | (use-package undo-fu | ||
564 | :ensure t | ||
565 | :init | ||
566 | (setq undo-limit 67108864) ; 64mb. | ||
567 | (setq undo-strong-limit 100663296) ; 96mb. | ||
568 | (setq undo-outer-limit 1006632960) ; 960mb. | ||
569 | :bind (("C-/" . undo-fu-only-undo) | ||
570 | ("C-?" . undo-fu-only-redo))) | ||
571 | |||
563 | (use-package undo-fu-session | 572 | (use-package undo-fu-session |
564 | :ensure t | 573 | :ensure t |
565 | :config | 574 | :config |
566 | (setq undo-fu-session-incompatible-files | 575 | (setopt undo-fu-session-compression (cond |
567 | '("/COMMIT_EDITMSG\\'" | 576 | ((executable-find "gunzip") 'gz) |
568 | "/git-rebase-todo\\'")) | 577 | ((executable-find "bzip2") 'bz2)) |
578 | undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" | ||
579 | "/git-rebase-todo\\'")) | ||
569 | (global-undo-fu-session-mode)) | 580 | (global-undo-fu-session-mode)) |
570 | 581 | ||
571 | (use-package crux | 582 | (use-package crux |
diff --git a/init.el b/init.el index aed189c..864ac1b 100644 --- a/init.el +++ b/init.el | |||
@@ -1,6 +1,17 @@ | |||
1 | ;;; init.el --- An Emacs of one's own -*- lexical-binding: t -*- | 1 | ;;; init.el --- An Emacs of one's own -*- lexical-binding: t -*- |
2 | |||
3 | ;; Author: Case Duckworth <acdw@acdw.net>, with inspo from many others | ||
4 | ;; Homepage: https://git.acdw.net/emacs | ||
5 | ;; Config-Requires: ((emacs "29.0")) | ||
2 | ;; Bankruptcy: 9.4 | 6 | ;; Bankruptcy: 9.4 |
3 | 7 | ||
8 | ;; This configuration is Free Software. Everyone is permitted to do whatever | ||
9 | ;; they want with it, without limitation. This software comes without any | ||
10 | ;; warranty whatsoever, but with two pieces of advice: | ||
11 | ;; | ||
12 | ;; - Don't hurt others. | ||
13 | ;; - Make good choices. | ||
14 | |||
4 | ;;; Code: | 15 | ;;; Code: |
5 | 16 | ||
6 | (load (locate-user-emacs-file "basics")) ; super basic stuff | 17 | (load (locate-user-emacs-file "basics")) ; super basic stuff |
@@ -106,6 +117,14 @@ | |||
106 | :config | 117 | :config |
107 | (fringe-mode '(nil . 0))) | 118 | (fringe-mode '(nil . 0))) |
108 | 119 | ||
120 | (use-package ispell | ||
121 | :config | ||
122 | (setopt ispell-program-name (choose-executable "ispell" "aspell")) | ||
123 | (add-hook 'before-save-hook | ||
124 | #'+ispell-move-buffer-words-to-dir-locals-hook) | ||
125 | (put 'ispell-buffer-session-localwords 'safe-local-variable | ||
126 | '+ispell-safe-local-p)) | ||
127 | |||
109 | (use-package flyspell | 128 | (use-package flyspell |
110 | :hook org-mode-hook) | 129 | :hook org-mode-hook) |
111 | 130 | ||
@@ -164,6 +183,8 @@ | |||
164 | (use-package time | 183 | (use-package time |
165 | :config | 184 | :config |
166 | (setopt display-time-format " %H:%M" | 185 | (setopt display-time-format " %H:%M" |
186 | display-time-interval 60 | ||
187 | display-time-use-mail-icon t | ||
167 | display-time-mail-function | 188 | display-time-mail-function |
168 | (defun +notmuch-new-mail-p () | 189 | (defun +notmuch-new-mail-p () |
169 | (plist-get (cl-find "inbox+unread" | 190 | (plist-get (cl-find "inbox+unread" |
@@ -173,8 +194,24 @@ | |||
173 | :test #'equal) | 194 | :test #'equal) |
174 | :count)) | 195 | :count)) |
175 | display-time-default-load-average nil) | 196 | display-time-default-load-average nil) |
197 | (with-eval-after-load 'notmuch | ||
198 | (add-hook 'notmuch-after-tag-hook #'display-time-update)) | ||
176 | (display-time-mode)) | 199 | (display-time-mode)) |
177 | 200 | ||
201 | (use-package tab-bar | ||
202 | :config | ||
203 | (setopt tab-bar-show t | ||
204 | tab-bar-close-button-show t) | ||
205 | ;; (add-to-list 'tab-bar-format 'tab-bar-format-menu-bar) | ||
206 | (add-to-list 'tab-bar-format 'tab-bar-format-align-right :append) | ||
207 | (add-to-list 'tab-bar-format 'tab-bar-format-global :append) | ||
208 | (when (daemonp) | ||
209 | (add-hook 'server-after-make-frame-hook | ||
210 | (defun after-frame@tab-bar () | ||
211 | (tab-bar-mode) | ||
212 | (remove-hook 'server-after-make-frame-hook | ||
213 | #'after-frame@tab-bar))))) | ||
214 | |||
178 | 215 | ||
179 | ;;; Applications | 216 | ;;; Applications |
180 | 217 | ||
@@ -265,7 +302,9 @@ With prefix ARG, toggle the value of | |||
265 | 302 | ||
266 | (use-package filldent | 303 | (use-package filldent |
267 | :load-path "~/src/emacs/filldent/" | 304 | :load-path "~/src/emacs/filldent/" |
268 | :bind ("M-q" . filldent-dwim)) | 305 | :bind ("M-q" . filldent-dwim) |
306 | :config | ||
307 | (setopt filldent-fill-modes '(web-mode))) | ||
269 | 308 | ||
270 | (use-package frowny | 309 | (use-package frowny |
271 | :load-path "~/src/emacs/frowny/" | 310 | :load-path "~/src/emacs/frowny/" |
@@ -338,8 +377,30 @@ With prefix ARG, toggle the value of | |||
338 | word-boundary))) | 377 | word-boundary))) |
339 | (hi-lock-unface-buffer regexp) | 378 | (hi-lock-unface-buffer regexp) |
340 | (highlight-regexp regexp 'font-lock-warning-face)))))) | 379 | (highlight-regexp regexp 'font-lock-warning-face)))))) |
380 | (add-hook 'jabber-chat-mode-hook | ||
381 | (defun jabber-chat@leave-when-kill () | ||
382 | (add-hook 'kill-buffer-hook | ||
383 | (defun @jabber-leave@kill () | ||
384 | (apply #'jabber-muc-leave (jabber-muc-argument-list))) | ||
385 | nil :local))) | ||
341 | (when (fboundp 'jabber-chat-update-focus) | 386 | (when (fboundp 'jabber-chat-update-focus) |
342 | (add-hook 'window-configuration-change-hook #'jabber-chat-update-focus))) | 387 | (add-hook 'window-configuration-change-hook #'jabber-chat-update-focus)) |
388 | (with-eval-after-load 'consult | ||
389 | (defvar jabber-chat-buffer-source | ||
390 | `( :name "Jabber" | ||
391 | :hidden nil | ||
392 | :narrow ?j | ||
393 | :category buffer | ||
394 | :state ,#'consult--buffer-state | ||
395 | :items ,(lambda () | ||
396 | (mapcar #'buffer-name | ||
397 | (seq-filter (lambda (buf) | ||
398 | (with-current-buffer buf | ||
399 | (eq major-mode 'jabber-chat-mode))) | ||
400 | (buffer-list)))))) | ||
401 | (add-to-list 'consult-buffer-sources 'jabber-chat-buffer-source :append) | ||
402 | (consult-customize | ||
403 | consult-buffer :preview-key (kbd "M-.")))) | ||
343 | 404 | ||
344 | (use-package keepassxc-shim | 405 | (use-package keepassxc-shim |
345 | :load-path "~/src/emacs/keepassxc-shim/" | 406 | :load-path "~/src/emacs/keepassxc-shim/" |
@@ -349,6 +410,14 @@ With prefix ARG, toggle the value of | |||
349 | 410 | ||
350 | ;;; External packages | 411 | ;;; External packages |
351 | 412 | ||
413 | (use-package async | ||
414 | :ensure t | ||
415 | :config | ||
416 | ;; https://github.com/jwiegley/emacs-async/issues/64 | ||
417 | ;; (setopt message-send-mail-function #'async-smtpmail-send-it) | ||
418 | (dired-async-mode) | ||
419 | (async-bytecomp-package-mode)) | ||
420 | |||
352 | (use-package trashed | 421 | (use-package trashed |
353 | :ensure t) | 422 | :ensure t) |
354 | 423 | ||
@@ -367,11 +436,45 @@ With prefix ARG, toggle the value of | |||
367 | :config (minions-mode)) | 436 | :config (minions-mode)) |
368 | 437 | ||
369 | (use-package visual-fill-column | 438 | (use-package visual-fill-column |
439 | :preface | ||
440 | (defcustom visual-fill-column-widen-amount 4 | ||
441 | "Amount to widen `fill-column' by in `visual-fill-column-mode'." | ||
442 | :type 'natnum | ||
443 | :group 'visual-fill-column) | ||
444 | (defun visual-fill-column--widen/narrow-handle-arg (cols) | ||
445 | (cond | ||
446 | ((null cols) visual-fill-column-widen-amount) | ||
447 | ((listp cols) (* visual-fill-column-widen-amount | ||
448 | (1+ (/ (car cols) 4)))) | ||
449 | ((eq '- cols) (- visual-fill-column-widen-amount)) | ||
450 | (:else cols))) | ||
451 | (defun visual-fill-column-widen (&optional cols) | ||
452 | "Widen `fill-column' by COLS, and re-display. | ||
453 | If COLS is missing or nil, widen by | ||
454 | `visual-fill-column-widen-amount'. When called with a plain | ||
455 | \\[universal-argument], multiply that amount by 1 + the amount of | ||
456 | \\[universal-argument]s. If called with a numerical prefix | ||
457 | argument, widen by that number of columns." | ||
458 | (interactive "P") | ||
459 | (let ((cols (visual-fill-column--widen/narrow-handle-arg cols))) | ||
460 | (cl-incf fill-column cols) | ||
461 | (visual-fill-column-adjust) | ||
462 | (message "Fill-column: %s" fill-column))) | ||
463 | (defun visual-fill-column-narrow (&optional cols) | ||
464 | "Narrow `fill-column' by COLS, then redisplay. | ||
465 | The prefix argument is as in `visual-fill-column-widen' but negated." | ||
466 | (interactive "P") | ||
467 | (let ((cols (visual-fill-column--widen/narrow-handle-arg cols))) | ||
468 | (cl-decf fill-column cols) | ||
469 | (visual-fill-column-adjust) | ||
470 | (message "Fill-column: %s" fill-column))) | ||
370 | :ensure t | 471 | :ensure t |
371 | :init | 472 | :init |
372 | (setopt visual-fill-column-center-text t | 473 | (setopt visual-fill-column-center-text t |
373 | visual-fill-column-extra-text-width '(3 . 3)) | 474 | visual-fill-column-extra-text-width '(3 . 3)) |
374 | :config | 475 | :config |
476 | (keymap-set visual-fill-column-mode-map "C-x C->" #'visual-fill-column-widen) | ||
477 | (keymap-set visual-fill-column-mode-map "C-x C-<" #'visual-fill-column-narrow) | ||
375 | (add-hook 'visual-fill-column-mode-hook #'visual-line-mode) | 478 | (add-hook 'visual-fill-column-mode-hook #'visual-line-mode) |
376 | (add-hook 'eww-mode-hook #'visual-fill-column-mode) | 479 | (add-hook 'eww-mode-hook #'visual-fill-column-mode) |
377 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust)) | 480 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust)) |
@@ -726,15 +829,5 @@ With PREFIX, prompt to change the current dictionary." | |||
726 | (use-package php-mode | 829 | (use-package php-mode |
727 | :ensure t) | 830 | :ensure t) |
728 | 831 | ||
729 | (use-package tab-bar | 832 | (use-package rec-mode |
730 | :config | 833 | :ensure t) |
731 | (setopt tab-bar-show t) | ||
732 | (add-to-list 'tab-bar-format 'tab-bar-format-menu-bar) | ||
733 | (add-to-list 'tab-bar-format 'tab-bar-format-align-right :append) | ||
734 | (add-to-list 'tab-bar-format 'tab-bar-format-global :append) | ||
735 | (with-eval-after-load 'notmuch | ||
736 | |||
737 | ;; (remove-hook 'notmuch-after-tag-hook #'tab-bar-make-keymap-1) | ||
738 | (define-advice notmuch-update-tags (:after (&rest _) update-tab-bar) | ||
739 | (tab-bar--update-tab-bar-lines))) | ||
740 | (tab-bar-mode)) | ||
diff --git a/lisp/acdw-mail.el b/lisp/acdw-mail.el index 8b0ab25..ae78fa0 100644 --- a/lisp/acdw-mail.el +++ b/lisp/acdw-mail.el | |||
@@ -74,6 +74,7 @@ for a free-form search. With any other PREFIX argument, open | |||
74 | (mapcar (lambda (elt) | 74 | (mapcar (lambda (elt) |
75 | (plist-get elt :name)) | 75 | (plist-get elt :name)) |
76 | notmuch-saved-searches)) | 76 | notmuch-saved-searches)) |
77 | notmuch-saved-searches | ||
77 | :key (lambda (elt) (plist-get elt :name)) | 78 | :key (lambda (elt) (plist-get elt :name)) |
78 | :test #'equal) | 79 | :test #'equal) |
79 | :query))) | 80 | :query))) |
@@ -127,6 +128,22 @@ the saved search as well." | |||
127 | (equal (plist-get a :name) | 128 | (equal (plist-get a :name) |
128 | (plist-get b :name)))))) | 129 | (plist-get b :name)))))) |
129 | 130 | ||
131 | (defun notmuch-async-poll () | ||
132 | "Run `notmuch-poll' in an async process." | ||
133 | (interactive) | ||
134 | (if (require 'async nil t) | ||
135 | (progn | ||
136 | (message "Polling mail async...") | ||
137 | (async-start | ||
138 | (lambda () | ||
139 | (push "~/usr/share/emacs/site-lisp/" load-path) | ||
140 | (require 'notmuch-lib) | ||
141 | (notmuch-poll)) | ||
142 | (lambda (result) | ||
143 | (message "%s" result)))) | ||
144 | (user-error "Feature `async' not found!"))) | ||
145 | |||
146 | |||
130 | ;;; Packages | 147 | ;;; Packages |
131 | 148 | ||
132 | (use-package bbdb | 149 | (use-package bbdb |
@@ -174,7 +191,9 @@ the saved search as well." | |||
174 | mail-specify-envelope-from t | 191 | mail-specify-envelope-from t |
175 | message-sendmail-envelope-from 'header | 192 | message-sendmail-envelope-from 'header |
176 | message-envelope-from 'header | 193 | message-envelope-from 'header |
177 | notmuch-saved-searches nil) | 194 | notmuch-saved-searches nil |
195 | notmuch-poll-script "~/usr/scripts/syncmail" ; XXX: Deprecated option | ||
196 | ) | ||
178 | ;; Key bindings | 197 | ;; Key bindings |
179 | (keymap-set notmuch-search-mode-map "!" #'+notmuch-search-mark-spam) | 198 | (keymap-set notmuch-search-mode-map "!" #'+notmuch-search-mark-spam) |
180 | (keymap-set notmuch-search-mode-map "RET" #'notmuch-search-show-thread) | 199 | (keymap-set notmuch-search-mode-map "RET" #'notmuch-search-show-thread) |
@@ -205,6 +224,9 @@ the saved search as well." | |||
205 | (add-hook 'notmuch-message-mode-hook #'visual-fill-column-mode) | 224 | (add-hook 'notmuch-message-mode-hook #'visual-fill-column-mode) |
206 | (add-hook 'notmuch-show-mode-hook #'visual-fill-column-mode) | 225 | (add-hook 'notmuch-show-mode-hook #'visual-fill-column-mode) |
207 | 226 | ||
227 | (define-advice notmuch-bury-or-kill-this-buffer (:after (&rest _) poll-async) | ||
228 | (notmuch-async-poll)) | ||
229 | |||
208 | (define-advice notmuch-address-selection-function | 230 | (define-advice notmuch-address-selection-function |
209 | (:override (prompt collection _) no-initial-input) | 231 | (:override (prompt collection _) no-initial-input) |
210 | "Call `completing-read' with `notmuch-address-history'. | 232 | "Call `completing-read' with `notmuch-address-history'. |
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. |
7 | DOCSTRING is applied to the variable; its default is DIRECTORY's | 10 | DOCSTRING 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 | |||
85 | used as a separator." | 88 | used 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. | ||
93 | Any keyword arguments to `cl-remove-duplicates' should come | ||
94 | before 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. |
90 | Both FUNC and PREDICATE will be executed with no arguments and in | 104 | Both 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. | ||
177 | This function prompts the user to save .dir-locals.el, unless | ||
178 | prefix 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. | ||
313 | When called with \\[universal-argument] \\[insert-iso-date], | ||
314 | include 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 |