diff options
-rw-r--r-- | init.el | 2343 | ||||
-rw-r--r-- | lisp/acdw.el | 19 |
2 files changed, 1198 insertions, 1164 deletions
diff --git a/init.el b/init.el index 60caeaf..4326433 100644 --- a/init.el +++ b/init.el | |||
@@ -16,42 +16,12 @@ | |||
16 | 16 | ||
17 | ;;; Code: | 17 | ;;; Code: |
18 | 18 | ||
19 | ;;; Built-ins | ||
20 | ;; NOTE that some of the names in `setup' forms are arbitrary. | 19 | ;; NOTE that some of the names in `setup' forms are arbitrary. |
21 | 20 | ||
22 | (setup (:require auth-source) | 21 | (setup (:straight (0x0 |
23 | (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg"))) | 22 | :host gitlab |
24 | 23 | :repo "willvaughn/emacs-0x0")) | |
25 | (setup (:require recentf) | 24 | (:option 0x0-default-server 'ttm)) |
26 | (:option recentf-save-file (acdw/dir "recentf.el") | ||
27 | recentf-max-menu-items 100 | ||
28 | recentf-max-saved-items nil | ||
29 | recentf-auto-cleanup 'mode | ||
30 | (append recentf-exclude) (acdw/dir)) | ||
31 | |||
32 | (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify) | ||
33 | |||
34 | (recentf-mode +1)) | ||
35 | |||
36 | (setup (:require savehist) | ||
37 | (:option history-length t | ||
38 | history-delete-duplicates t | ||
39 | savehist-autosave-interval 60 | ||
40 | savehist-file (acdw/dir "savehist.el")) | ||
41 | |||
42 | (dolist (var '(extended-command-history | ||
43 | global-mark-ring | ||
44 | kill-ring | ||
45 | regexp-search-ring | ||
46 | search-ring | ||
47 | mark-ring)) | ||
48 | (add-to-list 'savehist-additional-variables var)) | ||
49 | |||
50 | (savehist-mode +1)) | ||
51 | |||
52 | (setup (:require server) | ||
53 | (unless (server-running-p) | ||
54 | (server-start))) | ||
55 | 25 | ||
56 | (setup Info | 26 | (setup Info |
57 | (:hook variable-pitch-mode | 27 | (:hook variable-pitch-mode |
@@ -73,12 +43,83 @@ | |||
73 | 43 | ||
74 | (when-let ((default-directory | 44 | (when-let ((default-directory |
75 | (expand-file-name-exists-p "pkg/" user-emacs-directory))) | 45 | (expand-file-name-exists-p "pkg/" user-emacs-directory))) |
76 | (normal-top-level-add-subdirs-to-load-path))) | 46 | (normal-top-level-add-subdirs-to-load-path)) |
47 | |||
48 | (defun acdw/sort-setups () | ||
49 | "Sort `setup' forms in the current buffer. | ||
50 | Actually sorts all forms, but based on the logic of `setup'. | ||
51 | AKA, DO NOT USE THIS FUNCTION!!!" | ||
52 | (save-excursion | ||
53 | (sort-sexps (point-min) (point-max) | ||
54 | (lambda (sexp) | ||
55 | (let ((name (cadr sexp))) | ||
56 | (symbol-name (if (listp name) ; this is /terrible/! | ||
57 | (if (keywordp (car name)) | ||
58 | (let ((feature (cadr name))) | ||
59 | (if (listp feature) | ||
60 | (car feature) | ||
61 | feature)) | ||
62 | (car name)) | ||
63 | name)))))))) | ||
64 | |||
65 | (setup (:straight-if affe | ||
66 | (and (or (executable-find "fd") | ||
67 | (executable-find "find")) | ||
68 | (executable-find "rg"))) | ||
69 | ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find' | ||
70 | (:option affe-regexp-compiler | ||
71 | (defun affe-orderless-regexp-compiler (input _type) | ||
72 | (setq input (orderless-pattern-compiler input)) | ||
73 | (cons input (lambda (str) (orderless--highlight input str)))))) | ||
74 | |||
75 | (setup (:straight-if ahk-mode | ||
76 | (acdw/system :work))) | ||
77 | |||
78 | (setup (:straight alert) | ||
79 | (:option alert-default-style (acdw/system | ||
80 | (:home 'libnotify) | ||
81 | (_ 'message)))) | ||
82 | |||
83 | (setup (:straight (apheleia | ||
84 | :host github | ||
85 | :repo "raxod502/apheleia")) | ||
86 | |||
87 | (apheleia-global-mode +1) | ||
88 | |||
89 | ;; Use a dumb formatter on modes that `apheleia' doesn't work for. | ||
90 | (add-hook 'before-save-hook | ||
91 | (defun before-save@dumb-auto-format () | ||
92 | (setq stupid-modes '(makefile-mode | ||
93 | org-mode)) | ||
94 | ;; If there's no apheleia formatter for the mode, just indent the | ||
95 | ;; buffer. | ||
96 | (unless (or (apply #'derived-mode-p stupid-modes) | ||
97 | (and (fboundp 'apheleia--get-formatter-command) | ||
98 | (apheleia--get-formatter-command))) | ||
99 | (indent-region (point-min) (point-max)))))) | ||
100 | |||
101 | (setup (:straight async) | ||
102 | (dired-async-mode +1) | ||
103 | |||
104 | (:with-feature dired | ||
105 | (:hook (defun dired@disable-dired-async-mode-line () | ||
106 | (autoload 'dired-async--modeline-mode "dired-async" nil t) | ||
107 | (dired-async--modeline-mode -1))))) | ||
108 | |||
109 | (setup (:require auth-source) | ||
110 | (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg"))) | ||
77 | 111 | ||
78 | (setup autorevert | 112 | (setup autorevert |
79 | (:option global-auto-revert-non-file-buffers t) | 113 | (:option global-auto-revert-non-file-buffers t) |
80 | (global-auto-revert-mode +1)) | 114 | (global-auto-revert-mode +1)) |
81 | 115 | ||
116 | (setup (:straight avy) | ||
117 | (:global "C-:" #'avy-goto-char-timer | ||
118 | "C-c C-j" #'avy-resume) | ||
119 | |||
120 | (:with-feature isearch | ||
121 | (:bind "C-'" #'avy-isearch))) | ||
122 | |||
82 | (setup browse-url | 123 | (setup browse-url |
83 | (:require acdw-browse-url) | 124 | (:require acdw-browse-url) |
84 | 125 | ||
@@ -127,6 +168,106 @@ | |||
127 | (setup calendar | 168 | (setup calendar |
128 | (:option calendar-week-start-day 1)) | 169 | (:option calendar-week-start-day 1)) |
129 | 170 | ||
171 | (setup (:straight circe) | ||
172 | (require 'circe) | ||
173 | (require 'acdw-irc) | ||
174 | |||
175 | (:option acdw-irc/left-margin 12 | ||
176 | acdw-irc/post-my-nick "-> " | ||
177 | circe-channel-killed-confirmation nil | ||
178 | circe-color-nicks-everywhere t | ||
179 | circe-default-nick "acdw" | ||
180 | circe-default-part-message "See You, Space Cowpokes . . ." | ||
181 | circe-default-user "acdw" | ||
182 | circe-format-action | ||
183 | (lambda (&rest plist) | ||
184 | (concat | ||
185 | (acdw-irc/margin-format "" "*" "*" t) | ||
186 | " " (plist-get plist :nick) " " (plist-get plist :body))) | ||
187 | circe-format-say | ||
188 | (lambda (&rest plist) | ||
189 | (concat | ||
190 | (acdw-irc/margin-format (plist-get plist :nick) "" " |" t) | ||
191 | " " (plist-get plist :body))) | ||
192 | circe-format-self-action | ||
193 | (lambda (&rest plist) | ||
194 | (concat | ||
195 | (acdw-irc/margin-format "" "-*" " *" t) | ||
196 | " " (plist-get plist :nick) " " (plist-get plist :body))) | ||
197 | circe-format-self-say | ||
198 | (lambda (&rest plist) | ||
199 | (concat | ||
200 | (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t) | ||
201 | " " (plist-get plist :body))) | ||
202 | circe-highlight-nick-type 'sender | ||
203 | circe-network-options | ||
204 | `(("Libera Chat" | ||
205 | :channels ("#emacs" "#systemcrafters" "##webpals") | ||
206 | :sasl-username circe-default-nick | ||
207 | :sasl-password ,(acdw/make-password-fetcher | ||
208 | :host "libera.chat")) | ||
209 | ("Tilde Chat" :host "irc.tilde.chat" :port 6697 :use-tls t | ||
210 | :channels ("#meta" "#bread" "#dadjokes" "#team") | ||
211 | :sasl-username circe-default-nick | ||
212 | :sasl-password ,(acdw/make-password-fetcher | ||
213 | :host "tilde.chat")) | ||
214 | ("Casa" :host "m455.casa" :port 6697 :use-tls t | ||
215 | :channels ("#basement") | ||
216 | :sasl-username circe-default-nick | ||
217 | :sasl-password ,(acdw/make-password-fetcher | ||
218 | :host "m455.casa")) | ||
219 | ("Piss" :host "piss.hmm.st" :port 6697 :use-tls t)) | ||
220 | circe-reduce-lurker-spam t | ||
221 | circe-server-auto-join-default-type :after-auth) | ||
222 | |||
223 | (custom-set-faces '(circe-nick-highlight-face | ||
224 | ((t (:inherit (modus-themes-hl-line)))) | ||
225 | :now)) | ||
226 | |||
227 | (:bind "C-c C-p" #'circe-command-PART) | ||
228 | |||
229 | (:advise circe-command-PART :after | ||
230 | (defun circe-command-PART@kill-buffer (&rest _) | ||
231 | (let ((circe-channel-killed-confirmation nil)) | ||
232 | (kill-buffer)))) | ||
233 | |||
234 | (:with-mode circe-chat-mode | ||
235 | (:hook #'acdw/stop-paren-annoyances | ||
236 | (defun circe-chat@setup () | ||
237 | (lui-set-prompt | ||
238 | (concat (propertize (acdw-irc/margin-format (buffer-name) | ||
239 | "" | ||
240 | ">") | ||
241 | 'face 'circe-prompt-face | ||
242 | 'read-only t 'intangible t | ||
243 | 'cursor-intangible t) | ||
244 | " ")) | ||
245 | (enable-circe-color-nicks) | ||
246 | (enable-circe-display-images) | ||
247 | (enable-circe-new-day-notifier)))) | ||
248 | |||
249 | (autoload 'circe-nick-color-reset "circe-color-nicks") | ||
250 | (add-hook 'modus-themes-after-load-theme-hook | ||
251 | #'circe-nick-color-reset) | ||
252 | |||
253 | (:with-mode lui-mode | ||
254 | (:option lui-fill-column fill-column | ||
255 | lui-fill-type (repeat-string acdw-irc/left-margin " ") | ||
256 | lui-time-stamp-position 'right-margin | ||
257 | lui-time-stamp-format "%H:%M" | ||
258 | lui-track-behavior 'before-switch-to-buffer | ||
259 | lui-track-indicator 'fringe) | ||
260 | |||
261 | (:hook (defun lui-mode@setup () | ||
262 | (setq-local fringes-outside-margins t | ||
263 | right-margin-width 5 | ||
264 | scroll-margin 0 | ||
265 | word-wrap t | ||
266 | wrap-prefix (repeat-string | ||
267 | acdw-irc/left-margin " ") | ||
268 | line-number-mode nil) | ||
269 | (enable-lui-track))))) | ||
270 | |||
130 | (setup completion | 271 | (setup completion |
131 | (:option completion-ignore-case t | 272 | (:option completion-ignore-case t |
132 | read-buffer-completion-ignore-case t | 273 | read-buffer-completion-ignore-case t |
@@ -137,6 +278,154 @@ | |||
137 | 278 | ||
138 | (:global "M-/" #'hippie-expand)) | 279 | (:global "M-/" #'hippie-expand)) |
139 | 280 | ||
281 | (setup (:straight (consult | ||
282 | :host github | ||
283 | :repo "minad/consult")) | ||
284 | (require 'acdw-consult) | ||
285 | |||
286 | (setq consult--regexp-compiler #'consult--orderless-regexp-compiler) | ||
287 | |||
288 | ;; Bindings | ||
289 | (:global | ||
290 | ;; C-c bindings (`mode-specific-map') | ||
291 | ;; I don't use any of these right now. | ||
292 | ;; "C-c h" #'consult-history | ||
293 | ;; "C-c m" #'consult-mode-command | ||
294 | ;; "C-c b" #'consult-bookmark | ||
295 | ;; "C-c k" #'consult-kmacro | ||
296 | ;; C-x bindings (`ctl-x-map') | ||
297 | "C-x M-:" #'consult-complex-command | ||
298 | "C-x b" #'consult-buffer | ||
299 | "C-x 4 b" #'consult-buffer-other-window | ||
300 | "C-x 5 b" #'consult-buffer-other-frame | ||
301 | ;; Custom M-# bindings for fast register access | ||
302 | "M-#" #'consult-register-load | ||
303 | "M-'" #'consult-register-store | ||
304 | "C-M-#" #'consult-register | ||
305 | ;; M-g bindings (`goto-map') | ||
306 | "M-g e" #'consult-compile-error | ||
307 | "M-g g" #'consult-goto-line | ||
308 | "M-g M-g" #'consult-goto-line | ||
309 | "M-g o" #'consult-outline | ||
310 | "M-g m" #'consult-mark | ||
311 | "M-g k" #'consult-global-mark | ||
312 | "M-g i" #'consult-imenu | ||
313 | "M-g I" #'consult-project-imenu | ||
314 | ;; M-s bindings (`search-map') | ||
315 | "M-s g" #'acdw-consult/sensible-grep | ||
316 | "M-s f" #'acdw-consult/sensible-find | ||
317 | "M-s l" #'consult-line | ||
318 | "M-s m" #'consult-multi-occur | ||
319 | "M-s k" #'consult-keep-lines | ||
320 | "M-s u" #'consult-focus-lines | ||
321 | ;; Other bindings | ||
322 | "M-y" #'consult-yank-pop | ||
323 | "<help> a" #'consult-apropos | ||
324 | ;; Isearch integration | ||
325 | "M-s e" #'consult-isearch) | ||
326 | (:with-map isearch-mode-map | ||
327 | (:bind "M-e" #'consult-isearch | ||
328 | "M-s e" #'consult-isearch | ||
329 | "M-s l" #'consult-line)) | ||
330 | |||
331 | ;; see https://github.com/oantolin/completing-history | ||
332 | (defmacro consult-history-to-modes (map-hook-alist) | ||
333 | (let (defuns) | ||
334 | (dolist (map-hook map-hook-alist) | ||
335 | (let ((map-name (symbol-name (car map-hook))) | ||
336 | (key-defs `(progn (define-key | ||
337 | ,(car map-hook) | ||
338 | (kbd "M-r") | ||
339 | (function consult-history)) | ||
340 | (define-key ,(car map-hook) | ||
341 | (kbd "M-s") nil)))) | ||
342 | (push (if (cdr map-hook) | ||
343 | `(add-hook ',(cdr map-hook) | ||
344 | (defun | ||
345 | ,(intern (concat map-name | ||
346 | "@consult-history-bind")) | ||
347 | nil | ||
348 | ,(concat | ||
349 | "Bind `consult-history' to M-r in " | ||
350 | map-name ".\n" | ||
351 | "Defined by `consult-history-to-modes'.") | ||
352 | ,key-defs)) | ||
353 | key-defs) | ||
354 | defuns))) | ||
355 | `(progn ,@ (nreverse defuns)))) | ||
356 | |||
357 | (consult-history-to-modes ((minibuffer-local-map . nil) | ||
358 | (shell-mode-map . shell-mode-hook) | ||
359 | (term-mode-map . term-mode-hook) | ||
360 | (term-raw-map . term-mode-hook) | ||
361 | (comint-mode-map . comint-mode-hook) | ||
362 | (sly-mrepl-mode-map . sly-mrepl-hook))) | ||
363 | |||
364 | |||
365 | |||
366 | ;; Registers | ||
367 | (:autoload consult-register-preview) | ||
368 | (:option register-preview-delay 0 | ||
369 | register-preview-function #'consult-register-format) | ||
370 | (:advise register-preview :override #'consult-register-window) | ||
371 | |||
372 | ;; Xref | ||
373 | (:option xref-show-xrefs-function #'consult-xref | ||
374 | xref-show-definitions-function #'consult-xref) | ||
375 | |||
376 | ;; Projects | ||
377 | (:option consult-project-root-function #'vc-root-dir) | ||
378 | |||
379 | ;; Competion-at-point (complete-region) | ||
380 | (:option completion-in-region-function #'acdw-consult/complete-in-region | ||
381 | completion-cycle-threshold 3 | ||
382 | tab-always-indent 'complete) | ||
383 | |||
384 | ;; Completing-read-multple | ||
385 | (if (fboundp #'consult-completing-read-multiple) | ||
386 | (:advise completing-read-multple | ||
387 | :override #'consult-completing-read-multiple) | ||
388 | ;; else | ||
389 | (defun crm-indicator (args) | ||
390 | (cons (concat "[CRM] " (car args)) (cdr args))) | ||
391 | (:advise completing-read-multiple | ||
392 | :filter-args #'crm-indicator)) | ||
393 | |||
394 | (with-eval-after-loads (vertico consult) | ||
395 | (when (boundp 'consult-crm-map) | ||
396 | (define-key consult-crm-map "\r" #'+vertico-crm-exit) | ||
397 | (define-key consult-crm-map "\t" #'vertico-exit) | ||
398 | (defun +vertico-crm-exit () | ||
399 | (interactive) | ||
400 | (run-at-time 0 nil #'vertico-exit) | ||
401 | (funcall #'vertico-exit))))) | ||
402 | |||
403 | (setup (:straight crux) | ||
404 | |||
405 | (:global "C-x o" #'acdw/other-window-or-switch-buffer | ||
406 | "C-o" #'crux-smart-open-line | ||
407 | "M-o" #'crux-smart-open-line-above | ||
408 | "C-M-\\" #'crux-cleanup-buffer-or-region | ||
409 | "C-x 4 t" #'crux-transpose-windows) | ||
410 | |||
411 | (when (fboundp 'repeat-mode) | ||
412 | (unless (boundp 'other-window-repeat-map) | ||
413 | (defvar other-window-repeat-map (make-sparse-keymap) | ||
414 | "A map for repeating `other-window' keys.")) | ||
415 | |||
416 | (define-key other-window-repeat-map "o" | ||
417 | #'acdw/other-window-or-switch-buffer) | ||
418 | (define-key other-window-repeat-map "O" | ||
419 | (defun acdw/other-window-or-switch-buffer-backward () | ||
420 | (interactive) | ||
421 | (setq repeat-map 'other-window-repeat-map) | ||
422 | (acdw/other-window-or-switch-buffer -1))) | ||
423 | |||
424 | (put 'acdw/other-window-or-switch-buffer | ||
425 | 'repeat-map 'other-window-repeat-map)) | ||
426 | |||
427 | (crux-reopen-as-root-mode +1)) | ||
428 | |||
140 | (setup cursor | 429 | (setup cursor |
141 | (:option cursor-type 'bar | 430 | (:option cursor-type 'bar |
142 | cursor-in-non-selected-windows 'hollow | 431 | cursor-in-non-selected-windows 'hollow |
@@ -280,10 +569,56 @@ | |||
280 | (:option ediff-window-setup-function #'ediff-setup-windows-plain | 569 | (:option ediff-window-setup-function #'ediff-setup-windows-plain |
281 | ediff-split-window-function #'split-window-horizontally)) | 570 | ediff-split-window-function #'split-window-horizontally)) |
282 | 571 | ||
572 | ;; requires extension: | ||
573 | ;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/ | ||
574 | (setup (:straight edit-server) | ||
575 | (when (and (daemonp) | ||
576 | (require 'edit-server nil :noerror)) | ||
577 | (edit-server-start) | ||
578 | |||
579 | (:advise edit-server-make-frame :before | ||
580 | (defun edit-server@set-a-variable (&rest _) | ||
581 | (setq-local edit-server-frame-p t))))) | ||
582 | |||
283 | (setup eldoc | 583 | (setup eldoc |
284 | (:option eldoc-idle-delay 0.1 | 584 | (:option eldoc-idle-delay 0.1 |
285 | eldoc-echo-area-use-multiline-p nil)) | 585 | eldoc-echo-area-use-multiline-p nil)) |
286 | 586 | ||
587 | (setup (:straight (electric-cursor | ||
588 | :host github | ||
589 | :repo "duckwork/electric-cursor")) | ||
590 | (electric-cursor-mode +1)) | ||
591 | |||
592 | (setup (:straight elfeed | ||
593 | elfeed-protocol) | ||
594 | (:option elfeed-use-curl t | ||
595 | elfeed-feeds `(("fever+https://acdw@mf.acdw.net" | ||
596 | :api-url "https://mf.acdw.net/fever/" | ||
597 | :password ,(acdw/make-password-fetcher | ||
598 | :host "mf.acdw.net")))) | ||
599 | |||
600 | (elfeed-protocol-enable) | ||
601 | |||
602 | (:with-mode elfeed-show-mode | ||
603 | (:hook (defun elfeed-show@setup () | ||
604 | (acdw/reading-mode))) | ||
605 | |||
606 | ;; see https://irreal.org/blog/?p=8885 | ||
607 | (:bind "SPC" (defun elfeed-scroll-up-command (&optional arg) | ||
608 | "Scroll up or go to next feed item in Elfeed" | ||
609 | (interactive "^P") | ||
610 | (let ((scroll-error-top-bottom nil)) | ||
611 | (condition-case-unless-debug nil | ||
612 | (scroll-up-command arg) | ||
613 | (error (elfeed-show-next))))) | ||
614 | "S-SPC" (defun elfeed-scroll-down-command (&optional arg) | ||
615 | "Scroll up or go to next feed item in Elfeed" | ||
616 | (interactive "^P") | ||
617 | (let ((scroll-error-top-bottom nil)) | ||
618 | (condition-case-unless-debug nil | ||
619 | (scroll-down-command arg) | ||
620 | (error (elfeed-show-prev)))))))) | ||
621 | |||
287 | (setup elisp-mode | 622 | (setup elisp-mode |
288 | (:option eval-expression-print-length nil | 623 | (:option eval-expression-print-length nil |
289 | eval-expression-print-level nil | 624 | eval-expression-print-level nil |
@@ -297,9 +632,9 @@ | |||
297 | (setq-local lexical-binding t)) | 632 | (setq-local lexical-binding t)) |
298 | 633 | ||
299 | (defun emacs-lisp@imenu-add-setup () | 634 | (defun emacs-lisp@imenu-add-setup () |
300 | (add-to-list 'imenu-generic-expression | 635 | (:option (append imenu-generic-expression) |
301 | '("Setup" | 636 | '("Setup" |
302 | "\\(^\\s-*(setup +(?\\)\\(\\_<.+\\_>\\)" 2)))) | 637 | "\\(^\\s-*(setup +(?\\)\\(\\_<.+\\_>\\)" 2)))) |
303 | 638 | ||
304 | ;; Emulate slime's eval binds | 639 | ;; Emulate slime's eval binds |
305 | (:bind "C-c C-c" #'eval-defun | 640 | (:bind "C-c C-c" #'eval-defun |
@@ -312,6 +647,57 @@ | |||
312 | (pulse-momentary-highlight-region beg end) | 647 | (pulse-momentary-highlight-region beg end) |
313 | (apply fn start end args)))) | 648 | (apply fn start end args)))) |
314 | 649 | ||
650 | (setup (:straight elisp-slime-nav) | ||
651 | (:hook-into emacs-lisp-mode | ||
652 | ielm-mode)) | ||
653 | |||
654 | (setup (:straight (elpher | ||
655 | :host nil | ||
656 | :repo "git://thelambdalab.xyz/elpher.git")) | ||
657 | (:option elpher-ipv4-always t | ||
658 | elpher-certificate-directory (acdw/dir "elpher/") | ||
659 | elpher-gemini-max-fill-width fill-column) | ||
660 | |||
661 | (:bind "n" #'elpher-next-link | ||
662 | "p" #'elpher-prev-link | ||
663 | "o" #'elpher-follow-current-link | ||
664 | "G" #'elpher-go-current) | ||
665 | |||
666 | (:hook acdw/reading-mode) | ||
667 | |||
668 | (:autoload (elpher-bookmarks :interactive t) | ||
669 | (elpher-go :interactive t)) | ||
670 | |||
671 | ;; Make `eww' gemini/gopher aware. From Emacswiki. | ||
672 | ;; (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher) | ||
673 | ;; (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url) | ||
674 | ;; (require 'elpher) | ||
675 | ;; (elpher-go url)) | ||
676 | ;; (t (apply fn url args)))) | ||
677 | ) | ||
678 | |||
679 | (setup (:straight embark) | ||
680 | (:global "C-." #'embark-act) | ||
681 | (:option prefix-help-command #'embark-prefix-help-command | ||
682 | (append display-buffer-alist) | ||
683 | '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" | ||
684 | nil | ||
685 | (window-parameters (mode-line-format . none))) | ||
686 | embark-prompter #'embark-keymap-prompter | ||
687 | embark-verbose-indicator-display-action | ||
688 | '(display-buffer-at-bottom (window-height . fit-window-to-buffer))) | ||
689 | |||
690 | (setq embark-action-indicator | ||
691 | (lambda (map _target) | ||
692 | (which-key--show-keymap "Embark" map nil nil 'no-paging) | ||
693 | #'which-key--hide-popup-ignore-command) | ||
694 | embark-become-indicator embark-action-indicator) | ||
695 | |||
696 | (with-eval-after-loads (embark consult) | ||
697 | (:straight embark-consult) | ||
698 | (add-hook 'embark-collect-mode-hook | ||
699 | #'consult-preview-at-point-mode))) | ||
700 | |||
315 | (setup encoding | 701 | (setup encoding |
316 | (:option locale-coding-system 'utf-8-unix | 702 | (:option locale-coding-system 'utf-8-unix |
317 | coding-system-for-read 'utf-8-unix | 703 | coding-system-for-read 'utf-8-unix |
@@ -336,6 +722,60 @@ | |||
336 | (_ (set-selection-coding-system 'utf-8) | 722 | (_ (set-selection-coding-system 'utf-8) |
337 | (set-clipboard-coding-system 'utf-8)))) | 723 | (set-clipboard-coding-system 'utf-8)))) |
338 | 724 | ||
725 | (setup (:straight epithet) | ||
726 | (dolist (hook '(Info-selection-hook | ||
727 | eww-after-render-hook | ||
728 | help-mode-hook | ||
729 | occur-mode-hook)) | ||
730 | (add-hook hook #'epithet-rename-buffer))) | ||
731 | |||
732 | ;; TODO: look into emms or something related for this | ||
733 | (setup (:straight-if eradio | ||
734 | (executable-find "mpv")) | ||
735 | (:option | ||
736 | eradio-player '("mpv" "--no-video" "--no-terminal") | ||
737 | eradio-channels `(("KLSU" . | ||
738 | "http://130.39.238.143:8010/stream.mp3") | ||
739 | ("Soma FM Synphaera" . | ||
740 | "https://somafm.com/synphaera256.pls") | ||
741 | ("SomaFM BAGel Radio" . | ||
742 | "https://somafm.com/bagel.pls") | ||
743 | ("SomaFM Boot Liquor" . | ||
744 | "https://somafm.com/bootliquor320.pls") | ||
745 | ("SomaFM Deep Space One" . | ||
746 | "https://somafm.com/deepspaceone.pls") | ||
747 | ("SomaFM Fluid" . | ||
748 | "https://somafm.com/fluid.pls") | ||
749 | ("SomaFM Underground 80s" . | ||
750 | "https://somafm.com/u80s256.pls") | ||
751 | ("WBRH: Jazz & More" . | ||
752 | "http://wbrh.streamguys1.com/wbrh-mp3") | ||
753 | ("KBRH Blues & Rhythm Hits" . | ||
754 | "http://wbrh.streamguys1.com/kbrh-mp3") | ||
755 | ("WRKF HD-2" . | ||
756 | ,(concat "https://playerservices.streamtheworld.com/" | ||
757 | "api/livestream-redirect/WRKFHD2.mp3")) | ||
758 | ("WRKF: NPR for the Capital Region" . | ||
759 | ,(concat "https://playerservices.streamtheworld.com/" | ||
760 | "api/livestream-redirect/WRKFFM.mp3")) | ||
761 | ("BadRadio: 24/7 PHONK" . | ||
762 | "https://s2.radio.co/s2b2b68744/listen") | ||
763 | ("tilderadio" . | ||
764 | "https://radio.tildeverse.org/radio/8000/radio.ogg") | ||
765 | ("vantaradio" . | ||
766 | "https://vantaa.black/radio"))) | ||
767 | (:global "C-c r r" #'eradio-play ; mnemonic: radio | ||
768 | "C-c r s" #'eradio-stop ; mnemonic: stop | ||
769 | "C-c r p" #'eradio-toggle ; mnemonic: play/pause | ||
770 | )) | ||
771 | |||
772 | (setup (:straight eros) | ||
773 | (:hook-into emacs-lisp-mode)) | ||
774 | |||
775 | (setup (:straight esh-autosuggest) | ||
776 | (:autoload esh-autosuggest-mode) | ||
777 | (:hook-into eshell-mode)) | ||
778 | |||
339 | (setup eshell | 779 | (setup eshell |
340 | (:also-load acdw-eshell | 780 | (:also-load acdw-eshell |
341 | em-smart) | 781 | em-smart) |
@@ -371,6 +811,41 @@ | |||
371 | 811 | ||
372 | (:hook acdw/reading-mode)) | 812 | (:hook acdw/reading-mode)) |
373 | 813 | ||
814 | (setup (:straight-if exec-path-from-shell | ||
815 | (acdw/system :home)) | ||
816 | (when (daemonp) | ||
817 | (exec-path-from-shell-initialize))) | ||
818 | |||
819 | (setup (:straight expand-region) | ||
820 | (:global "C-=" #'er/expand-region | ||
821 | "C-SPC" | ||
822 | (defun acdw/set-mark-or-expand-region (arg) | ||
823 | "Set mark at point and activate, jump to mark, or expand region. | ||
824 | See `set-mark-command' and `expand-region'. | ||
825 | |||
826 | With no prefix argument, either run `set-mark-command' on first | ||
827 | invocation and `er/expand-region' on each successive invocation. | ||
828 | |||
829 | With any prefix argument | ||
830 | (e.g., \\[universal-argument] \\[set-mark-command]), act as with | ||
831 | `set-mark-command' (i.e., pop the mark). Don't care about | ||
832 | successive invocations." | ||
833 | (interactive "P") | ||
834 | (cond | ||
835 | ((or arg | ||
836 | (and set-mark-command-repeat-pop | ||
837 | (eq last-command 'pop-to-mark-command))) | ||
838 | (setq this-command 'set-mark-command) | ||
839 | (set-mark-command arg)) | ||
840 | ((eq last-command 'acdw/set-mark-or-expand-region) | ||
841 | (er/expand-region 1)) | ||
842 | (t (set-mark-command arg)))))) | ||
843 | |||
844 | (setup (:straight-if fennel-mode | ||
845 | (executable-find "fennel")) | ||
846 | (:autoload (fennel-repl :interactive t)) | ||
847 | (:file-match (rx ".fnl" eos))) | ||
848 | |||
374 | (setup files | 849 | (setup files |
375 | (:option | 850 | (:option |
376 | auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t)) | 851 | auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t)) |
@@ -400,6 +875,12 @@ | |||
400 | (setup flyspell | 875 | (setup flyspell |
401 | (add-hook 'text-mode-hook #'flyspell-mode)) | 876 | (add-hook 'text-mode-hook #'flyspell-mode)) |
402 | 877 | ||
878 | (setup (:straight flyspell-correct) | ||
879 | (:with-mode flyspell-mode | ||
880 | (:hook (defun flyspell@correct () | ||
881 | (:bind "C-;" #'flyspell-correct-wrapper) | ||
882 | (:unbind "C-," "C-." "C-M-i"))))) | ||
883 | |||
403 | (setup frames | 884 | (setup frames |
404 | (:option frame-title-format '("%b@" | 885 | (:option frame-title-format '("%b@" |
405 | (:eval | 886 | (:eval |
@@ -412,11 +893,87 @@ | |||
412 | 893 | ||
413 | (add-hook 'unfocused-hook #'garbage-collect)) | 894 | (add-hook 'unfocused-hook #'garbage-collect)) |
414 | 895 | ||
896 | (setup (:straight gcmh) | ||
897 | (:option gcmh-idle-delay 'auto) | ||
898 | (gcmh-mode +1)) | ||
899 | |||
900 | (setup (:straight-if geiser | ||
901 | (progn | ||
902 | (defvar acdw/schemes | ||
903 | (let (schemes) | ||
904 | (dolist (scheme '(("scheme" . geiser-chez) ; chez | ||
905 | ("petite" . geiser-chez) ; petite | ||
906 | ("csi" . geiser-chez) ; chicken | ||
907 | ("gsi" . geiser-gambit) | ||
908 | ("gosh" . geiser-gauche) | ||
909 | ("guile" . geiser-guile) | ||
910 | ("kawa" . geiser-kawa) | ||
911 | ("mit-scheme" . geiser-mit) | ||
912 | ("racket" . geiser-racket) | ||
913 | ("stklos" . geiser-stklos))) | ||
914 | (when-let (binary (executable-find (car scheme))) | ||
915 | (push binary schemes) | ||
916 | ;; and install the proper helper package | ||
917 | (straight-use-package (cdr scheme)))) | ||
918 | (nreverse schemes))) | ||
919 | acdw/schemes)) | ||
920 | (:file-match (rx ".rkt" eos) | ||
921 | (rx ".scm" eos))) | ||
922 | |||
923 | (setup (:straight (gemini-mode | ||
924 | :host nil | ||
925 | :repo "https://git.carcosa.net/jmcbray/gemini.el.git")) | ||
926 | (:file-match (rx (seq "." (or "gemini" "gmi") eos))) | ||
927 | (:hook turn-off-auto-fill)) | ||
928 | |||
929 | (setup (:straight (gemini-write | ||
930 | :host nil | ||
931 | :repo "https://alexschroeder.ch/cgit/gemini-write" | ||
932 | :branch "main")) | ||
933 | (with-eval-after-load 'elpher | ||
934 | (require 'gemini-write))) | ||
935 | |||
936 | (setup (:require gforth) | ||
937 | (:autoload forth-mode | ||
938 | forth-block-mode) | ||
939 | (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode)) | ||
940 | (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))) | ||
941 | |||
415 | (setup goto-addr | 942 | (setup goto-addr |
416 | (if (fboundp #'global-goto-address-mode) | 943 | (if (fboundp #'global-goto-address-mode) |
417 | (global-goto-address-mode) | 944 | (global-goto-address-mode) |
418 | (add-hook 'after-change-major-mode-hook #'goto-address-mode))) | 945 | (add-hook 'after-change-major-mode-hook #'goto-address-mode))) |
419 | 946 | ||
947 | |||
948 | ;; TODO: figure out a popper.el / shackle.el ... thing to fix this | ||
949 | (setup (:straight helpful) | ||
950 | (:option helpful-max-buffers 5) | ||
951 | (:global "<help> f" #'helpful-callable | ||
952 | "<help> v" #'helpful-variable | ||
953 | "<help> k" #'helpful-key | ||
954 | "<help> o" #'helpful-symbol)) | ||
955 | |||
956 | (setup (:straight hungry-delete) | ||
957 | (:option hungry-delete-chars-to-skip " \t" | ||
958 | hungry-delete-join-reluctantly nil) | ||
959 | |||
960 | (global-hungry-delete-mode +1) | ||
961 | |||
962 | (:with-feature paredit | ||
963 | (:bind [remap paredit-backward-delete] | ||
964 | (defun acdw/paredit-hungry-delete-backward (arg) | ||
965 | (interactive "P") | ||
966 | (if (looking-back "[ \t]" 1) | ||
967 | (hungry-delete-backward (or arg 1)) | ||
968 | (paredit-backward-delete arg))) | ||
969 | |||
970 | [remap paredit-forward-delete] | ||
971 | (defun acdw/paredit-hungry-delete-forward (arg) | ||
972 | (interactive "P") | ||
973 | (if (looking-at "[ \t]") | ||
974 | (hungry-delete-forward (or arg 1)) | ||
975 | (paredit-forward-delete arg)))))) | ||
976 | |||
420 | (setup ibuffer | 977 | (setup ibuffer |
421 | (:also-load ibuf-ext) | 978 | (:also-load ibuf-ext) |
422 | (:option ibuffer-expert t | 979 | (:option ibuffer-expert t |
@@ -464,9 +1021,21 @@ | |||
464 | (setup imenu | 1021 | (setup imenu |
465 | (:option imenu-auto-rescan t)) | 1022 | (:option imenu-auto-rescan t)) |
466 | 1023 | ||
1024 | (setup (:straight iscroll) | ||
1025 | (define-globalized-minor-mode global-iscroll-mode iscroll-mode | ||
1026 | (lambda () (iscroll-mode +1))) | ||
1027 | |||
1028 | (global-iscroll-mode +1)) | ||
1029 | |||
467 | (setup isearch | 1030 | (setup isearch |
468 | (:option search-default-mode t)) | 1031 | (:option search-default-mode t)) |
469 | 1032 | ||
1033 | (setup (:straight lacarte) | ||
1034 | (:global "<f10>" #'lacarte-execute-menu-command)) | ||
1035 | |||
1036 | (setup (:straight-if ledger-mode | ||
1037 | (executable-find "ledger"))) | ||
1038 | |||
470 | (setup lines | 1039 | (setup lines |
471 | (:option fill-column 79 | 1040 | (:option fill-column 79 |
472 | word-wrap t | 1041 | word-wrap t |
@@ -490,556 +1059,68 @@ | |||
490 | (delete-indentation 1) | 1059 | (delete-indentation 1) |
491 | (apply fn args))))) | 1060 | (apply fn args))))) |
492 | 1061 | ||
493 | (setup minibuffer | 1062 | (setup (:straight link-hint) |
494 | (:option enable-recursive-minibuffers t | 1063 | ;; Browse web URLs with a browser with a prefix argument. |
495 | file-name-shadow-properties '(invisible t intangible t) | 1064 | (dolist (type '(gnus-w3m-image-url |
496 | minibuffer-eldef-shorten-default t | 1065 | gnus-w3m-url |
497 | minibuffer-prompt-properties | 1066 | markdown-link |
498 | '(read-only t cursor-intangible t face minibuffer-prompt) | 1067 | mu4e-attachment |
499 | read-answer-short t | 1068 | mu4e-url |
500 | read-extended-command-predicate ; used on >28 | 1069 | notmuch-hello |
501 | #'command-completion-default-include-p) | 1070 | nov-link |
502 | 1071 | org-link | |
503 | (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) | 1072 | shr-url |
504 | 1073 | text-url | |
505 | (add-hook 'minibuffer-setup-hook #'acdw/gc-disable) | 1074 | w3m-link |
506 | (add-hook 'minibuffer-exit-hook #'acdw/gc-enable) | 1075 | w3m-message-link)) |
507 | 1076 | (link-hint-define-type type | |
508 | (minibuffer-depth-indicate-mode +1) | 1077 | :open-secondary browse-url-secondary-browser-function)) |
509 | (file-name-shadow-mode +1) | ||
510 | (minibuffer-electric-default-mode +1) | ||
511 | (fset 'yes-or-no-p #'y-or-n-p)) | ||
512 | |||
513 | (setup page | ||
514 | (:option page-delimiter | ||
515 | (rx bol (or "\f" ";;;") | ||
516 | (not (any "#")) (* not-newline) "\n" | ||
517 | (* (* blank) (opt ";" (* not-newline)) "\n"))) | ||
518 | |||
519 | (defun recenter-to-top (&rest _) | ||
520 | "Recenter the cursor to the top of the window." | ||
521 | (when (called-interactively-p 'any) | ||
522 | (recenter (if (or (null scroll-margin) | ||
523 | (zerop scroll-margin)) | ||
524 | 3 | ||
525 | scroll-margin)))) | ||
526 | |||
527 | (:advise forward-page :after #'recenter-to-top | ||
528 | backward-page :after #'recenter-to-top) | ||
529 | |||
530 | ;; I'm not sure where this is in /my/ version of Emacs | ||
531 | (defvar page-navigation-repeat-map | ||
532 | (let ((map (make-sparse-keymap))) | ||
533 | (define-key map "]" #'forward-page) | ||
534 | (define-key map "[" #'backward-page) | ||
535 | map) | ||
536 | "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.") | ||
537 | |||
538 | (put 'forward-page 'repeat-map 'page-navigation-repeat-map) | ||
539 | (put 'backward-page 'repeat-map 'page-navigation-repeat-map)) | ||
540 | |||
541 | (setup prog | ||
542 | (:option show-paren-delay 0 | ||
543 | show-paren-style 'mixed | ||
544 | show-paren-when-point-inside-paren t | ||
545 | show-paren-when-point-in-periphery t | ||
546 | smie-indent-basic tab-width) | ||
547 | |||
548 | (:hook show-paren-mode | ||
549 | electric-pair-local-mode | ||
550 | acdw/setup-fringes | ||
551 | |||
552 | (defun flymake-mode-except () | ||
553 | "Turn on flymake mode, except in some modes." | ||
554 | (let ((no-flymake-modes '(emacs-lisp-mode))) | ||
555 | (unless (or (member major-mode no-flymake-modes) | ||
556 | (apply #'derived-mode-p no-flymake-modes)) | ||
557 | (flymake-mode-on)))) | ||
558 | 1078 | ||
559 | (defun prog-mode@auto-fill () | 1079 | (:option link-hint-avy-style 'at) |
560 | (setq-local comment-auto-fill-only-comments t) | 1080 | (:global "C-;" |
561 | (turn-on-auto-fill))) | 1081 | (defun acdw/link-hint-open-link (arg) |
1082 | "Open a link using `link-hint-open-link', prefix-aware. | ||
1083 | That is, a prefix argument (\\[universal-argument]) will open the | ||
1084 | browser defined in `browse-url-secondary-browser-function'." | ||
1085 | (interactive "P") | ||
1086 | (avy-with link-hint-open-link | ||
1087 | (link-hint--one (if arg :open-secondary :open)))))) | ||
562 | 1088 | ||
563 | (add-hook 'after-save-hook | 1089 | (setup (:straight lua-mode) |
564 | #'executable-make-buffer-file-executable-if-script-p)) | 1090 | (:file-match (rx ".lua" eos))) |
565 | 1091 | ||
566 | (setup repeat | 1092 | (setup (:straight macrostep) |
567 | ;; new for Emacs 28! | ||
568 | (:only-if (fboundp #'repeat-mode)) | ||
569 | 1093 | ||
570 | (:option repeat-exit-key "g" | 1094 | (:with-mode emacs-lisp-mode |
571 | repeat-exit-timeout 5) | 1095 | (:bind "C-c e" #'macrostep-expand))) |
572 | |||
573 | (repeat-mode +1)) | ||
574 | 1096 | ||
575 | (setup saveplace | 1097 | (setup (:straight magit) |
576 | (:option save-place-file (acdw/dir "places.el") | 1098 | (:global "C-c g" #'magit-status) |
577 | save-place-forget-unreadable-files (acdw/system :home)) | ||
578 | |||
579 | (save-place-mode +1)) | ||
580 | 1099 | ||
581 | (setup scratch | 1100 | (:option magit-display-buffer-function |
582 | (:option inhibit-startup-screen t | 1101 | (defun magit-display-buffer-same-window (buffer) |
583 | initial-buffer-choice t | 1102 | "Display BUFFER in the selected window like God intended." |
584 | initial-scratch-message "" | 1103 | (display-buffer buffer '(display-buffer-same-window))) |
585 | ;; (concat ";; Howdy, " | 1104 | magit-popup-display-buffer-action '((display-buffer-same-window)) |
586 | ;; (nth 0 (split-string | 1105 | magit-refresh-status-buffer nil)) |
587 | ;; user-full-name)) | ||
588 | ;; "! " | ||
589 | ;; "Welcome to GNU Emacs.\n\n") | ||
590 | initial-major-mode 'emacs-lisp-mode) | ||
591 | |||
592 | (add-hook 'kill-buffer-query-functions | ||
593 | (defun kill-buffer-query@immortal-scratch () | ||
594 | (if (eq (current-buffer) (get-buffer "*scratch*")) | ||
595 | (progn (bury-buffer) | ||
596 | nil) | ||
597 | t)))) | ||
598 | 1106 | ||
599 | (setup scrolling | 1107 | (setup (:straight marginalia) |
600 | (:option auto-window-vscroll nil | 1108 | (:option marginalia-annotators '(marginalia-annotators-heavy |
601 | fast-but-imprecise-scrolling t | 1109 | marginalia-annotators-light)) |
602 | scroll-margin 3 | 1110 | (marginalia-mode +1)) |
603 | scroll-conservatively 101 | ||
604 | scroll-preserve-screen-position 1)) | ||
605 | 1111 | ||
606 | (setup selection | 1112 | (setup (:straight markdown-mode) |
607 | (:option save-interprogram-paste-before-kill t | 1113 | (:file-match (rx ".md" eos) |
608 | yank-pop-change-selection t | 1114 | (rx ".markdown" eos)) |
609 | x-select-enable-clipboard t | ||
610 | x-select-enable-primary t | ||
611 | mouse-drag-copy-region t | ||
612 | kill-do-not-save-duplicates t) | ||
613 | 1115 | ||
614 | (delete-selection-mode +1)) | 1116 | (:with-mode gfm-mode |
1117 | (:file-match (rx "README.md" eos))) | ||
615 | 1118 | ||
616 | (setup sh-mode | 1119 | (when (executable-find "markdownfmt") |
617 | (:option sh-basic-offset tab-width | ||
618 | sh-indent-after-case 0 | ||
619 | sh-indent-for-case-alt '+ | ||
620 | sh-indent-for-case-label 0) | ||
621 | |||
622 | (:local-set indent-tabs-mode t) | ||
623 | |||
624 | (when (executable-find "shfmt") | ||
625 | (with-eval-after-load 'apheleia | 1120 | (with-eval-after-load 'apheleia |
626 | (:option (append apheleia-formatters) '(shfmt . ("shfmt")) | 1121 | (:option (append apheleia-formatters) '(markdownfmt . ("markdownfmt")) |
627 | (append apheleia-mode-alist) '(sh-mode . shfmt)))) | 1122 | (append apheleia-mode-alist) '(markdown-mode . markdownfmt) |
628 | 1123 | (append apheleia-mode-alist) '(gfm-mode . markdownfmt))))) | |
629 | (when (executable-find "shellcheck") | ||
630 | (:straight flymake-shellcheck) | ||
631 | (:hook flymake-mode | ||
632 | flymake-shellcheck-load))) | ||
633 | |||
634 | (setup shell-command | ||
635 | (:option shell-command-switch (acdw/system | ||
636 | ;; I should be testing on some variable | ||
637 | (:home "-csi") | ||
638 | (:work "-c")) | ||
639 | shell-command-prompt-show-cwd t | ||
640 | shell-command-default-error-buffer "*shell-command-errors*")) | ||
641 | |||
642 | (setup shr | ||
643 | (:option shr-width fill-column | ||
644 | shr-max-width fill-column | ||
645 | shr-max-image-proportion 0.6 | ||
646 | shr-image-animate t | ||
647 | shr-discard-aria-hidden t | ||
648 | shr-folding-mode t)) | ||
649 | |||
650 | (setup text | ||
651 | (:hook turn-on-auto-fill | ||
652 | acdw/setup-fringes)) | ||
653 | |||
654 | (setup uniquify | ||
655 | (:option uniquify-buffer-name-style 'forward | ||
656 | uniquify-separator path-separator | ||
657 | uniquify-after-kill-buffer-p t | ||
658 | uniquify-ignore-buffers-re "^\\*")) | ||
659 | |||
660 | (setup variable-pitch-mode | ||
661 | |||
662 | ;; I might want to change this to `buffer-face-mode-hook'... | ||
663 | (advice-add 'variable-pitch-mode :after | ||
664 | (defun variable-pitch-mode@setup (&rest _) | ||
665 | "Set up `variable-pitch-mode' with my customizations." | ||
666 | (display-fill-column-indicator-mode (if buffer-face-mode | ||
667 | -1 | ||
668 | +1))))) | ||
669 | |||
670 | (setup view | ||
671 | (:option view-read-only t) | ||
672 | |||
673 | (:hook (defun acdw/read-view-mode () | ||
674 | (acdw/reading-mode (if view-mode +1 -1))))) | ||
675 | |||
676 | (setup w32 | ||
677 | (:option w32-allow-system-shell t | ||
678 | w32-pass-lwindow-to-system nil | ||
679 | w32-lwindow-modifier 'super | ||
680 | w32-pass-rwindow-to-system nil | ||
681 | w32-rwindow-modifier 'super | ||
682 | w32-pass-apps-to-system nil | ||
683 | w32-apps-modifier 'hyper)) | ||
684 | |||
685 | (setup whitespace | ||
686 | (:option whitespace-style | ||
687 | '(empty indentation space-before-tab space-after-tab) | ||
688 | indent-tabs-mode nil | ||
689 | tab-width 4 | ||
690 | backward-delete-char-untabify-method 'hungry) | ||
691 | |||
692 | (:global "M-SPC" #'cycle-spacing)) | ||
693 | |||
694 | (setup windmove | ||
695 | (:option windmove-wrap-around t) | ||
696 | (:global | ||
697 | ;; moving | ||
698 | "C-x 4 <left>" #'windmove-left | ||
699 | "C-x 4 <right>" #'windmove-right | ||
700 | "C-x 4 <up>" #'windmove-up | ||
701 | "C-x 4 <down>" #'windmove-down | ||
702 | ;; swapping | ||
703 | "C-x 4 S-<left>" #'windmove-swap-states-left | ||
704 | "C-x 4 S-<right>" #'windmove-swap-states-right | ||
705 | "C-x 4 S-<up>" #'windmove-swap-states-up | ||
706 | "C-x 4 S-<down>" #'windmove-swap-states-down) | ||
707 | |||
708 | (when (fboundp 'repeat-mode) | ||
709 | (defvar windmove-repeat-map | ||
710 | (let ((map (make-sparse-keymap))) | ||
711 | ;; moving | ||
712 | (define-key map [left] #'windmove-left) | ||
713 | (define-key map [right] #'windmove-right) | ||
714 | (define-key map [up] #'windmove-up) | ||
715 | (define-key map [down] #'windmove-down) | ||
716 | ;; swapping | ||
717 | (define-key map [S-left] #'windmove-swap-states-left) | ||
718 | (define-key map [S-right] #'windmove-swap-states-right) | ||
719 | (define-key map [S-up] #'windmove-swap-states-up) | ||
720 | (define-key map [S-down] #'windmove-swap-states-down) | ||
721 | map) | ||
722 | "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.") | ||
723 | |||
724 | (dolist (sym '(windmove-left | ||
725 | windmove-right | ||
726 | windmove-up | ||
727 | windmove-down | ||
728 | windmove-swap-states-left | ||
729 | windmove-swap-states-right | ||
730 | windmove-swap-states-up | ||
731 | windmove-swap-states-down)) | ||
732 | (put sym 'repeat-map 'windmove-repeat-map)))) | ||
733 | |||
734 | (setup window | ||
735 | (require 'acdw-bell) | ||
736 | (:option Man-notify-method 'pushy | ||
737 | display-buffer-alist ; from FrostyX | ||
738 | '(("shell.*" (display-buffer-same-window) ()) | ||
739 | (".*" (display-buffer-reuse-window | ||
740 | display-buffer-same-window) | ||
741 | (reusable-frames . t))) | ||
742 | recenter-positions '(top middle bottom) | ||
743 | ring-bell-function (lambda () | ||
744 | (acdw-bell/flash-mode-line | ||
745 | (acdw/system :home))) | ||
746 | tab-bar-show 1 | ||
747 | use-dialog-box nil | ||
748 | use-file-dialog nil | ||
749 | visible-bell nil) | ||
750 | |||
751 | (tooltip-mode -1)) | ||
752 | |||
753 | (setup winner | ||
754 | ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html | ||
755 | (:global "C-x 4 C-/" #'winner-undo | ||
756 | "C-x 4 /" #'winner-undo | ||
757 | "C-x 4 C-?" #'winner-redo | ||
758 | "C-x 4 ?" #'winner-redo) | ||
759 | |||
760 | ;; add `winner-undo' and `winner-redo' to `repeat-mode' | ||
761 | (when (fboundp 'repeat-mode) | ||
762 | (defvar winner-mode-repeat-map | ||
763 | (let ((map (make-sparse-keymap))) | ||
764 | (define-key map "/" #'winner-undo) | ||
765 | (define-key map "?" #'winner-redo) | ||
766 | map) | ||
767 | "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.") | ||
768 | |||
769 | (put 'winner-undo 'repeat-map 'winner-mode-repeat-map) | ||
770 | (put 'winner-redo 'repeat-map 'winner-mode-repeat-map)) | ||
771 | |||
772 | (winner-mode +1)) | ||
773 | |||
774 | (setup x-emacs | ||
775 | ;; "Et cetera" settings | ||
776 | ;; This should stay as /minimal/ as possible. Anything that can go somewhere | ||
777 | ;; else /should/ go there. | ||
778 | (:option | ||
779 | attempt-orderly-shutdown-on-fatal-signal nil | ||
780 | attempt-stack-overflow-recovery nil | ||
781 | echo-keystrokes 0.01 | ||
782 | find-function-C-source-directory (acdw/find-emacs-source) | ||
783 | kill-read-only-ok t | ||
784 | load-prefer-newer t | ||
785 | native-comp-async-report-warnings-errors nil | ||
786 | set-mark-command-repeat-pop t) | ||
787 | |||
788 | (when (fboundp 'command-completion-default-include-p) | ||
789 | (setq read-extended-command-predicate | ||
790 | #'command-completion-default-include-p)) | ||
791 | |||
792 | (defvar case-map (make-sparse-keymap) | ||
793 | "A keymap for setting case in various ways.") | ||
794 | (global-set-key (kbd "C-c c") case-map) | ||
795 | |||
796 | (defvar lookup-map (make-sparse-keymap) | ||
797 | "A keymap for looking up things.") | ||
798 | (global-set-key (kbd "C-c l") lookup-map) | ||
799 | |||
800 | (:global "M-=" #'count-words | ||
801 | "C-w" #'kill-region-or-backward-word | ||
802 | "C-c c c" #'capitalize-dwim | ||
803 | "C-c c t" #'titlecase-dwim | ||
804 | "C-c c u" #'upcase-dwim | ||
805 | "C-c c l" #'downcase-dwim | ||
806 | "C-c d" #'acdw/insert-iso-date | ||
807 | "M-`" nil) | ||
808 | |||
809 | ;; toggle bindings | ||
810 | (defvar toggle-map (make-sparse-keymap) | ||
811 | "A keymap for toggling!") | ||
812 | (global-set-key (kbd "C-c t") toggle-map) | ||
813 | |||
814 | (:with-map toggle-map | ||
815 | (:bind "c" #'column-number-mode | ||
816 | "l" #'display-line-numbers-mode | ||
817 | "d" #'toggle-debug-on-error)) | ||
818 | |||
819 | (defalias 'forward-word-with-case 'forward-word | ||
820 | "Alias for `forward-word' for use in `case-repeat-map'.") | ||
821 | (defalias 'backward-word-with-case 'backward-word | ||
822 | "Alias for `backward-word for use in `case-repeat-map'.") | ||
823 | |||
824 | (defvar case-repeat-map | ||
825 | (let ((map (make-sparse-keymap))) | ||
826 | (define-key map "c" #'capitalize-word) | ||
827 | (define-key map "u" #'upcase-word) | ||
828 | (define-key map "l" #'downcase-word) | ||
829 | ;; movement | ||
830 | (define-key map "f" #'forward-word-with-case) | ||
831 | (define-key map "b" #'backward-word-with-case) | ||
832 | map) | ||
833 | "A map to repeat word-casing commands. For use with `repeat-mode'.") | ||
834 | |||
835 | (dolist (command '(capitalize-word | ||
836 | capitalize-dwim | ||
837 | upcase-word | ||
838 | upcase-dwim | ||
839 | downcase-word | ||
840 | downcase-dwim | ||
841 | forward-word-with-case | ||
842 | backward-word-with-case)) | ||
843 | (put command 'repeat-map 'case-repeat-map)) | ||
844 | |||
845 | (add-hook 'after-make-frame-functions | ||
846 | (defun after-make-frame@maximize (frame) | ||
847 | (unless (bound-and-true-p edit-server-frame-p) | ||
848 | (toggle-frame-maximized frame))))) | ||
849 | |||
850 | |||
851 | ;;; Packages | ||
852 | |||
853 | (setup (:require gforth) | ||
854 | (:autoload forth-mode | ||
855 | forth-block-mode) | ||
856 | (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode)) | ||
857 | (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))) | ||
858 | |||
859 | (setup (:straight (0x0 :host gitlab | ||
860 | :repo "willvaughn/emacs-0x0")) | ||
861 | (:option 0x0-default-server 'ttm)) | ||
862 | |||
863 | (setup (:straight (apheleia :host github | ||
864 | :repo "raxod502/apheleia")) | ||
865 | |||
866 | (apheleia-global-mode +1) | ||
867 | |||
868 | ;; Use a dumb formatter on modes that `apheleia' doesn't work for. | ||
869 | (add-hook 'before-save-hook | ||
870 | (defun before-save@dumb-auto-format () | ||
871 | (setq stupid-modes '(makefile-mode | ||
872 | org-mode)) | ||
873 | ;; If there's no apheleia formatter for the mode, just indent the | ||
874 | ;; buffer. | ||
875 | (unless (or (apply #'derived-mode-p stupid-modes) | ||
876 | (and (fboundp 'apheleia--get-formatter-command) | ||
877 | (apheleia--get-formatter-command))) | ||
878 | (indent-region (point-min) (point-max)))))) | ||
879 | |||
880 | (setup (:straight (consult | ||
881 | :host github | ||
882 | :repo "minad/consult")) | ||
883 | (require 'acdw-consult) | ||
884 | |||
885 | (setq consult--regexp-compiler #'consult--orderless-regexp-compiler) | ||
886 | |||
887 | ;; Bindings | ||
888 | (:global | ||
889 | ;; C-c bindings (`mode-specific-map') | ||
890 | ;; I don't use any of these right now. | ||
891 | ;; "C-c h" #'consult-history | ||
892 | ;; "C-c m" #'consult-mode-command | ||
893 | ;; "C-c b" #'consult-bookmark | ||
894 | ;; "C-c k" #'consult-kmacro | ||
895 | ;; C-x bindings (`ctl-x-map') | ||
896 | "C-x M-:" #'consult-complex-command | ||
897 | "C-x b" #'consult-buffer | ||
898 | "C-x 4 b" #'consult-buffer-other-window | ||
899 | "C-x 5 b" #'consult-buffer-other-frame | ||
900 | ;; Custom M-# bindings for fast register access | ||
901 | "M-#" #'consult-register-load | ||
902 | "M-'" #'consult-register-store | ||
903 | "C-M-#" #'consult-register | ||
904 | ;; M-g bindings (`goto-map') | ||
905 | "M-g e" #'consult-compile-error | ||
906 | "M-g g" #'consult-goto-line | ||
907 | "M-g M-g" #'consult-goto-line | ||
908 | "M-g o" #'consult-outline | ||
909 | "M-g m" #'consult-mark | ||
910 | "M-g k" #'consult-global-mark | ||
911 | "M-g i" #'consult-imenu | ||
912 | "M-g I" #'consult-project-imenu | ||
913 | ;; M-s bindings (`search-map') | ||
914 | "M-s g" #'acdw-consult/sensible-grep | ||
915 | "M-s f" #'acdw-consult/sensible-find | ||
916 | "M-s l" #'consult-line | ||
917 | "M-s m" #'consult-multi-occur | ||
918 | "M-s k" #'consult-keep-lines | ||
919 | "M-s u" #'consult-focus-lines | ||
920 | ;; Other bindings | ||
921 | "M-y" #'consult-yank-pop | ||
922 | "<help> a" #'consult-apropos | ||
923 | ;; Isearch integration | ||
924 | "M-s e" #'consult-isearch) | ||
925 | (:with-map isearch-mode-map | ||
926 | (:bind "M-e" #'consult-isearch | ||
927 | "M-s e" #'consult-isearch | ||
928 | "M-s l" #'consult-line)) | ||
929 | |||
930 | ;; see https://github.com/oantolin/completing-history | ||
931 | (defmacro consult-history-to-modes (map-hook-alist) | ||
932 | (let (defuns) | ||
933 | (dolist (map-hook map-hook-alist) | ||
934 | (let ((map-name (symbol-name (car map-hook))) | ||
935 | (key-defs `(progn (define-key | ||
936 | ,(car map-hook) | ||
937 | (kbd "M-r") | ||
938 | (function consult-history)) | ||
939 | (define-key ,(car map-hook) | ||
940 | (kbd "M-s") nil)))) | ||
941 | (push (if (cdr map-hook) | ||
942 | `(add-hook ',(cdr map-hook) | ||
943 | (defun | ||
944 | ,(intern (concat map-name | ||
945 | "@consult-history-bind")) | ||
946 | nil | ||
947 | ,(concat | ||
948 | "Bind `consult-history' to M-r in " | ||
949 | map-name ".\n" | ||
950 | "Defined by `consult-history-to-modes'.") | ||
951 | ,key-defs)) | ||
952 | key-defs) | ||
953 | defuns))) | ||
954 | `(progn ,@ (nreverse defuns)))) | ||
955 | |||
956 | (consult-history-to-modes ((minibuffer-local-map . nil) | ||
957 | (shell-mode-map . shell-mode-hook) | ||
958 | (term-mode-map . term-mode-hook) | ||
959 | (term-raw-map . term-mode-hook) | ||
960 | (comint-mode-map . comint-mode-hook) | ||
961 | (sly-mrepl-mode-map . sly-mrepl-hook))) | ||
962 | |||
963 | |||
964 | |||
965 | ;; Registers | ||
966 | (:autoload consult-register-preview) | ||
967 | (:option register-preview-delay 0 | ||
968 | register-preview-function #'consult-register-format) | ||
969 | (:advise register-preview :override #'consult-register-window) | ||
970 | |||
971 | ;; Xref | ||
972 | (:option xref-show-xrefs-function #'consult-xref | ||
973 | xref-show-definitions-function #'consult-xref) | ||
974 | |||
975 | ;; Projects | ||
976 | (:option consult-project-root-function #'vc-root-dir) | ||
977 | |||
978 | ;; Competion-at-point (complete-region) | ||
979 | (:option completion-in-region-function #'acdw-consult/complete-in-region | ||
980 | completion-cycle-threshold 3 | ||
981 | tab-always-indent 'complete) | ||
982 | |||
983 | ;; Completing-read-multple | ||
984 | (if (fboundp #'consult-completing-read-multiple) | ||
985 | (:advise completing-read-multple | ||
986 | :override #'consult-completing-read-multiple) | ||
987 | ;; else | ||
988 | (defun crm-indicator (args) | ||
989 | (cons (concat "[CRM] " (car args)) (cdr args))) | ||
990 | (:advise completing-read-multiple | ||
991 | :filter-args #'crm-indicator)) | ||
992 | |||
993 | (with-eval-after-loads (vertico consult) | ||
994 | (when (boundp 'consult-crm-map) | ||
995 | (define-key consult-crm-map "\r" #'+vertico-crm-exit) | ||
996 | (define-key consult-crm-map "\t" #'vertico-exit) | ||
997 | (defun +vertico-crm-exit () | ||
998 | (interactive) | ||
999 | (run-at-time 0 nil #'vertico-exit) | ||
1000 | (funcall #'vertico-exit))))) | ||
1001 | |||
1002 | (setup (:straight (electric-cursor | ||
1003 | :host github | ||
1004 | :repo "duckwork/electric-cursor")) | ||
1005 | (electric-cursor-mode +1)) | ||
1006 | |||
1007 | (setup (:straight (elpher :host nil | ||
1008 | :repo "git://thelambdalab.xyz/elpher.git")) | ||
1009 | (:option elpher-ipv4-always t | ||
1010 | elpher-certificate-directory (acdw/dir "elpher/") | ||
1011 | elpher-gemini-max-fill-width fill-column) | ||
1012 | |||
1013 | (:bind "n" #'elpher-next-link | ||
1014 | "p" #'elpher-prev-link | ||
1015 | "o" #'elpher-follow-current-link | ||
1016 | "G" #'elpher-go-current) | ||
1017 | |||
1018 | (:hook acdw/reading-mode) | ||
1019 | |||
1020 | (:autoload (elpher-bookmarks :interactive t) | ||
1021 | (elpher-go :interactive t)) | ||
1022 | |||
1023 | ;; Make `eww' gemini/gopher aware. From Emacswiki. | ||
1024 | ;; (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher) | ||
1025 | ;; (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url) | ||
1026 | ;; (require 'elpher) | ||
1027 | ;; (elpher-go url)) | ||
1028 | ;; (t (apply fn url args)))) | ||
1029 | ) | ||
1030 | |||
1031 | (setup (:straight (gemini-mode | ||
1032 | :host nil | ||
1033 | :repo "https://git.carcosa.net/jmcbray/gemini.el.git")) | ||
1034 | (:file-match (rx (seq "." (or "gemini" "gmi") eos))) | ||
1035 | (:hook turn-off-auto-fill)) | ||
1036 | |||
1037 | (setup (:straight (gemini-write | ||
1038 | :host nil | ||
1039 | :repo "https://alexschroeder.ch/cgit/gemini-write" | ||
1040 | :branch "main")) | ||
1041 | (with-eval-after-load 'elpher | ||
1042 | (require 'gemini-write))) | ||
1043 | 1124 | ||
1044 | (setup (:straight (mastodon | 1125 | (setup (:straight (mastodon |
1045 | :host github | 1126 | :host github |
@@ -1052,6 +1133,26 @@ | |||
1052 | (:hook #'hl-line-mode | 1133 | (:hook #'hl-line-mode |
1053 | #'acdw/reading-mode)) | 1134 | #'acdw/reading-mode)) |
1054 | 1135 | ||
1136 | (setup minibuffer | ||
1137 | (:option enable-recursive-minibuffers t | ||
1138 | file-name-shadow-properties '(invisible t intangible t) | ||
1139 | minibuffer-eldef-shorten-default t | ||
1140 | minibuffer-prompt-properties | ||
1141 | '(read-only t cursor-intangible t face minibuffer-prompt) | ||
1142 | read-answer-short t | ||
1143 | read-extended-command-predicate ; used on >28 | ||
1144 | #'command-completion-default-include-p) | ||
1145 | |||
1146 | (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) | ||
1147 | |||
1148 | (add-hook 'minibuffer-setup-hook #'acdw/gc-disable) | ||
1149 | (add-hook 'minibuffer-exit-hook #'acdw/gc-enable) | ||
1150 | |||
1151 | (minibuffer-depth-indicate-mode +1) | ||
1152 | (file-name-shadow-mode +1) | ||
1153 | (minibuffer-electric-default-mode +1) | ||
1154 | (fset 'yes-or-no-p #'y-or-n-p)) | ||
1155 | |||
1055 | (setup (:straight (modus-themes | 1156 | (setup (:straight (modus-themes |
1056 | :host gitlab | 1157 | :host gitlab |
1057 | :repo "protesilaos/modus-themes")) | 1158 | :repo "protesilaos/modus-themes")) |
@@ -1066,6 +1167,24 @@ | |||
1066 | (acdw/sunrise-sunset #'modus-themes-load-operandi | 1167 | (acdw/sunrise-sunset #'modus-themes-load-operandi |
1067 | #'modus-themes-load-vivendi)) | 1168 | #'modus-themes-load-vivendi)) |
1068 | 1169 | ||
1170 | (setup (:straight mwim) | ||
1171 | (:global "C-a" #'mwim-beginning | ||
1172 | "C-e" #'mwim-end)) | ||
1173 | |||
1174 | (setup (:straight nov) | ||
1175 | (:option nov-text-width fill-column) | ||
1176 | (:file-match (rx ".epub" eos))) | ||
1177 | |||
1178 | (setup (:straight olivetti) | ||
1179 | (:option olivetti-body-width (+ fill-column 4) | ||
1180 | olivetti-minimum-body-width fill-column) | ||
1181 | |||
1182 | (:hook (defun olivetti-mode@setup () | ||
1183 | (if olivetti-mode | ||
1184 | (setq-local indicate-empty-lines nil | ||
1185 | indicate-buffer-boundaries nil) | ||
1186 | (acdw/setup-fringes))))) | ||
1187 | |||
1069 | (setup (:straight (orderless | 1188 | (setup (:straight (orderless |
1070 | :host github | 1189 | :host github |
1071 | :repo "oantolin/orderless")) | 1190 | :repo "oantolin/orderless")) |
@@ -1123,434 +1242,6 @@ | |||
1123 | ((string-suffix-p "~" pattern) | 1242 | ((string-suffix-p "~" pattern) |
1124 | `(orderless-flex . ,(substring pattern 0 -1)))))) | 1243 | `(orderless-flex . ,(substring pattern 0 -1)))))) |
1125 | 1244 | ||
1126 | (setup (:straight (topsy | ||
1127 | :host github | ||
1128 | :repo "alphapapa/topsy.el")) | ||
1129 | (:hook-into prog-mode)) | ||
1130 | |||
1131 | (setup (:straight (unfocused | ||
1132 | :host github | ||
1133 | :repo "duckwork/unfocused")) | ||
1134 | (unfocused-mode +1)) | ||
1135 | |||
1136 | (setup (:straight (vertico | ||
1137 | :host github | ||
1138 | :repo "minad/vertico" | ||
1139 | :files ("*" "extensions/*" | ||
1140 | (:exclude ".git")))) | ||
1141 | |||
1142 | (:option resize-mini-windows 'grow-only | ||
1143 | vertico-count-format nil | ||
1144 | vertico-cycle t) | ||
1145 | |||
1146 | (:with-map vertico-map | ||
1147 | (:bind "<C-backspace>" | ||
1148 | (defun up-directory (arg) | ||
1149 | "Move up a directory (delete backwards to /)." | ||
1150 | (interactive "p") | ||
1151 | (if (string-match-p "/." (minibuffer-contents)) | ||
1152 | (zap-up-to-char (- arg) ?/) | ||
1153 | (backward-kill-word arg))))) | ||
1154 | |||
1155 | (if (boundp 'comp-deferred-compilation-deny-list) | ||
1156 | (add-to-list 'comp-deferred-compilation-deny-list "vertico")) | ||
1157 | |||
1158 | (vertico-mode +1) | ||
1159 | |||
1160 | ;; Extensions! | ||
1161 | (:also-load vertico-mouse) | ||
1162 | (vertico-mouse-mode +1) | ||
1163 | |||
1164 | ;; Prefix the current candidate with "> ". From Vertico wiki. | ||
1165 | |||
1166 | (:advise vertico--format-candidate :around | ||
1167 | (defun vertico-format@add-arrow (orig cand pref suf index start) | ||
1168 | (setq cand (funcall orig cand pref suf index start)) | ||
1169 | (concat (if (= vertico--index index) | ||
1170 | (propertize "> " 'face 'vertico-current) | ||
1171 | " ") | ||
1172 | cand)))) | ||
1173 | |||
1174 | (setup (:straight alert) | ||
1175 | (:option alert-default-style (acdw/system | ||
1176 | (:home 'libnotify) | ||
1177 | (_ 'message)))) | ||
1178 | |||
1179 | (setup (:straight async) | ||
1180 | (:autoload (dired-async-mode :interactive t)) | ||
1181 | (dired-async-mode +1) | ||
1182 | |||
1183 | (add-hook 'dired-mode | ||
1184 | (defun dired@disable-dired-async-mode-line () | ||
1185 | (autoload 'dired-async--modeline-mode "dired-async.el" nil t) | ||
1186 | (dired-async--modeline-mode -1)))) | ||
1187 | |||
1188 | (setup (:straight avy) | ||
1189 | (:global "C-:" #'avy-goto-char-timer | ||
1190 | "C-c C-j" #'avy-resume) | ||
1191 | |||
1192 | (:with-feature isearch | ||
1193 | (:bind "C-'" #'avy-isearch))) | ||
1194 | |||
1195 | (setup (:straight circe) | ||
1196 | (require 'circe) | ||
1197 | (require 'acdw-irc) | ||
1198 | |||
1199 | (:option acdw-irc/left-margin 12 | ||
1200 | acdw-irc/post-my-nick "-> " | ||
1201 | circe-channel-killed-confirmation nil | ||
1202 | circe-color-nicks-everywhere t | ||
1203 | circe-default-nick "acdw" | ||
1204 | circe-default-part-message "See You, Space Cowpokes . . ." | ||
1205 | circe-default-user "acdw" | ||
1206 | circe-format-action | ||
1207 | (lambda (&rest plist) | ||
1208 | (concat | ||
1209 | (acdw-irc/margin-format "" "*" "*" t) | ||
1210 | " " (plist-get plist :nick) " " (plist-get plist :body))) | ||
1211 | circe-format-say | ||
1212 | (lambda (&rest plist) | ||
1213 | (concat | ||
1214 | (acdw-irc/margin-format (plist-get plist :nick) "" " |" t) | ||
1215 | " " (plist-get plist :body))) | ||
1216 | circe-format-self-action | ||
1217 | (lambda (&rest plist) | ||
1218 | (concat | ||
1219 | (acdw-irc/margin-format "" "-*" " *" t) | ||
1220 | " " (plist-get plist :nick) " " (plist-get plist :body))) | ||
1221 | circe-format-self-say | ||
1222 | (lambda (&rest plist) | ||
1223 | (concat | ||
1224 | (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t) | ||
1225 | " " (plist-get plist :body))) | ||
1226 | circe-highlight-nick-type 'sender | ||
1227 | circe-network-options | ||
1228 | `(("Libera Chat" | ||
1229 | :channels ("#emacs" "#systemcrafters" "##webpals") | ||
1230 | :sasl-username circe-default-nick | ||
1231 | :sasl-password ,(acdw/make-password-fetcher | ||
1232 | :host "libera.chat")) | ||
1233 | ("Tilde Chat" :host "irc.tilde.chat" :port 6697 :use-tls t | ||
1234 | :channels ("#meta" "#bread" "#dadjokes" "#team") | ||
1235 | :sasl-username circe-default-nick | ||
1236 | :sasl-password ,(acdw/make-password-fetcher | ||
1237 | :host "tilde.chat")) | ||
1238 | ("Casa" :host "m455.casa" :port 6697 :use-tls t | ||
1239 | :channels ("#basement") | ||
1240 | :sasl-username circe-default-nick | ||
1241 | :sasl-password ,(acdw/make-password-fetcher | ||
1242 | :host "m455.casa")) | ||
1243 | ("Piss" :host "piss.hmm.st" :port 6697 :use-tls t)) | ||
1244 | circe-reduce-lurker-spam t | ||
1245 | circe-server-auto-join-default-type :after-auth) | ||
1246 | |||
1247 | (custom-set-faces '(circe-nick-highlight-face | ||
1248 | ((t (:inherit (modus-themes-hl-line)))) | ||
1249 | :now)) | ||
1250 | |||
1251 | (:bind "C-c C-p" #'circe-command-PART) | ||
1252 | |||
1253 | (:advise circe-command-PART :after | ||
1254 | (defun circe-command-PART@kill-buffer (&rest _) | ||
1255 | (let ((circe-channel-killed-confirmation nil)) | ||
1256 | (kill-buffer)))) | ||
1257 | |||
1258 | (:with-mode circe-chat-mode | ||
1259 | (:hook #'acdw/stop-paren-annoyances | ||
1260 | (defun circe-chat@setup () | ||
1261 | (lui-set-prompt | ||
1262 | (concat (propertize (acdw-irc/margin-format (buffer-name) | ||
1263 | "" | ||
1264 | ">") | ||
1265 | 'face 'circe-prompt-face | ||
1266 | 'read-only t 'intangible t | ||
1267 | 'cursor-intangible t) | ||
1268 | " ")) | ||
1269 | (enable-circe-color-nicks) | ||
1270 | (enable-circe-display-images) | ||
1271 | (enable-circe-new-day-notifier)))) | ||
1272 | |||
1273 | (autoload 'circe-nick-color-reset "circe-color-nicks") | ||
1274 | (add-hook 'modus-themes-after-load-theme-hook | ||
1275 | #'circe-nick-color-reset) | ||
1276 | |||
1277 | (:with-mode lui-mode | ||
1278 | (:option lui-fill-column fill-column | ||
1279 | lui-fill-type (repeat-string acdw-irc/left-margin " ") | ||
1280 | lui-time-stamp-position 'right-margin | ||
1281 | lui-time-stamp-format "%H:%M" | ||
1282 | lui-track-behavior 'before-switch-to-buffer | ||
1283 | lui-track-indicator 'fringe) | ||
1284 | |||
1285 | (:hook (defun lui-mode@setup () | ||
1286 | (setq-local fringes-outside-margins t | ||
1287 | right-margin-width 5 | ||
1288 | scroll-margin 0 | ||
1289 | word-wrap t | ||
1290 | wrap-prefix (repeat-string | ||
1291 | acdw-irc/left-margin " ") | ||
1292 | line-number-mode nil) | ||
1293 | (enable-lui-track))))) | ||
1294 | |||
1295 | (setup (:straight crux) | ||
1296 | |||
1297 | (:global "C-x o" #'acdw/other-window-or-switch-buffer | ||
1298 | "C-o" #'crux-smart-open-line | ||
1299 | "M-o" #'crux-smart-open-line-above | ||
1300 | "C-M-\\" #'crux-cleanup-buffer-or-region | ||
1301 | "C-x 4 t" #'crux-transpose-windows) | ||
1302 | |||
1303 | (when (fboundp 'repeat-mode) | ||
1304 | (unless (boundp 'other-window-repeat-map) | ||
1305 | (defvar other-window-repeat-map (make-sparse-keymap) | ||
1306 | "A map for repeating `other-window' keys.")) | ||
1307 | |||
1308 | (define-key other-window-repeat-map "o" | ||
1309 | #'acdw/other-window-or-switch-buffer) | ||
1310 | (define-key other-window-repeat-map "O" | ||
1311 | (defun acdw/other-window-or-switch-buffer-backward () | ||
1312 | (interactive) | ||
1313 | (setq repeat-map 'other-window-repeat-map) | ||
1314 | (acdw/other-window-or-switch-buffer -1))) | ||
1315 | |||
1316 | (put 'acdw/other-window-or-switch-buffer | ||
1317 | 'repeat-map 'other-window-repeat-map)) | ||
1318 | |||
1319 | (crux-reopen-as-root-mode +1)) | ||
1320 | |||
1321 | ;; requires extension: | ||
1322 | ;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/ | ||
1323 | (setup (:straight edit-server) | ||
1324 | (when (and (daemonp) | ||
1325 | (require 'edit-server nil :noerror)) | ||
1326 | (edit-server-start) | ||
1327 | |||
1328 | (:advise edit-server-make-frame :before | ||
1329 | (defun edit-server@set-a-variable (&rest _) | ||
1330 | (setq-local edit-server-frame-p t))))) | ||
1331 | |||
1332 | (setup (:straight elfeed | ||
1333 | elfeed-protocol) | ||
1334 | (:option elfeed-use-curl t | ||
1335 | elfeed-feeds `(("fever+https://acdw@mf.acdw.net" | ||
1336 | :api-url "https://mf.acdw.net/fever/" | ||
1337 | :password ,(acdw/make-password-fetcher | ||
1338 | :host "mf.acdw.net")))) | ||
1339 | |||
1340 | (elfeed-protocol-enable) | ||
1341 | |||
1342 | (:with-mode elfeed-show-mode | ||
1343 | (:hook (defun elfeed-show@setup () | ||
1344 | (acdw/reading-mode))) | ||
1345 | |||
1346 | ;; see https://irreal.org/blog/?p=8885 | ||
1347 | (:bind "SPC" (defun elfeed-scroll-up-command (&optional arg) | ||
1348 | "Scroll up or go to next feed item in Elfeed" | ||
1349 | (interactive "^P") | ||
1350 | (let ((scroll-error-top-bottom nil)) | ||
1351 | (condition-case-unless-debug nil | ||
1352 | (scroll-up-command arg) | ||
1353 | (error (elfeed-show-next))))) | ||
1354 | "S-SPC" (defun elfeed-scroll-down-command (&optional arg) | ||
1355 | "Scroll up or go to next feed item in Elfeed" | ||
1356 | (interactive "^P") | ||
1357 | (let ((scroll-error-top-bottom nil)) | ||
1358 | (condition-case-unless-debug nil | ||
1359 | (scroll-down-command arg) | ||
1360 | (error (elfeed-show-prev)))))))) | ||
1361 | |||
1362 | (setup (:straight elisp-slime-nav) | ||
1363 | (:hook-into emacs-lisp-mode | ||
1364 | ielm-mode)) | ||
1365 | |||
1366 | (setup (:straight embark) | ||
1367 | (:global "C-." #'embark-act) | ||
1368 | (:option prefix-help-command #'embark-prefix-help-command | ||
1369 | (append display-buffer-alist) | ||
1370 | '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" | ||
1371 | nil | ||
1372 | (window-parameters (mode-line-format . none))) | ||
1373 | embark-prompter #'embark-keymap-prompter | ||
1374 | embark-verbose-indicator-display-action | ||
1375 | '(display-buffer-at-bottom (window-height . fit-window-to-buffer))) | ||
1376 | |||
1377 | (setq embark-action-indicator | ||
1378 | (lambda (map _target) | ||
1379 | (which-key--show-keymap "Embark" map nil nil 'no-paging) | ||
1380 | #'which-key--hide-popup-ignore-command) | ||
1381 | embark-become-indicator embark-action-indicator) | ||
1382 | |||
1383 | (with-eval-after-loads (embark consult) | ||
1384 | (:straight embark-consult) | ||
1385 | (add-hook 'embark-collect-mode-hook | ||
1386 | #'consult-preview-at-point-mode))) | ||
1387 | |||
1388 | (setup (:straight epithet) | ||
1389 | (dolist (hook '(Info-selection-hook | ||
1390 | eww-after-render-hook | ||
1391 | help-mode-hook | ||
1392 | occur-mode-hook)) | ||
1393 | (add-hook hook #'epithet-rename-buffer))) | ||
1394 | |||
1395 | (setup (:straight eros) | ||
1396 | (:hook-into emacs-lisp-mode)) | ||
1397 | |||
1398 | (setup (:straight esh-autosuggest) | ||
1399 | (:autoload esh-autosuggest-mode) | ||
1400 | (:hook-into eshell-mode)) | ||
1401 | |||
1402 | (setup (:straight expand-region) | ||
1403 | (:global "C-=" #'er/expand-region | ||
1404 | "C-SPC" | ||
1405 | (defun acdw/set-mark-or-expand-region (arg) | ||
1406 | "Set mark at point and activate, jump to mark, or expand region. | ||
1407 | See `set-mark-command' and `expand-region'. | ||
1408 | |||
1409 | With no prefix argument, either run `set-mark-command' on first | ||
1410 | invocation and `er/expand-region' on each successive invocation. | ||
1411 | |||
1412 | With any prefix argument | ||
1413 | (e.g., \\[universal-argument] \\[set-mark-command]), act as with | ||
1414 | `set-mark-command' (i.e., pop the mark). Don't care about | ||
1415 | successive invocations." | ||
1416 | (interactive "P") | ||
1417 | (cond | ||
1418 | ((or arg | ||
1419 | (and set-mark-command-repeat-pop | ||
1420 | (eq last-command 'pop-to-mark-command))) | ||
1421 | (setq this-command 'set-mark-command) | ||
1422 | (set-mark-command arg)) | ||
1423 | ((eq last-command 'acdw/set-mark-or-expand-region) | ||
1424 | (er/expand-region 1)) | ||
1425 | (t (set-mark-command arg)))))) | ||
1426 | |||
1427 | (setup (:straight flyspell-correct) | ||
1428 | (:with-mode flyspell-mode | ||
1429 | (:hook (defun flyspell@correct () | ||
1430 | (:bind "C-;" #'flyspell-correct-wrapper) | ||
1431 | (:unbind "C-," "C-." "C-M-i"))))) | ||
1432 | |||
1433 | (setup (:straight gcmh) | ||
1434 | (:option gcmh-idle-delay 'auto) | ||
1435 | (gcmh-mode +1)) | ||
1436 | |||
1437 | ;; TODO: figure out a popper.el / shackle.el ... thing to fix this | ||
1438 | (setup (:straight helpful) | ||
1439 | (:option helpful-max-buffers 5) | ||
1440 | (:global "<help> f" #'helpful-callable | ||
1441 | "<help> v" #'helpful-variable | ||
1442 | "<help> k" #'helpful-key | ||
1443 | "<help> o" #'helpful-symbol)) | ||
1444 | |||
1445 | (setup (:straight hungry-delete) | ||
1446 | (:option hungry-delete-chars-to-skip " \t" | ||
1447 | hungry-delete-join-reluctantly nil) | ||
1448 | |||
1449 | (global-hungry-delete-mode +1) | ||
1450 | |||
1451 | (:with-feature paredit | ||
1452 | (:bind [remap paredit-backward-delete] | ||
1453 | (defun acdw/paredit-hungry-delete-backward (arg) | ||
1454 | (interactive "P") | ||
1455 | (if (looking-back "[ \t]" 1) | ||
1456 | (hungry-delete-backward (or arg 1)) | ||
1457 | (paredit-backward-delete arg))) | ||
1458 | |||
1459 | [remap paredit-forward-delete] | ||
1460 | (defun acdw/paredit-hungry-delete-forward (arg) | ||
1461 | (interactive "P") | ||
1462 | (if (looking-at "[ \t]") | ||
1463 | (hungry-delete-forward (or arg 1)) | ||
1464 | (paredit-forward-delete arg)))))) | ||
1465 | |||
1466 | (setup (:straight iscroll) | ||
1467 | (define-globalized-minor-mode global-iscroll-mode iscroll-mode | ||
1468 | (lambda () (iscroll-mode +1))) | ||
1469 | |||
1470 | (global-iscroll-mode +1)) | ||
1471 | |||
1472 | (setup (:straight lacarte) | ||
1473 | (:global "<f10>" #'lacarte-execute-menu-command)) | ||
1474 | |||
1475 | (setup (:straight link-hint) | ||
1476 | ;; Browse web URLs with a browser with a prefix argument. | ||
1477 | (dolist (type '(gnus-w3m-image-url | ||
1478 | gnus-w3m-url | ||
1479 | markdown-link | ||
1480 | mu4e-attachment | ||
1481 | mu4e-url | ||
1482 | notmuch-hello | ||
1483 | nov-link | ||
1484 | org-link | ||
1485 | shr-url | ||
1486 | text-url | ||
1487 | w3m-link | ||
1488 | w3m-message-link)) | ||
1489 | (link-hint-define-type type | ||
1490 | :open-secondary browse-url-secondary-browser-function)) | ||
1491 | |||
1492 | (:option link-hint-avy-style 'at) | ||
1493 | (:global "C-;" | ||
1494 | (defun acdw/link-hint-open-link (arg) | ||
1495 | "Open a link using `link-hint-open-link', prefix-aware. | ||
1496 | That is, a prefix argument (\\[universal-argument]) will open the | ||
1497 | browser defined in `browse-url-secondary-browser-function'." | ||
1498 | (interactive "P") | ||
1499 | (avy-with link-hint-open-link | ||
1500 | (link-hint--one (if arg :open-secondary :open)))))) | ||
1501 | |||
1502 | (setup (:straight lua-mode) | ||
1503 | (:file-match (rx ".lua" eos))) | ||
1504 | |||
1505 | (setup (:straight macrostep) | ||
1506 | (:with-mode emacs-lisp-mode | ||
1507 | (:bind "C-c e" #'macrostep-expand))) | ||
1508 | |||
1509 | (setup (:straight magit) | ||
1510 | (:global "C-c g" #'magit-status) | ||
1511 | |||
1512 | (:option magit-display-buffer-function | ||
1513 | (defun magit-display-buffer-same-window (buffer) | ||
1514 | "Display BUFFER in the selected window like God intended." | ||
1515 | (display-buffer buffer '(display-buffer-same-window))) | ||
1516 | magit-popup-display-buffer-action '((display-buffer-same-window)) | ||
1517 | magit-refresh-status-buffer nil)) | ||
1518 | |||
1519 | (setup (:straight marginalia) | ||
1520 | (:option marginalia-annotators '(marginalia-annotators-heavy | ||
1521 | marginalia-annotators-light)) | ||
1522 | (marginalia-mode +1)) | ||
1523 | |||
1524 | (setup (:straight markdown-mode) | ||
1525 | (dolist (cell '(("README\\.md\\'" . gfm-mode) | ||
1526 | ("\\.md\\'" . markdown-mode) | ||
1527 | ("\\.markdown\\'" . markdown-mode))) | ||
1528 | (add-to-list 'auto-mode-alist cell)) | ||
1529 | |||
1530 | (when (executable-find "markdownfmt") | ||
1531 | (with-eval-after-load 'apheleia | ||
1532 | (:option (append apheleia-formatters) '(markdownfmt . ("markdownfmt")) | ||
1533 | (append apheleia-mode-alist) '(markdown-mode . markdownfmt) | ||
1534 | (append apheleia-mode-alist) '(gfm-mode . markdownfmt))))) | ||
1535 | |||
1536 | (setup (:straight mwim) | ||
1537 | (:global "C-a" #'mwim-beginning | ||
1538 | "C-e" #'mwim-end)) | ||
1539 | |||
1540 | (setup (:straight nov) | ||
1541 | (:option nov-text-width fill-column) | ||
1542 | (:file-match (rx ".epub" eos))) | ||
1543 | |||
1544 | (setup (:straight olivetti) | ||
1545 | (:option olivetti-body-width (+ fill-column 4) | ||
1546 | olivetti-minimum-body-width fill-column) | ||
1547 | |||
1548 | (:hook (defun olivetti-mode@setup () | ||
1549 | (if olivetti-mode | ||
1550 | (setq-local indicate-empty-lines nil | ||
1551 | indicate-buffer-boundaries nil) | ||
1552 | (acdw/setup-fringes))))) | ||
1553 | |||
1554 | (setup (:straight org | 1245 | (setup (:straight org |
1555 | org-contrib) | 1246 | org-contrib) |
1556 | (:also-load 'acdw-org) ; so I don't clutter up init.el | 1247 | (:also-load 'acdw-org) ; so I don't clutter up init.el |
@@ -1598,8 +1289,8 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1598 | "C-c C-p" #'acdw/org-previous-heading-widen) | 1289 | "C-c C-p" #'acdw/org-previous-heading-widen) |
1599 | 1290 | ||
1600 | (with-eval-after-load 'org-export | 1291 | (with-eval-after-load 'org-export |
1601 | (add-to-list 'org-export-filter-final-output-functions | 1292 | (:option (append org-export-filter-final-output-functions) |
1602 | #'org-export-remove-zero-width-spaces)) | 1293 | #'org-export-remove-zero-width-spaces)) |
1603 | 1294 | ||
1604 | (:hook variable-pitch-mode | 1295 | (:hook variable-pitch-mode |
1605 | olivetti-mode | 1296 | olivetti-mode |
@@ -1626,6 +1317,34 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1626 | 1317 | ||
1627 | (setup (:straight package-lint-flymake)) | 1318 | (setup (:straight package-lint-flymake)) |
1628 | 1319 | ||
1320 | (setup page | ||
1321 | (:option page-delimiter | ||
1322 | (rx bol (or "\f" ";;;") | ||
1323 | (not (any "#")) (* not-newline) "\n" | ||
1324 | (* (* blank) (opt ";" (* not-newline)) "\n"))) | ||
1325 | |||
1326 | (defun recenter-to-top (&rest _) | ||
1327 | "Recenter the cursor to the top of the window." | ||
1328 | (when (called-interactively-p 'any) | ||
1329 | (recenter (if (or (null scroll-margin) | ||
1330 | (zerop scroll-margin)) | ||
1331 | 3 | ||
1332 | scroll-margin)))) | ||
1333 | |||
1334 | (:advise forward-page :after #'recenter-to-top | ||
1335 | backward-page :after #'recenter-to-top) | ||
1336 | |||
1337 | ;; I'm not sure where this is in /my/ version of Emacs | ||
1338 | (defvar page-navigation-repeat-map | ||
1339 | (let ((map (make-sparse-keymap))) | ||
1340 | (define-key map "]" #'forward-page) | ||
1341 | (define-key map "[" #'backward-page) | ||
1342 | map) | ||
1343 | "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.") | ||
1344 | |||
1345 | (put 'forward-page 'repeat-map 'page-navigation-repeat-map) | ||
1346 | (put 'backward-page 'repeat-map 'page-navigation-repeat-map)) | ||
1347 | |||
1629 | (setup (:straight page-break-lines) | 1348 | (setup (:straight page-break-lines) |
1630 | (global-page-break-lines-mode +1)) | 1349 | (global-page-break-lines-mode +1)) |
1631 | 1350 | ||
@@ -1652,6 +1371,13 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1652 | (dolist (mode lispy-modes) | 1371 | (dolist (mode lispy-modes) |
1653 | (add-hook (intern (concat (symbol-name mode) "-hook")) #'paren-face-mode))) | 1372 | (add-hook (intern (concat (symbol-name mode) "-hook")) #'paren-face-mode))) |
1654 | 1373 | ||
1374 | (setup (:straight-if (pdf-tools | ||
1375 | :host github | ||
1376 | :repo "vedang/pdf-tools") | ||
1377 | (acdw/system :home)) | ||
1378 | (:file-match (rx ".pdf" eos)) | ||
1379 | (pdf-loader-install)) | ||
1380 | |||
1655 | (setup (:straight persistent-scratch) | 1381 | (setup (:straight persistent-scratch) |
1656 | (:option persistent-scratch-backup-directory (acdw/dir "scratch" t) | 1382 | (:option persistent-scratch-backup-directory (acdw/dir "scratch" t) |
1657 | persistent-scratch-keep-n-newest-backups 12) | 1383 | persistent-scratch-keep-n-newest-backups 12) |
@@ -1664,19 +1390,171 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1664 | (persistent-scratch-mode +1)))) | 1390 | (persistent-scratch-mode +1)))) |
1665 | (buffer-list))) | 1391 | (buffer-list))) |
1666 | 1392 | ||
1393 | (setup (:straight-if pkgbuild-mode | ||
1394 | (executable-find "makepkg")) | ||
1395 | (:file-match "PKGBUILD")) | ||
1396 | |||
1667 | (setup (:straight powerthesaurus) | 1397 | (setup (:straight powerthesaurus) |
1668 | (:global "C-c l t" #'powerthesaurus-lookup-word-dwim)) | 1398 | (:global "C-c l t" #'powerthesaurus-lookup-word-dwim)) |
1669 | 1399 | ||
1400 | (setup prog | ||
1401 | (:option show-paren-delay 0 | ||
1402 | show-paren-style 'mixed | ||
1403 | show-paren-when-point-inside-paren t | ||
1404 | show-paren-when-point-in-periphery t | ||
1405 | smie-indent-basic tab-width) | ||
1406 | |||
1407 | (:hook show-paren-mode | ||
1408 | electric-pair-local-mode | ||
1409 | acdw/setup-fringes | ||
1410 | |||
1411 | (defun flymake-mode-except () | ||
1412 | "Turn on flymake mode, except in some modes." | ||
1413 | (let ((no-flymake-modes '(emacs-lisp-mode))) | ||
1414 | (unless (or (member major-mode no-flymake-modes) | ||
1415 | (apply #'derived-mode-p no-flymake-modes)) | ||
1416 | (flymake-mode-on)))) | ||
1417 | |||
1418 | (defun prog-mode@auto-fill () | ||
1419 | (setq-local comment-auto-fill-only-comments t) | ||
1420 | (turn-on-auto-fill))) | ||
1421 | |||
1422 | (add-hook 'after-save-hook | ||
1423 | #'executable-make-buffer-file-executable-if-script-p)) | ||
1424 | |||
1425 | (setup (:require recentf) | ||
1426 | (:option recentf-save-file (acdw/dir "recentf.el") | ||
1427 | recentf-max-menu-items 100 | ||
1428 | recentf-max-saved-items nil | ||
1429 | recentf-auto-cleanup 'mode | ||
1430 | (append recentf-exclude) (acdw/dir)) | ||
1431 | |||
1432 | (:advise dired-rename-file :after #'rjs/recentf-rename-notify) | ||
1433 | |||
1434 | (recentf-mode +1)) | ||
1435 | |||
1436 | (setup repeat | ||
1437 | ;; new for Emacs 28! | ||
1438 | (:only-if (fboundp #'repeat-mode)) | ||
1439 | |||
1440 | (:option repeat-exit-key "g" | ||
1441 | repeat-exit-timeout 5) | ||
1442 | |||
1443 | (repeat-mode +1)) | ||
1444 | |||
1670 | (setup (:straight restart-emacs) | 1445 | (setup (:straight restart-emacs) |
1671 | (defun emacs-upgrade (&optional update-packages) | 1446 | (defun emacs-upgrade (&optional update-packages) |
1672 | "Pull config, upgrade packages, restart Emacs." | 1447 | "Pull config, upgrade packages, restart Emacs." |
1673 | (interactive "P") | 1448 | (interactive "P") |
1674 | (emacs-git-pull-config) | 1449 | (emacs-git-pull-config) |
1675 | (when update-packages | 1450 | (when update-packages |
1676 | (require 'straight) | 1451 | (require 'straight-x) |
1677 | (straight-pull-all)) | 1452 | (straight-x-pull-all)) |
1678 | (restart-emacs))) | 1453 | (restart-emacs))) |
1679 | 1454 | ||
1455 | (setup (:require savehist) | ||
1456 | (:option history-length t | ||
1457 | history-delete-duplicates t | ||
1458 | savehist-autosave-interval 60 | ||
1459 | savehist-file (acdw/dir "savehist.el")) | ||
1460 | |||
1461 | (dolist (var '(extended-command-history | ||
1462 | global-mark-ring | ||
1463 | kill-ring | ||
1464 | regexp-search-ring | ||
1465 | search-ring | ||
1466 | mark-ring)) | ||
1467 | (:option (append savehist-additional-variables) var)) | ||
1468 | |||
1469 | (savehist-mode +1)) | ||
1470 | |||
1471 | (setup saveplace | ||
1472 | (:option save-place-file (acdw/dir "places.el") | ||
1473 | save-place-forget-unreadable-files (acdw/system :home)) | ||
1474 | |||
1475 | (save-place-mode +1)) | ||
1476 | |||
1477 | (setup scratch | ||
1478 | (:option inhibit-startup-screen t | ||
1479 | initial-buffer-choice t | ||
1480 | initial-scratch-message "" | ||
1481 | ;; (concat ";; Howdy, " | ||
1482 | ;; (nth 0 (split-string | ||
1483 | ;; user-full-name)) | ||
1484 | ;; "! " | ||
1485 | ;; "Welcome to GNU Emacs.\n\n") | ||
1486 | initial-major-mode 'emacs-lisp-mode) | ||
1487 | |||
1488 | (add-hook 'kill-buffer-query-functions | ||
1489 | (defun kill-buffer-query@immortal-scratch () | ||
1490 | (if (eq (current-buffer) (get-buffer "*scratch*")) | ||
1491 | (progn (bury-buffer) | ||
1492 | nil) | ||
1493 | t)))) | ||
1494 | |||
1495 | (setup scrolling | ||
1496 | (:option auto-window-vscroll nil | ||
1497 | fast-but-imprecise-scrolling t | ||
1498 | scroll-margin 3 | ||
1499 | scroll-conservatively 101 | ||
1500 | scroll-preserve-screen-position 1)) | ||
1501 | |||
1502 | (setup selection | ||
1503 | (:option save-interprogram-paste-before-kill t | ||
1504 | yank-pop-change-selection t | ||
1505 | x-select-enable-clipboard t | ||
1506 | x-select-enable-primary t | ||
1507 | mouse-drag-copy-region t | ||
1508 | kill-do-not-save-duplicates t) | ||
1509 | |||
1510 | (delete-selection-mode +1)) | ||
1511 | |||
1512 | (setup (:require server) | ||
1513 | (unless (server-running-p) | ||
1514 | (server-start))) | ||
1515 | |||
1516 | (setup sh-mode | ||
1517 | (:option sh-basic-offset tab-width | ||
1518 | sh-indent-after-case 0 | ||
1519 | sh-indent-for-case-alt '+ | ||
1520 | sh-indent-for-case-label 0) | ||
1521 | |||
1522 | (:local-set indent-tabs-mode t) | ||
1523 | |||
1524 | (when (executable-find "shfmt") | ||
1525 | (with-eval-after-load 'apheleia | ||
1526 | (:option (append apheleia-formatters) '(shfmt . ("shfmt")) | ||
1527 | (append apheleia-mode-alist) '(sh-mode . shfmt)))) | ||
1528 | |||
1529 | (when (executable-find "shellcheck") | ||
1530 | (:straight flymake-shellcheck) | ||
1531 | (:hook flymake-mode | ||
1532 | flymake-shellcheck-load))) | ||
1533 | |||
1534 | (setup shell-command | ||
1535 | (:option shell-command-switch (acdw/system | ||
1536 | ;; I should be testing on some variable | ||
1537 | (:home "-csi") | ||
1538 | (:work "-c")) | ||
1539 | shell-command-prompt-show-cwd t | ||
1540 | shell-command-default-error-buffer "*shell-command-errors*")) | ||
1541 | |||
1542 | (setup (:straight (shell-command+ | ||
1543 | :host nil | ||
1544 | :repo "https://git.sr.ht/~pkal/shell-command-plus")) | ||
1545 | (:option shell-command-prompt "$ ") | ||
1546 | (:with-feature dired | ||
1547 | (:bind "M-!" shell-command+)) | ||
1548 | (:global "M-!" shell-command+)) | ||
1549 | |||
1550 | (setup shr | ||
1551 | (:option shr-width fill-column | ||
1552 | shr-max-width fill-column | ||
1553 | shr-max-image-proportion 0.6 | ||
1554 | shr-image-animate t | ||
1555 | shr-discard-aria-hidden t | ||
1556 | shr-folding-mode t)) | ||
1557 | |||
1680 | (setup (:straight simple-modeline | 1558 | (setup (:straight simple-modeline |
1681 | minions) | 1559 | minions) |
1682 | (:also-load acdw-modeline) | 1560 | (:also-load acdw-modeline) |
@@ -1716,15 +1594,60 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1716 | 1594 | ||
1717 | (simple-modeline-mode +1)) | 1595 | (simple-modeline-mode +1)) |
1718 | 1596 | ||
1597 | (setup (:straight-if sly | ||
1598 | (progn | ||
1599 | (defvar acdw/lisps | ||
1600 | (let (lisps) | ||
1601 | (dolist (lisp '("sbcl" ; TODO: add more lisps | ||
1602 | "clisp")) | ||
1603 | (when-let (binary (executable-find lisp)) | ||
1604 | (push binary lisps))) | ||
1605 | (nreverse lisps))) | ||
1606 | acdw/lisps)) | ||
1607 | (:also-load sly-autoloads) | ||
1608 | (:straight clhs) | ||
1609 | |||
1610 | (:option inferior-lisp-program acdw/lisp-bin | ||
1611 | sly-kill-without-query-p t) | ||
1612 | |||
1613 | (:with-feature sly-mrepl | ||
1614 | (defun sly-mrepl-return-at-end () | ||
1615 | (interactive) | ||
1616 | (if (<= (point-max) (point)) | ||
1617 | (sly-mrepl-return) | ||
1618 | (if (bound-and-true-p paredit-mode) | ||
1619 | (paredit-newline) | ||
1620 | (electric-newline-and-maybe-indent)))) | ||
1621 | |||
1622 | (dolist (key '("RET" "<return>")) | ||
1623 | (:bind key #'sly-mrepl-return-at-end)) | ||
1624 | |||
1625 | (:bind "C-c C-c" #'sly-mrepl-return))) | ||
1626 | |||
1719 | (setup (:straight ssh-config-mode) | 1627 | (setup (:straight ssh-config-mode) |
1720 | (dolist (spec '(("/\\.ssh/config\\'" . ssh-config-mode) | 1628 | (:file-match (rx "/.ssh/config" eos) |
1721 | ("/sshd?_config\\'" . ssh-config-mode) | 1629 | (rx "/ssh" (? "d") "_config" eos)) |
1722 | ("/knownhosts\\'" . ssh-known-hosts-mode) | 1630 | |
1723 | ("/authorized_keys2?\\'" . ssh-authorized-keys-mode))) | 1631 | (:with-mode ssh-known-hosts-mode |
1724 | (add-to-list 'auto-mode-alist spec)) | 1632 | (:file-match (rx "/knownhosts" eos))) |
1633 | |||
1634 | (:with-mode ssh-authorized-keys-mode | ||
1635 | (:file-match (rx "/authorized_keys" (? "2") eos))) | ||
1725 | 1636 | ||
1726 | (:hook #'turn-on-font-lock)) | 1637 | (:hook #'turn-on-font-lock)) |
1727 | 1638 | ||
1639 | (setup (:straight-if systemd | ||
1640 | (executable-find "systemd"))) | ||
1641 | |||
1642 | (setup text | ||
1643 | (:hook turn-on-auto-fill | ||
1644 | acdw/setup-fringes)) | ||
1645 | |||
1646 | (setup (:straight (topsy | ||
1647 | :host github | ||
1648 | :repo "alphapapa/topsy.el")) | ||
1649 | (:hook-into prog-mode)) | ||
1650 | |||
1728 | (setup (:straight typo) | 1651 | (setup (:straight typo) |
1729 | 1652 | ||
1730 | ;; Enable C-c 8 map in all buffers | 1653 | ;; Enable C-c 8 map in all buffers |
@@ -1747,7 +1670,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1747 | ;; consideration, not an input consideration. (I suppose you could make | 1670 | ;; consideration, not an input consideration. (I suppose you could make |
1748 | ;; the argument that all of these are typographical considerations, but | 1671 | ;; the argument that all of these are typographical considerations, but |
1749 | ;; .. bleh.) | 1672 | ;; .. bleh.) |
1750 | |||
1751 | (:bind "'" (define-typo-cycle typo-cycle-apostrophe | 1673 | (:bind "'" (define-typo-cycle typo-cycle-apostrophe |
1752 | "Cycle through apostrophe-like graphemes. | 1674 | "Cycle through apostrophe-like graphemes. |
1753 | If used with a numeric prefix argument N, N apostrophes will be inserted." | 1675 | If used with a numeric prefix argument N, N apostrophes will be inserted." |
@@ -1771,11 +1693,85 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
1771 | 1693 | ||
1772 | (setup (:straight unfill)) | 1694 | (setup (:straight unfill)) |
1773 | 1695 | ||
1696 | (setup (:straight (unfocused | ||
1697 | :host github | ||
1698 | :repo "duckwork/unfocused")) | ||
1699 | (unfocused-mode +1)) | ||
1700 | |||
1701 | (setup uniquify | ||
1702 | (:option uniquify-buffer-name-style 'forward | ||
1703 | uniquify-separator path-separator | ||
1704 | uniquify-after-kill-buffer-p t | ||
1705 | uniquify-ignore-buffers-re "^\\*")) | ||
1706 | |||
1707 | (setup variable-pitch-mode | ||
1708 | ;; I might want to change this to `buffer-face-mode-hook'... | ||
1709 | (:advise variable-pitch-mode :after | ||
1710 | (defun variable-pitch-mode@setup (&rest _) | ||
1711 | "Set up `variable-pitch-mode' with my customizations." | ||
1712 | (display-fill-column-indicator-mode (if buffer-face-mode | ||
1713 | -1 | ||
1714 | +1))))) | ||
1715 | |||
1716 | (setup (:straight (vertico | ||
1717 | :host github | ||
1718 | :repo "minad/vertico" | ||
1719 | :files ("*" "extensions/*" | ||
1720 | (:exclude ".git")))) | ||
1721 | |||
1722 | (:option resize-mini-windows 'grow-only | ||
1723 | vertico-count-format nil | ||
1724 | vertico-cycle t) | ||
1725 | |||
1726 | (:with-map vertico-map | ||
1727 | (:bind "<C-backspace>" | ||
1728 | (defun up-directory (arg) | ||
1729 | "Move up a directory (delete backwards to /)." | ||
1730 | (interactive "p") | ||
1731 | (if (string-match-p "/." (minibuffer-contents)) | ||
1732 | (zap-up-to-char (- arg) ?/) | ||
1733 | (backward-kill-word arg))))) | ||
1734 | |||
1735 | (when (boundp 'native-comp-deferred-compilation-deny-list) | ||
1736 | (add-to-list 'native-comp-deferred-compilation-deny-list "vertico")) | ||
1737 | |||
1738 | (vertico-mode +1) | ||
1739 | |||
1740 | ;; Extensions! | ||
1741 | (:also-load vertico-mouse) | ||
1742 | (vertico-mouse-mode +1) | ||
1743 | |||
1744 | ;; Prefix the current candidate with "> ". From Vertico wiki. | ||
1745 | (:advise vertico--format-candidate :around | ||
1746 | (defun vertico-format@add-arrow (orig cand pref suf index start) | ||
1747 | (setq cand (funcall orig cand pref suf index start)) | ||
1748 | (concat (if (= vertico--index index) | ||
1749 | (propertize "> " 'face 'vertico-current) | ||
1750 | " ") | ||
1751 | cand)))) | ||
1752 | |||
1753 | (setup view | ||
1754 | (:option view-read-only t) | ||
1755 | |||
1756 | (:hook (defun acdw/read-view-mode () | ||
1757 | (acdw/reading-mode (if view-mode +1 -1))))) | ||
1758 | |||
1774 | (setup (:straight visual-regexp) | 1759 | (setup (:straight visual-regexp) |
1775 | (:global "M-%" #'vr/query-replace)) | 1760 | (:global "M-%" #'vr/query-replace)) |
1776 | 1761 | ||
1777 | (setup (:straight wc-mode) ; TODO: move some of this stuff around | 1762 | (setup (:straight-if vterm |
1763 | (acdw/system :home))) | ||
1778 | 1764 | ||
1765 | (setup w32 | ||
1766 | (:option w32-allow-system-shell t | ||
1767 | w32-pass-lwindow-to-system nil | ||
1768 | w32-lwindow-modifier 'super | ||
1769 | w32-pass-rwindow-to-system nil | ||
1770 | w32-rwindow-modifier 'super | ||
1771 | w32-pass-apps-to-system nil | ||
1772 | w32-apps-modifier 'hyper)) | ||
1773 | |||
1774 | (setup (:straight wc-mode) | ||
1779 | (:option wc-modeline-format "[%tww]" | 1775 | (:option wc-modeline-format "[%tww]" |
1780 | wc-idle-wait 2) | 1776 | wc-idle-wait 2) |
1781 | 1777 | ||
@@ -1786,13 +1782,14 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
1786 | js-indent-level 2 | 1782 | js-indent-level 2 |
1787 | sgml-indent-offset 2) | 1783 | sgml-indent-offset 2) |
1788 | 1784 | ||
1789 | (:file-match "\\.\\(p\\|dj\\)?html\\'" | 1785 | (:file-match (rx ".htm" (? "l") eos) |
1790 | "\\.html?\\'" | 1786 | (rx "." (? "tpl.") "php" eos) |
1791 | "\\.\\(tpl\\.\\)?php\\'" | 1787 | (rx "." (| "asp" "gsp" "jsp") eos) |
1792 | "\\.[agj]sp\\'" | 1788 | (rx "." (| "ascx" "aspx") eos) |
1793 | "\\.as[cp]x\\'" | 1789 | (rx ".erb" eos) |
1794 | "\\.erb\\'" | 1790 | (rx ".mustache" eos))) |
1795 | "\\.mustache\\'")) | 1791 | |
1792 | (setup (:straight wgrep)) | ||
1796 | 1793 | ||
1797 | (setup (:straight which-key) | 1794 | (setup (:straight which-key) |
1798 | (:option which-key-show-early-on-C-h t | 1795 | (:option which-key-show-early-on-C-h t |
@@ -1805,9 +1802,98 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
1805 | (which-key-setup-side-window-right-bottom) | 1802 | (which-key-setup-side-window-right-bottom) |
1806 | (which-key-mode +1)) | 1803 | (which-key-mode +1)) |
1807 | 1804 | ||
1805 | (setup whitespace | ||
1806 | (:option whitespace-style | ||
1807 | '(empty indentation space-before-tab space-after-tab) | ||
1808 | indent-tabs-mode nil | ||
1809 | tab-width 4 | ||
1810 | backward-delete-char-untabify-method 'hungry) | ||
1811 | |||
1812 | (:global "M-SPC" #'cycle-spacing)) | ||
1813 | |||
1808 | (setup (:straight whitespace-cleanup-mode) | 1814 | (setup (:straight whitespace-cleanup-mode) |
1809 | (global-whitespace-cleanup-mode +1)) | 1815 | (global-whitespace-cleanup-mode +1)) |
1810 | 1816 | ||
1817 | (setup windmove | ||
1818 | (:option windmove-wrap-around t) | ||
1819 | (:global | ||
1820 | ;; moving | ||
1821 | "C-x 4 <left>" #'windmove-left | ||
1822 | "C-x 4 <right>" #'windmove-right | ||
1823 | "C-x 4 <up>" #'windmove-up | ||
1824 | "C-x 4 <down>" #'windmove-down | ||
1825 | ;; swapping | ||
1826 | "C-x 4 S-<left>" #'windmove-swap-states-left | ||
1827 | "C-x 4 S-<right>" #'windmove-swap-states-right | ||
1828 | "C-x 4 S-<up>" #'windmove-swap-states-up | ||
1829 | "C-x 4 S-<down>" #'windmove-swap-states-down) | ||
1830 | |||
1831 | (when (fboundp 'repeat-mode) | ||
1832 | (defvar windmove-repeat-map | ||
1833 | (let ((map (make-sparse-keymap))) | ||
1834 | ;; moving | ||
1835 | (define-key map [left] #'windmove-left) | ||
1836 | (define-key map [right] #'windmove-right) | ||
1837 | (define-key map [up] #'windmove-up) | ||
1838 | (define-key map [down] #'windmove-down) | ||
1839 | ;; swapping | ||
1840 | (define-key map [S-left] #'windmove-swap-states-left) | ||
1841 | (define-key map [S-right] #'windmove-swap-states-right) | ||
1842 | (define-key map [S-up] #'windmove-swap-states-up) | ||
1843 | (define-key map [S-down] #'windmove-swap-states-down) | ||
1844 | map) | ||
1845 | "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.") | ||
1846 | |||
1847 | (dolist (sym '(windmove-left | ||
1848 | windmove-right | ||
1849 | windmove-up | ||
1850 | windmove-down | ||
1851 | windmove-swap-states-left | ||
1852 | windmove-swap-states-right | ||
1853 | windmove-swap-states-up | ||
1854 | windmove-swap-states-down)) | ||
1855 | (put sym 'repeat-map 'windmove-repeat-map)))) | ||
1856 | |||
1857 | (setup window | ||
1858 | (require 'acdw-bell) | ||
1859 | (:option Man-notify-method 'pushy | ||
1860 | display-buffer-alist ; from FrostyX | ||
1861 | '(("shell.*" (display-buffer-same-window) ()) | ||
1862 | (".*" (display-buffer-reuse-window | ||
1863 | display-buffer-same-window) | ||
1864 | (reusable-frames . t))) | ||
1865 | recenter-positions '(top middle bottom) | ||
1866 | ring-bell-function (lambda () | ||
1867 | (acdw-bell/flash-mode-line | ||
1868 | (acdw/system :home))) | ||
1869 | tab-bar-show 1 | ||
1870 | use-dialog-box nil | ||
1871 | use-file-dialog nil | ||
1872 | visible-bell nil) | ||
1873 | |||
1874 | (tooltip-mode -1)) | ||
1875 | |||
1876 | (setup winner | ||
1877 | ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html | ||
1878 | (:global "C-x 4 C-/" #'winner-undo | ||
1879 | "C-x 4 /" #'winner-undo | ||
1880 | "C-x 4 C-?" #'winner-redo | ||
1881 | "C-x 4 ?" #'winner-redo) | ||
1882 | |||
1883 | ;; add `winner-undo' and `winner-redo' to `repeat-mode' | ||
1884 | (when (fboundp 'repeat-mode) | ||
1885 | (defvar winner-mode-repeat-map | ||
1886 | (let ((map (make-sparse-keymap))) | ||
1887 | (define-key map "/" #'winner-undo) | ||
1888 | (define-key map "?" #'winner-redo) | ||
1889 | map) | ||
1890 | "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.") | ||
1891 | |||
1892 | (put 'winner-undo 'repeat-map 'winner-mode-repeat-map) | ||
1893 | (put 'winner-redo 'repeat-map 'winner-mode-repeat-map)) | ||
1894 | |||
1895 | (winner-mode +1)) | ||
1896 | |||
1811 | (setup (:straight winum) | 1897 | (setup (:straight winum) |
1812 | (:option winum-scope 'frame-local | 1898 | (:option winum-scope 'frame-local |
1813 | winum-auto-setup-mode-line nil | 1899 | winum-auto-setup-mode-line nil |
@@ -1834,154 +1920,93 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
1834 | 1920 | ||
1835 | (winum-mode +1)) | 1921 | (winum-mode +1)) |
1836 | 1922 | ||
1837 | (setup (:straight xr)) | 1923 | (setup x-emacs |
1838 | 1924 | ;; "Et cetera" settings | |
1839 | (setup (:straight zzz-to-char) | 1925 | ;; This should stay as /minimal/ as possible. Anything that can go somewhere |
1840 | 1926 | ;; else /should/ go there. | |
1841 | (:global "M-z" | ||
1842 | (defun acdw/zzz-up-to-char (prefix) | ||
1843 | "Call `zzz-up-to-char' or `zzz-to-char', PREFIX-depending." | ||
1844 | (interactive "P") | ||
1845 | (if prefix | ||
1846 | (call-interactively #'zzz-to-char) | ||
1847 | (call-interactively #'zzz-up-to-char))))) | ||
1848 | |||
1849 | (setup (:straight-if (pdf-tools | ||
1850 | :host github | ||
1851 | :repo "vedang/pdf-tools") | ||
1852 | (acdw/system :home)) | ||
1853 | (:file-match (rx ".pdf" eos)) | ||
1854 | (pdf-loader-install)) | ||
1855 | |||
1856 | (setup (:straight-if affe | ||
1857 | (and (or (executable-find "fd") | ||
1858 | (executable-find "find")) | ||
1859 | (executable-find "rg"))) | ||
1860 | ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find' | ||
1861 | (:option affe-regexp-compiler | ||
1862 | (defun affe-orderless-regexp-compiler (input _type) | ||
1863 | (setq input (orderless-pattern-compiler input)) | ||
1864 | (cons input (lambda (str) (orderless--highlight input str)))))) | ||
1865 | |||
1866 | (setup (:straight-if ahk-mode | ||
1867 | (acdw/system :work))) | ||
1868 | |||
1869 | ;; TODO: look into emms or something related for this | ||
1870 | (setup (:straight-if eradio | ||
1871 | (executable-find "mpv")) | ||
1872 | (:option | 1927 | (:option |
1873 | eradio-player '("mpv" "--no-video" "--no-terminal") | 1928 | attempt-orderly-shutdown-on-fatal-signal nil |
1874 | eradio-channels `(("KLSU" . | 1929 | attempt-stack-overflow-recovery nil |
1875 | "http://130.39.238.143:8010/stream.mp3") | 1930 | echo-keystrokes 0.01 |
1876 | ("Soma FM Synphaera" . | 1931 | find-function-C-source-directory (acdw/find-emacs-source) |
1877 | "https://somafm.com/synphaera256.pls") | 1932 | kill-read-only-ok t |
1878 | ("SomaFM BAGel Radio" . | 1933 | load-prefer-newer t |
1879 | "https://somafm.com/bagel.pls") | 1934 | native-comp-async-report-warnings-errors nil |
1880 | ("SomaFM Boot Liquor" . | 1935 | set-mark-command-repeat-pop t) |
1881 | "https://somafm.com/bootliquor320.pls") | ||
1882 | ("SomaFM Deep Space One" . | ||
1883 | "https://somafm.com/deepspaceone.pls") | ||
1884 | ("SomaFM Fluid" . | ||
1885 | "https://somafm.com/fluid.pls") | ||
1886 | ("SomaFM Underground 80s" . | ||
1887 | "https://somafm.com/u80s256.pls") | ||
1888 | ("WBRH: Jazz & More" . | ||
1889 | "http://wbrh.streamguys1.com/wbrh-mp3") | ||
1890 | ("KBRH Blues & Rhythm Hits" . | ||
1891 | "http://wbrh.streamguys1.com/kbrh-mp3") | ||
1892 | ("WRKF HD-2" . | ||
1893 | ,(concat "https://playerservices.streamtheworld.com/" | ||
1894 | "api/livestream-redirect/WRKFHD2.mp3")) | ||
1895 | ("WRKF: NPR for the Capital Region" . | ||
1896 | ,(concat "https://playerservices.streamtheworld.com/" | ||
1897 | "api/livestream-redirect/WRKFFM.mp3")) | ||
1898 | ("BadRadio: 24/7 PHONK" . | ||
1899 | "https://s2.radio.co/s2b2b68744/listen") | ||
1900 | ("tilderadio" . | ||
1901 | "https://radio.tildeverse.org/radio/8000/radio.ogg") | ||
1902 | ("vantaradio" . | ||
1903 | "https://vantaa.black/radio"))) | ||
1904 | (:global "C-c r r" #'eradio-play ; mnemonic: radio | ||
1905 | "C-c r s" #'eradio-stop ; mnemonic: stop | ||
1906 | "C-c r p" #'eradio-toggle ; mnemonic: play/pause | ||
1907 | )) | ||
1908 | 1936 | ||
1909 | (setup (:straight-if exec-path-from-shell | 1937 | (when (fboundp 'command-completion-default-include-p) |
1910 | (acdw/system :home)) | 1938 | (setq read-extended-command-predicate |
1911 | (when (daemonp) | 1939 | #'command-completion-default-include-p)) |
1912 | (exec-path-from-shell-initialize))) | ||
1913 | 1940 | ||
1914 | (setup (:straight-if fennel-mode | 1941 | (defvar case-map (make-sparse-keymap) |
1915 | (executable-find "fennel")) | 1942 | "A keymap for setting case in various ways.") |
1916 | (:autoload (fennel-repl :interactive t)) | 1943 | (global-set-key (kbd "C-c c") case-map) |
1917 | (:file-match (rx ".fnl" eos))) | ||
1918 | 1944 | ||
1919 | (setup (:straight-if geiser | 1945 | (defvar lookup-map (make-sparse-keymap) |
1920 | (progn | 1946 | "A keymap for looking up things.") |
1921 | (defvar acdw/schemes | 1947 | (global-set-key (kbd "C-c l") lookup-map) |
1922 | (let (schemes) | 1948 | |
1923 | (dolist (scheme '(("scheme" . geiser-chez) ; chez | 1949 | (:global "M-=" #'count-words |
1924 | ("petite" . geiser-chez) ; petite | 1950 | "C-w" #'kill-region-or-backward-word |
1925 | ("csi" . geiser-chez) ; chicken | 1951 | "C-c c c" #'capitalize-dwim |
1926 | ("gsi" . geiser-gambit) | 1952 | "C-c c t" #'titlecase-dwim |
1927 | ("gosh" . geiser-gauche) | 1953 | "C-c c u" #'upcase-dwim |
1928 | ("guile" . geiser-guile) | 1954 | "C-c c l" #'downcase-dwim |
1929 | ("kawa" . geiser-kawa) | 1955 | "C-c d" #'acdw/insert-iso-date |
1930 | ("mit-scheme" . geiser-mit) | 1956 | "M-`" nil) |
1931 | ("racket" . geiser-racket) | ||
1932 | ("stklos" . geiser-stklos))) | ||
1933 | (when-let (binary (executable-find (car scheme))) | ||
1934 | (push binary schemes) | ||
1935 | ;; and install the proper helper package | ||
1936 | (straight-use-package (cdr scheme)))) | ||
1937 | (nreverse schemes))) | ||
1938 | acdw/schemes)) | ||
1939 | (:file-match (rx ".rkt" eos) | ||
1940 | (rx ".scm" eos))) | ||
1941 | 1957 | ||
1942 | (setup (:straight-if ledger-mode | 1958 | ;; toggle bindings |
1943 | (executable-find "ledger"))) | 1959 | (defvar toggle-map (make-sparse-keymap) |
1960 | "A keymap for toggling!") | ||
1961 | (global-set-key (kbd "C-c t") toggle-map) | ||
1944 | 1962 | ||
1945 | (setup (:straight-if pkgbuild-mode | 1963 | (:with-map toggle-map |
1946 | (executable-find "makepkg")) | 1964 | (:bind "c" #'column-number-mode |
1947 | (:file-match "PKGBUILD")) | 1965 | "l" #'display-line-numbers-mode |
1966 | "d" #'toggle-debug-on-error)) | ||
1948 | 1967 | ||
1949 | (setup (:straight-if sly | 1968 | (defalias 'forward-word-with-case 'forward-word |
1950 | (progn | 1969 | "Alias for `forward-word' for use in `case-repeat-map'.") |
1951 | (defvar acdw/lisps | 1970 | (defalias 'backward-word-with-case 'backward-word |
1952 | (let (lisps) | 1971 | "Alias for `backward-word for use in `case-repeat-map'.") |
1953 | (dolist (lisp '("sbcl" ; TODO: add more lisps | ||
1954 | "clisp")) | ||
1955 | (when-let (binary (executable-find lisp)) | ||
1956 | (push binary lisps))) | ||
1957 | (nreverse lisps))) | ||
1958 | acdw/lisps)) | ||
1959 | (:also-load sly-autoloads) | ||
1960 | (:straight clhs) | ||
1961 | |||
1962 | (:option inferior-lisp-program acdw/lisp-bin | ||
1963 | sly-kill-without-query-p t) | ||
1964 | 1972 | ||
1965 | (defun sly-mrepl-return-at-end () | 1973 | (defvar case-repeat-map |
1966 | (interactive) | 1974 | (let ((map (make-sparse-keymap))) |
1967 | (if (<= (point-max) (point)) | 1975 | (define-key map "c" #'capitalize-word) |
1968 | (sly-mrepl-return) | 1976 | (define-key map "u" #'upcase-word) |
1969 | (if (bound-and-true-p paredit-mode) | 1977 | (define-key map "l" #'downcase-word) |
1970 | (paredit-newline) | 1978 | ;; movement |
1971 | (electric-newline-and-maybe-indent)))) | 1979 | (define-key map "f" #'forward-word-with-case) |
1980 | (define-key map "b" #'backward-word-with-case) | ||
1981 | map) | ||
1982 | "A map to repeat word-casing commands. For use with `repeat-mode'.") | ||
1972 | 1983 | ||
1973 | (:with-feature sly-mrepl | 1984 | (dolist (command '(capitalize-word |
1974 | (dolist (key '("RET" "<return>")) | 1985 | capitalize-dwim |
1975 | (:bind key #'sly-mrepl-return-at-end)) | 1986 | upcase-word |
1976 | (:bind "C-c C-c" #'sly-mrepl-return))) | 1987 | upcase-dwim |
1988 | downcase-word | ||
1989 | downcase-dwim | ||
1990 | forward-word-with-case | ||
1991 | backward-word-with-case)) | ||
1992 | (put command 'repeat-map 'case-repeat-map)) | ||
1977 | 1993 | ||
1978 | (setup (:straight-if systemd | 1994 | (add-hook 'after-make-frame-functions |
1979 | (executable-find "systemd"))) | 1995 | (defun after-make-frame@maximize (frame) |
1996 | (unless (bound-and-true-p edit-server-frame-p) | ||
1997 | (toggle-frame-maximized frame))))) | ||
1980 | 1998 | ||
1981 | (setup (:straight-if vterm | 1999 | (setup (:straight xr)) |
1982 | (acdw/system :home))) | ||
1983 | 2000 | ||
1984 | (setup (:straight wgrep)) | 2001 | (setup (:straight zzz-to-char) |
2002 | |||
2003 | (:global "M-z" | ||
2004 | (defun acdw/zzz-up-to-char (prefix) | ||
2005 | "Call `zzz-up-to-char' or `zzz-to-char', PREFIX-depending." | ||
2006 | (interactive "P") | ||
2007 | (if prefix | ||
2008 | (call-interactively #'zzz-to-char) | ||
2009 | (call-interactively #'zzz-up-to-char))))) | ||
1985 | 2010 | ||
1986 | 2011 | ||
1987 | ;;; init.el ends here | 2012 | ;;; init.el ends here |
diff --git a/lisp/acdw.el b/lisp/acdw.el index 8db7fea..cf8914f 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el | |||
@@ -19,7 +19,9 @@ | |||
19 | ;; functions for me, acdw. | 19 | ;; functions for me, acdw. |
20 | 20 | ||
21 | ;;; Code: | 21 | ;;; Code: |
22 | 22 | ||
23 | (require 'cl-lib) | ||
24 | |||
23 | ;;; Variables | 25 | ;;; Variables |
24 | 26 | ||
25 | (defconst acdw/system | 27 | (defconst acdw/system |
@@ -242,10 +244,12 @@ With a prefix argument N, (un)comment that many sexps." | |||
242 | 244 | ||
243 | ;;; Sort sexps | 245 | ;;; Sort sexps |
244 | ;; from https://github.com/alphapapa/unpackaged.el#sort-sexps | 246 | ;; from https://github.com/alphapapa/unpackaged.el#sort-sexps |
247 | ;; and https://github.com/alphapapa/unpackaged.el/issues/20 | ||
245 | 248 | ||
246 | (defun sort-sexps (beg end) | 249 | (defun sort-sexps (beg end &optional key) |
247 | "Sort sexps in region. | 250 | "Sort sexps in region. |
248 | Comments stay with the code below." | 251 | Comments stay with the code below. KEY is a function to sort by, |
252 | e.g. (lambda (sexp) (symbol-name (car sexp)))" | ||
249 | (interactive "r") | 253 | (interactive "r") |
250 | (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n")))) | 254 | (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n")))) |
251 | (goto-char (match-end 0)))) | 255 | (goto-char (match-end 0)))) |
@@ -270,11 +274,16 @@ Comments stay with the code below." | |||
270 | for end = (point-marker) | 274 | for end = (point-marker) |
271 | while sexp | 275 | while sexp |
272 | ;; Collect the real string, then one used for sorting. | 276 | ;; Collect the real string, then one used for sorting. |
273 | collect (cons (buffer-substring (marker-position start) (marker-position end)) | 277 | collect (cons (buffer-substring (marker-position start) |
278 | (marker-position end)) | ||
274 | (save-excursion | 279 | (save-excursion |
275 | (goto-char (marker-position start)) | 280 | (goto-char (marker-position start)) |
276 | (skip-both) | 281 | (skip-both) |
277 | (buffer-substring (point) (marker-position end)))) | 282 | (if key |
283 | (funcall key sexp) | ||
284 | (buffer-substring | ||
285 | (point) | ||
286 | (marker-position end))))) | ||
278 | into sexps | 287 | into sexps |
279 | collect (cons start end) | 288 | collect (cons start end) |
280 | into markers | 289 | into markers |