summary refs log tree commit diff stats
path: root/init.el
diff options
context:
space:
mode:
authorCase Duckworth2021-11-21 23:57:41 -0600
committerCase Duckworth2021-11-21 23:57:41 -0600
commita2657993bad828af6743c68931a0e848bfcdec53 (patch)
tree1e9220389184a0c68bc9f6bfe08edca3f2a362e6 /init.el
parentUn-stupidify org-mode filling (diff)
downloademacs-a2657993bad828af6743c68931a0e848bfcdec53.tar.gz
emacs-a2657993bad828af6743c68931a0e848bfcdec53.zip
I DECLARE BANKRUPTCY ... 8
Didn't think to do this till pretty .. written, so here we are.
Diffstat (limited to 'init.el')
-rw-r--r--init.el2802
1 files changed, 333 insertions, 2469 deletions
diff --git a/init.el b/init.el index c2fbadf..abd40fe 100644 --- a/init.el +++ b/init.el
@@ -1,262 +1,47 @@
1;;; init.el -*- lexical-binding: t; coding: utf-8-unix -*- 1;;; init.el --- Emacs initiation file -*- lexical-binding: t -*-
2 2
3;; Author: Case Duckworth <(rot13-string "npqj@npqj.arg")> 3;; Author: Case Duckworth <acdw@acdw.net>
4;; Created: Sometime during Covid-19, 2020 4;; Created: Sometime during Covid-19, 2020
5;; Keywords: configuration 5;; Keywords: configuration
6;; URL: https://tildegit.org/acdw/emacs 6;; URL: https://tildegit.org/acdw/emacs
7;; Bankruptcy: 7 7;; Bankruptcy: 8
8
9;; This file is NOT part of GNU Emacs.
10 8
11;;; License: 9;;; License:
12 10
13;; Everyone is permitted to do whatever with this software, without 11;; Everyone is permitted to do whatever they like with this software
14;; limitation. This software comes without any warranty whatsoever, 12;; without limitation. This software comes without any warranty
15;; but with two pieces of advice: 13;; whatsoever, but with two pieces of advice:
16
17;; - Be kind to yourself. 14;; - Be kind to yourself.
18
19;; - Make good choices. 15;; - Make good choices.
20 16
21;;; Commentary:
22
23;; Some of the names in these `setup' forms are arbitrary.
24
25;;; Code: 17;;; Code:
26 18
27(setup (:require auth-source) 19;; Require early-init.el just in case it hasn't been yet.
28 (:option auth-sources (list (acdw/sync-dir "authinfo") 20(require 'early-init (locate-user-emacs-file "early-init.el") :noerror)
29 (acdw/sync-dir "authinfo.gpg") 21;; Requre my private stuff
30 "~/.authinfo" 22(require 'private)
31 "~/.authinfo.gpg")))
32
33(setup (:require goto-addr)
34 (if (fboundp #'global-goto-address-mode)
35 (global-goto-address-mode)
36 (add-hook 'after-change-major-mode-hook #'goto-address-mode)))
37
38(setup (:require recentf)
39 (:option recentf-save-file (acdw/dir "recentf.el")
40 recentf-max-menu-items 100
41 recentf-max-saved-items nil
42 recentf-auto-cleanup 'mode
43 (append recentf-exclude) (acdw/dir))
44
45 (:advise dired-rename-file :after #'rjs/recentf-rename-notify)
46
47 (recentf-mode +1))
48
49(setup (:require savehist)
50 (:option history-length t
51 history-delete-duplicates t
52 savehist-autosave-interval 60
53 savehist-file (acdw/dir "savehist.el"))
54
55 (dolist (var '(extended-command-history
56 global-mark-ring
57 kill-ring
58 regexp-search-ring
59 search-ring
60 mark-ring))
61 (:option (append savehist-additional-variables) var))
62
63 (savehist-mode +1))
64
65(setup (:require server)
66 (unless (server-running-p)
67 (server-start)))
68
69(setup (:require tramp)
70 ;; thanks Irreal! https://irreal.org/blog/?p=895
71 (add-to-list 'tramp-default-proxies-alist
72 '(nil "\\`root\\'" "/ssh:%h:"))
73 (add-to-list 'tramp-default-proxies-alist
74 '((regexp-quote (system-name)) nil nil)))
75
76(setup Info
77 (:hook #'variable-pitch-mode
78 #'reading-mode))
79
80(setup abbrev
81 (:option abbrev-file-name "~/Sync/abbrev.el"
82 save-abbrevs 'silent)
83 (:hook-into text-mode
84 circe-chat-mode))
85
86(setup acdw
87 (:also-load acdw-compat
88 acdw-lisp
89 acdw-reading)
90
91 (:option user-full-name "Case Duckworth"
92 user-mail-address (rot13-string "npqj@npqj.arg"))
93
94 (when-let ((default-directory
95 (expand-file-name-exists-p "pkg/" user-emacs-directory)))
96 (normal-top-level-add-subdirs-to-load-path)))
97
98(setup auto-fill
99 (:hook (defun auto-fill@truncate-lines ()
100 (setq-local truncate-lines t))))
101
102(setup autoinsert
103 (require 'acdw-autoinsert)
104 (acdw/define-auto-insert '(:replace t)
105 ;; This is my custom auto-insert for elisp files.
106 '("\\.el\\'" . "Emacs Lisp header (acdw)")
107 '("Short description: " ";;; "
108 (file-name-nondirectory (buffer-file-name))
109 " --- " str
110 (make-string (max 2 ( - fill-column (current-column) 27)) 32)
111 "-*- lexical-binding: t; -*-"
112 '(setq lexical-binding t)
113 "\n\n;; Copyright (C) " (format-time-string "%Y")
114 " " (getenv "ORGANIZATION") | (progn user-full-name)
115 "\n\n;; Author: " (user-full-name)
116 '(if (search-backward "&" (line-beginning-position) t)
117 (replace-match (capitalize (user-login-name)) t t))
118 '(end-of-line 1)
119 " <" (progn user-mail-address) ">"
120 & -2
121 "\n\n;;; License:"
122 "\n\n;; Everyone is permitted to do whatever with this software, without"
123 "\n;; limitation. This software comes without any warranty whatsoever,"
124 "\n;; but with two pieces of advice:"
125 "\n\n;; - Be kind to yourself."
126 "\n\n;; - Make good choices."
127 "\n\n;;; Commentary:"
128 "\n\n;; " _
129 "\n\n;;; Code:"
130 "\n\n\n\n(provide '" (file-name-base (buffer-file-name)) ")"
131 "\n;;; " (file-name-nondirectory (buffer-file-name)) " ends here\n"))
132 (auto-insert-mode +1))
133
134(setup autorevert
135 (:option global-auto-revert-non-file-buffers t
136 auto-revert-verbose nil)
137 (global-auto-revert-mode +1))
138 23
139(setup browse-url 24(setup (:require +defaults))
140 (:require acdw-browse-url)
141
142 (:option browse-url-secondary-browser-function
143 (if (executable-find "firefox") ; prefer Firefox
144 #'browse-url-firefox
145 #'browse-url-default-browser)
146 browse-url-new-window-flag nil ; for eww
147 browse-url-firefox-arguments '("--new-tab") ; for firefox
148 browse-url-firefox-new-window-is-tab t)
149
150 (acdw/browse-url-set-handlers
151 (list
152 (cons (rx (seq "." (or "jpeg" "jpg" ; images
153 "png")
154 eos))
155 (lambda (&rest args)
156 (apply
157 (cond ((executable-find "feh") #'browse-url-feh)
158 ((executable-find "mpv")
159 (defun browse-image-url-mpv (url &rest _args)
160 "View an image URL in mpv."
161 (let ((url (browse-url-encode-url url))
162 (process-environment
163 (browse-url-process-environment)))
164 (message "Viewing %s in mpv..." url)
165 (apply #'start-process
166 (concat "mpv " url) nil
167 "mpv"
168 (append browse-url-mpv-arguments
169 (list "--image-display-duration=inf"
170 url))))))
171 (t #'eww-browse-url))
172 args)))
173 (cons (rx (or "youtube.com" ; videos
174 "youtu.be"
175 (seq "." (or "mp4"
176 "gif"
177 "mov" "MOV")
178 eos)))
179 (lambda (&rest args)
180 (apply (if (executable-find "mpv")
181 #'browse-url-mpv
182 browse-url-secondary-browser-function)
183 args)))
184 (cons (rx (or "google.com" ; websites that don't work with eww
185 "reddit.com"
186 "twitter.com"
187 "imgur.com"
188 "pixelfed"
189 "taskiq"))
190 browse-url-secondary-browser-function)
191 (cons "." ; everything else
192 #'eww-browse-url)))
193
194 ;; Buttonize gemini:// links.
195 (acdw/add-button-url-regexp-protocol "gemini"))
196 25
197(setup buffers 26(setup (:require +init)
198 (:global "C-x k" #'acdw/kill-a-buffer) 27 (:bind "C-c s" (lambda ()
199 ;; Set the right major mode based on buffer name, if not visiting a file. 28 (interactive)
200 ;; http://ruzkuku.com/emacs.d.html#orgeab93c3 29 (+init-sort)
201 (setq-default major-mode (lambda () 30 (save-buffer)))
202 (unless buffer-file-name 31 (:hook '+init-add-setup-to-imenu))
203 (let ((buffer-file-name (buffer-name)))
204 (set-auto-mode))))))
205 32
206(setup calendar 33(setup calendar
207 (:option calendar-week-start-day 1)) 34 (require '_location)
208 35 (:option calendar-location-name _location-name
209(setup completion 36 calendar-latitude _location-latitude
210 (:option completion-ignore-case t 37 calendar-longitude _location-longitude))
211 read-buffer-completion-ignore-case t
212 completion-styles '(substring partial-completion)
213 completion-category-defaults nil
214 completion-category-overrides
215 '((file (styles . (partial-completion)))))
216
217 (:global "M-/" #'hippie-expand))
218
219(setup css-mode
220 (:bind "C-c C-h" #'css-lookup-symbol))
221
222(setup cursor
223 (:option cursor-type 'bar
224 cursor-in-non-selected-windows 'hollow
225 blink-cursor-blinks 1)
226 (blink-cursor-mode +1))
227
228(setup cus-edit
229 (:also-load acdw-cus-edit)
230 (:option custom-file (acdw/dir "custom.el")
231 custom-magic-show nil
232 custom-magic-show-button t
233 custom-raised-buttons nil
234 custom-unlispify-tag-names nil
235 custom-variable-default-form 'lisp)
236
237 ;; I need this to save `safe-local-variables' between Emacs invocations. For
238 ;; now, of course .... I would /love/ a better solution.
239 (when (file-exists-p custom-file)
240 ;; Don't load faces, since those are all set in init.el
241 (cl-letf (((symbol-function 'custom-set-faces) #'ignore))
242 (load custom-file nil nil)))
243
244 ;; `Custom-mode-hook' fires /before/ the widgets are built, so I have to
245 ;; install advice after the widgets are made.
246 (:advise custom-buffer-create-internal :after #'acdw-cus/expand-widgets)
247
248 (:with-mode Custom-mode
249 (:local-set imenu-generic-expression acdw-cus/imenu-generic-expression)))
250
251(setup debugger
252 (:hook visual-line-mode))
253 38
254(setup dired 39(setup dired
255 (:also-load dired-x) 40 (:also-load dired-x)
256 (:straight dired-subtree 41 (:also-straight dired-subtree
257 dired-collapse 42 dired-collapse
258 dired-git-info) 43 dired-git-info
259 44 dired+)
260 (:option dired-recursive-copies 'top 45 (:option dired-recursive-copies 'top
261 dired-recursive-deletes 'top 46 dired-recursive-deletes 'top
262 dired-create-destination-dirs 'ask 47 dired-create-destination-dirs 'ask
@@ -269,1248 +54,255 @@
269 hardlink load move 54 hardlink load move
270 shell touch symlink) 55 shell touch symlink)
271 dired-dwim-target t) 56 dired-dwim-target t)
272 57 (:bind "TAB" 'dired-subtree-cycle
273 (:bind "TAB" #'dired-subtree-cycle 58 "i" 'dired-subtree-toggle
274 "i" #'dired-subtree-toggle 59 ")" 'dired-git-info-mode)
275 ")" #'dired-git-info-mode) 60 (:hook 'dired-collapse-mode
276 61 'dired-hide-details-mode
277 (:hook dired-collapse-mode 62 'hl-line-mode)
278 dired-hide-details-mode 63 (:global "C-x C-j" 'dired-jump)
279 hl-line-mode)
280
281 (:global "C-x C-j" #'dired-jump)
282
283 (with-eval-after-load 'dired 64 (with-eval-after-load 'dired
284 (acdw/system 65 (pcase system-type
285 (:work (:straight w32-browser) 66 ((or 'ms-dos 'windows-nt)
286 (autoload #'dired-w32-browser "w32-browser" nil t) 67 (:straight w32-browser))
287 (:bind "RET" #'dired-w32-browser)) 68 ((or 'gnu/linux)
288 (:home (:straight dired-open) 69 (:straight dired-open)
289 (autoload #'dired-find-alternate-file "dired-open" nil t) 70 (:option dired-listing-switches
290 (:bind "RET" #'dired-find-alternate-file))))) 71 (concat dired-listing-switches " -F")))))
291 72 (with-eval-after-load 'frowny
292(setup disabled 73 (add-to-list 'frowny-inhibit-modes 'dired-mode)))
293 ;; While this stuff is defined in novice.el, I'm using 'disabled' as the name
294 ;; for easy finding.
295
296 ;; Enable all disabled commands.
297 ;; This is an option, but I'm going to try /enabling/ just the ones that I
298 ;; use instead.
299 ;; (mapatoms (lambda (symbol)
300 ;; (when (get symbol 'disabled)
301 ;; (put symbol 'disabled nil))))
302
303 ;; Enable /some/ disabled commands
304 (dolist (enable-sym '(narrow-to-region
305 dired-find-alternate-file
306 narrow-to-page))
307 (put enable-sym 'disabled nil))
308
309 ;; Now, disable symbols as I wish.
310 (dolist (disable-sym '(view-hello-file
311 suspend-frame
312 scroll-left
313 scroll-right
314 comment-set-column
315 set-fill-column))
316 (put disable-sym 'disabled t))
317
318 ;; And set the disabled function to something better than the default.
319 ;; Now, I can run any disabled command, but I have to use M-x to do it.
320 (:option disabled-command-function #'acdw/disabled-command-function))
321
322(setup ediff
323 (:option ediff-diff-options "-w" ; ignore whitespace
324 ediff-window-setup-function #'ediff-setup-windows-plain
325 ediff-split-window-function #'split-window-horizontally)
326 ;; https://oremacs.com/2015/01/17/setting-up-ediff/
327 (add-hook 'ediff-after-quit-hook-internal #'winner-undo))
328
329(setup eldoc
330 (:option eldoc-idle-delay 0.1
331 eldoc-echo-area-use-multiline-p nil))
332
333(setup elec-pair
334 (electric-pair-mode +1))
335
336(setup elisp-mode
337 (:with-mode emacs-lisp-mode ;; -_-
338 (:option eval-expression-print-length nil
339 eval-expression-print-level nil
340 print-length nil
341 print-level nil
342 lisp-indent-function #'lisp-indent-function)
343
344 (:local-set (append imenu-generic-expression)
345 `("Setup"
346 ,(rx (seq
347 (group bol (* space) "(setup" (+ space))
348 (? (group "(:" (+ graph) (* space) (? "(")))
349 (group (+ (any word ?+ ?-)))))
350 3))
351
352 (:hook #'checkdoc-minor-mode
353 #'turn-on-eldoc-mode)
354
355 ;; Emulate slime's eval binds
356 (:bind "C-c C-c" #'eval-defun
357 "C-c C-k" #'acdw/eval-region-or-buffer
358 "C-c C-z" #'ielm)
359
360 ;; Add advice to pulse evaluated regions
361 (:advise eval-region :around
362 (defun eval-region@pulse (fn beg end &rest args)
363 (let ((pulse-flag t))
364 (pulse-momentary-highlight-region beg end))
365 (apply fn beg end args))))
366
367 (:with-mode lisp-interaction-mode ;; -___-
368 (:bind "C-c C-c" #'eval-defun
369 "C-c C-k" #'acdw/eval-region-or-buffer
370 "C-c C-z" #'ielm)))
371
372(setup emacs
373 ;; "Et cetera" settings
374 ;; This should stay as /minimal/ as possible. Anything that can go somewhere
375 ;; else /should/ go there.
376 (:option
377 async-shell-command-display-buffer nil
378 async-shell-command-buffer #'new-buffer
379 attempt-orderly-shutdown-on-fatal-signal nil
380 auto-hscroll-mode 'current-line
381 attempt-stack-overflow-recovery nil
382 echo-keystrokes 0.01
383 find-function-C-source-directory (acdw/find-emacs-source)
384 image-use-external-converter (and (not (version< emacs-version "27"))
385 (or (executable-find "magick")
386 (executable-find "convert")))
387 kill-read-only-ok t
388 kill-ring-max 500 ; RAM is cheap, right?
389 mark-ring-max 50
390 kmacro-ring-max 20
391 search-ring-max 200
392 global-mark-ring-max 100
393 regexp-search-ring-max 100
394 load-prefer-newer t
395 native-comp-async-report-warnings-errors nil
396 password-cache t
397 password-cache-expiry (* 60 5) ; seconds
398 set-mark-command-repeat-pop t
399 hscroll-step 1
400 scroll-step 1)
401
402 (when (fboundp 'command-completion-default-include-p)
403 (setq read-extended-command-predicate
404 #'command-completion-default-include-p))
405
406 (defvar case-map (make-sparse-keymap)
407 "A keymap for setting case in various ways.")
408 (global-set-key (kbd "C-c c") case-map)
409
410 (defvar lookup-map (make-sparse-keymap)
411 "A keymap for looking up things.")
412 (global-set-key (kbd "C-c l") lookup-map)
413
414 (:global "M-=" #'count-words
415 "C-M-;" #'comment-or-uncomment-sexp
416 "C-w" #'kill-region-or-backward-word
417 "C-c d" #'acdw/insert-iso-date
418 "M-`" nil
419 "C-x o" #'acdw/other-window-or-switch-buffer
420 "C-x O" #'acdw/other-window-or-switch-buffer-backward
421 "C-c _" #'add-file-local-variable
422 "C-x C-c" #'acdw/fat-finger-exit)
423
424 (global-set-key (kbd "M-n") (kbd "C-u 1 C-v"))
425 (global-set-key (kbd "M-p") (kbd "C-u 1 M-v"))
426
427 ;; inspo: https://github.com/zaeph/.emacs.d/blob/master/init.el#L479
428 (defvar toggle-map (make-sparse-keymap)
429 "A keymap for toggling!")
430 (global-set-key (kbd "C-c t") toggle-map)
431
432 (:with-map toggle-map
433 (:bind "c" #'column-number-mode
434 "l" #'display-line-numbers-mode
435 "d" #'toggle-debug-on-error
436 "s" #'so-long-mode
437 "S" #'scroll-bar-mode))
438
439 ;; Toggle
440 (:with-map toggle-map
441 (:bind "b" (defun acdw/toggle-lexical-binding ()
442 "Toggle `lexical-binding' in the current buffer."
443 (interactive)
444 (setq lexical-binding (not lexical-binding))
445 (message "Lexical-binding is %sabled."
446 (if lexical-binding "en" "dis"))
447 (force-mode-line-update))))
448
449
450 (:with-map case-map
451 (require 'titlecase)
452 (require 'acdw)
453 (:bind "c" #'capitalize-dwim
454 "t" #'titlecase-dwim
455 "u" #'upcase-dwim
456 "l" #'downcase-dwim))
457
458 (column-number-mode +1))
459
460(setup encoding
461 (:option locale-coding-system 'utf-8-unix
462 coding-system-for-read 'utf-8-unix
463 coding-system-for-write 'utf-8-unix
464 buffer-file-coding-system 'utf-8-unix
465 default-process-coding-system '(utf-8-unix . utf-8-unix)
466 x-select-request-type '(UTF8_STRING
467 COMPOUND_TEXT
468 TEXT
469 STRING))
470
471 (set-charset-priority 'unicode)
472 (set-language-environment "UTF-8")
473 (prefer-coding-system 'utf-8-unix)
474 (set-default-coding-systems 'utf-8-unix)
475 (set-terminal-coding-system 'utf-8-unix)
476 (set-keyboard-coding-system 'utf-8-unix)
477
478 (acdw/system
479 (:work (set-clipboard-coding-system 'utf-16-le)
480 (set-selection-coding-system 'utf-16-le))
481 (_ (set-selection-coding-system 'utf-8)
482 (set-clipboard-coding-system 'utf-8))))
483 74
484(setup eshell 75(setup eshell
485 (:also-load acdw-eshell 76 (:also-load +eshell
486 em-smart 77 em-smart
487 em-tramp) 78 em-tramp)
488 79 (:option eshell-aliases-file (.etc "eshell/aliases" t)
489 (:option eshell-aliases-file (acdw/dir "eshell/aliases" t)
490 eshell-destroy-buffer-when-process-dies t 80 eshell-destroy-buffer-when-process-dies t
491 eshell-directory-name (acdw/dir "eshell/" t) 81 eshell-directory-name (.etc "eshell/" t)
492 eshell-error-if-no-glob t 82 eshell-error-if-no-glob t
493 eshell-hist-ignore-dups t 83 eshell-hist-ignore-dups t
494 eshell-kill-on-exit nil 84 eshell-kill-on-exit nil
495 eshell-prefer-lisp-functions t ; I want to try using eshell 85 eshell-prefer-lisp-functions t
496 eshell-prefer-lisp-variables t ; as much as possible. 86 eshell-prefer-lisp-variables t
497 eshell-review-quick-commands nil 87 eshell-review-quick-commands nil
498 eshell-save-history-on-exit t 88 eshell-save-history-on-exit t
499 eshell-scroll-to-bottom-on-input 'all 89 eshell-scroll-to-bottom-on-input 'all
500 eshell-smart-space-goes-to-end t 90 eshell-smart-space-goes-to-end t
501 eshell-where-to-jump 'begin) 91 eshell-where-to-jump 'begin)
502
503 (:local-set outline-regexp eshell-prompt-regexp 92 (:local-set outline-regexp eshell-prompt-regexp
504 page-delimiter eshell-prompt-regexp) 93 page-delimiter eshell-prompt-regexp)
505 94 (:bind "C-d" '+eshell-quit-or-delete-char)
506 (:hook #'eshell-arg-hist-mode 95 (:when-loaded
507 (defun eshell-mode@setup () 96 (setenv "PAGER" "cat")))
508 (require 'eshellrc (locate-user-emacs-file "eshell") :noerror) 97
509 (:bind "C-d" #'eshell-quit-or-delete-char)))) 98(setup magit
510 99 ;; This setup is weird because of dependency issues
511(setup eww 100 (:straight (transient :host github :repo "magit/transient" :branch "master")
512 (:also-load acdw-eww) 101 (magit :host github :repo "magit/magit")
513 (defvar-local eww-readable-p nil 102 (git-modes :host github :repo "magit/git-modes"))
514 "Whether current buffer is in readable-mode.") 103 (when (eq system-type 'gnu/linux)
515 (:option eww-search-prefix "https://duckduckgo.com/html?q=" 104 (:straight (forge :host github :repo "magit/forge"))
516 url-privacy-level '(email agent cookies lastloc)) 105 (with-eval-after-load 'magit
517 106 (require 'forge)
518 (defun eww@is-readable (&rest _) 107 (add-to-list 'forge-alist
519 (setq-local eww-readable-p t)) 108 '("tildegit.org" "tildegit.org/api/v1" "tildegit.org"
520 (defun eww@is-not-readable (&rest _) 109 forge-gitea-repository)))))
521 (setq-local eww-readable-p nil)) 110
522 111(setup (:straight 0x0)
523 (advice-add 'eww-readable :after #'eww@is-readable) 112 (:option 0x0-default-server 'ttm)
524 (advice-add 'eww-render :after #'eww@is-not-readable) 113 (with-eval-after-load 'embark
525 (advice-add 'eww-back-url :after #'eww@is-not-readable) 114 (define-key embark-region-map (kbd "U") '0x0-dwim)))
526 115
527 (:hook #'reading-mode 116(setup (:straight acme-theme)
528 (defun bookmark-eww--setup () 117 ;; (load-theme 'acme t)
529 "Setup eww bookmark integration."
530 (setq-local bookmark-make-record-function #'bookmark-eww--make)))
531
532 (:bind "RET" (defun eww/browse-url (arg)
533 (interactive "P")
534 (if-let ((url (thing-at-point 'url)))
535 (browse-url url)
536 (call-interactively #'acdw/link-hint-open-link)))
537 "b" #'bookmark-set
538 "B" #'bookmark-jump
539 "M-n" nil
540 "M-p" nil))
541
542(setup executable
543 (:option executable-prefix-env t)
544 (add-hook 'after-save-hook
545 #'executable-make-buffer-file-executable-if-script-p))
546
547(setup files
548 (:option auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t))
549 auto-save-list-file-prefix (acdw/dir "auto-save-list/.saves-" t)
550 auto-save-interval 60
551 auto-save-timeout 60
552 auto-save-visited-interval auto-save-timeout
553 backup-by-copying t
554 backup-directory-alist `((".*" . ,(acdw/dir "backup/" t)))
555 delete-old-versions t
556 mode-require-final-newline 'visit-save
557 tramp-backup-directory-alist backup-directory-alist
558 vc-make-backup-files t
559 version-control t)
560 (auto-save-visited-mode +1))
561
562(setup find-func
563 (:global "C-c l f" #'find-function
564 "C-c l l" #'find-library
565 "C-c l v" #'find-variable))
566
567(setup flymake
568 ;; TODO: look at flycheck for ideas around `flycheck-disabled-checkers' and
569 ;; `flycheck-emacs-lisp-load-path'... there must be a way to get flymake to
570 ;; recognize new values in the load path.
571 (defvar-local flymake-inhibit nil
572 "Buffer-local variable to inhibit `flymake'.")
573 (add-to-list 'safe-local-variable-values '(flymake-inhibit . t))
574 (add-to-list 'safe-local-variable-values '(flymake-inhibit . nil))
575
576 (defvar flymake-inhibit-major-modes nil
577 "Which major-modes NOT to enable `flymake' in.")
578
579 (defvar flymake-inhibit-file-name-regexps '("init\\.el\\'"
580 "early-init\\.el\\'")
581 "List of file regexps NOT to enable `flymake' in.")
582
583 (defvar flymake-inhibit-buffer-name-regexps (list (rx "*scratch*"))
584 "List of buffer-name regexps NOT to enable `flymake' in.")
585
586 (defun list-string-match-p (string regexp-list)
587 "Return t if at least one regex in RETGEXP-LIST matches STRING, else nil."
588 ;; FINE alphapapa ;P
589 (seq-some (lambda (regexp)
590 (string-match regexp (or string "")))
591 regexp-list))
592
593 (defun flymake-unless ()
594 "Turn on `flymake-mode', UNLESS it's inhibited.
595There are three methods to inhibit flymake in a file. From most
596specific to most general, they are these:
597
598- `flymake-inhibit': a file-local-variable
599
600- `flymake-inhibit-buffer-name-regexps': a list of regexps to
601 match the buffer name against. If one of them matches, inhibit
602 `flymake-mode'.
603
604- `flymake-inhibit-file-name-regexps': a list of regexps to match
605 the filename against. If one of them matches, inhibit
606 `flymake-mode'.
607
608- `flymake-inhibit-major-modes': a list of major-modes in which
609 to inhibit `flymake-mode'. Really only useful if you want to
610 generally add `flymake-mode' to `prog-mode-hook'."
611 ;; The name of this hook tells you pretty much everything you need to know
612 ;; for this little thing right here.
613 (add-hook 'hack-local-variables-hook
614 (defun flymake-unless@hack-local-variables ()
615 (unless (or (cdr (assoc 'flymake-inhibit
616 file-local-variables-alist))
617 (list-string-match-p
618 (buffer-name)
619 flymake-inhibit-buffer-name-regexps)
620 (list-string-match-p
621 (buffer-file-name)
622 flymake-inhibit-file-name-regexps)
623 (apply #'derived-mode-p
624 flymake-inhibit-major-modes))
625 (flymake-mode-on)))))
626
627 (add-hook 'prog-mode-hook #'flymake-unless)
628
629 (:bind "M-n" #'flymake-goto-next-error
630 "M-p" #'flymake-goto-prev-error))
631
632(setup flyspell
633 (:hook-into text-mode))
634
635(setup frames
636 (:option frame-title-format '("%b@"
637 (:eval
638 (or (file-remote-p default-directory 'host)
639 system-name))
640 " %+%* GNU Emacs"
641 (:eval (when (frame-parameter nil 'client)
642 " Client")))
643 window-resize-pixelwise t))
644
645(setup ibuffer
646 (:also-load ibuf-ext)
647 (:option ibuffer-expert t
648 ibuffer-show-empty-filter-groups nil
649 ibuffer-saved-filter-groups
650 '(("default"
651 ("dired" (mode . dired-mode))
652 ("customize" (mode . Custom-mode))
653 ("emacs" (or (name . "^\\*scratch\\*$")
654 (name . "^\\*Messages\\*$")
655 (name . "^\\*Warnings\\*$")
656 (name . "^\\*straight-process\\*$")
657 (name . "^\\*Calendar\\*$")))
658 ("git" (or (name . "^\*magit")
659 (name . "^\magit")))
660 ("help" (or (mode . help-mode)
661 (mode . Info-mode)
662 (mode . helpful-mode)))
663 ("messaging" (or (mode . message-mode)
664 (mode . bbdb-mode)
665 (mode . mail-mode)
666 (mode . gnus-group-mode)
667 (mode . gnus-summary-mode)
668 (mode . gnus-article-mode)
669 (name . "^\\.bbdb$")
670 (name . "^\\.newsrc-dribble")
671 (mode . erc-mode)
672 (mode . circe-server-mode)
673 (mode . circe-channel-mode)))
674 ("shell" (or (mode . eshell-mode)
675 (mode . shell-mode)
676 (mode . vterm-mode)))
677 ("web" (or (mode . elpher-mode)
678 (mode . gemini-mode)
679 (mode . eww-mode))))))
680
681 (:global "C-x C-b" #'ibuffer)
682
683 (:hook (defun ibuffer@filter-to-default ()
684 (ibuffer-switch-to-saved-filter-groups "default"))))
685
686(setup ielm
687 (:hook #'turn-on-eldoc-mode))
688
689(setup imenu
690 (:option imenu-auto-rescan t))
691
692(setup isearch
693 (:option search-default-mode t))
694
695(setup lines
696 (:option fill-column 79
697 word-wrap t
698 truncate-lines nil)
699
700 (global-display-fill-column-indicator-mode -1)
701 (global-so-long-mode +1)
702
703 (add-hook 'visual-line-mode-hook
704 (defun acdw/disable-fill-column-indicator ()
705 (display-fill-column-indicator-mode
706 (if visual-line-mode -1 +1))))
707
708 ;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'.
709 ;; I can't simply advise `kill-line' with an override from crux because crux
710 ;; itself calls `kill-line', leading to a infinite nesting situation.
711 (advice-add 'kill-line :around
712 (defun kill-line@join (fn &rest args)
713 (if (and (eolp)
714 (not (bolp)))
715 (delete-indentation 1)
716 (apply fn args)))))
717
718(setup minibuffer
719 (:option enable-recursive-minibuffers t
720 file-name-shadow-properties '(invisible t intangible t)
721 minibuffer-eldef-shorten-default t
722 minibuffer-prompt-properties
723 '(read-only t cursor-intangible t face minibuffer-prompt)
724 read-answer-short t
725 read-extended-command-predicate ; used on >28
726 #'command-completion-default-include-p)
727
728 (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
729
730 (add-hook 'minibuffer-setup-hook #'acdw/gc-disable)
731 (add-hook 'minibuffer-exit-hook #'acdw/gc-enable)
732
733 (minibuffer-depth-indicate-mode +1)
734 (file-name-shadow-mode +1)
735 (minibuffer-electric-default-mode +1)
736
737 (if (version< emacs-version "28")
738 (fset 'yes-or-no-p #'y-or-n-p)
739 (setq use-short-answers t)))
740
741(setup mouse
742 ;; Unconditionally follow links when clicked.
743 ;; This is because mouse-1 usually sets point.
744 ;; Other options:
745 ;; +[ms] -> perform mouse-2 until held for [ms], then mouse-1
746 ;; -[ms] -> perform mouse-1 until held for [ms], then mouse-2
747 ;; 'double -> mouse-2 on double click
748 ;; nil -> mouse-1 never follows link
749 ;; <anything> -> mouse-1 /always/ follows link
750 (:option mouse-1-click-follows-link t))
751
752(setup mu4e
753 (:load-from "/usr/share/emacs/site-lisp/mu4e")
754 (:autoload (mu4e :interactive t)
755 make-mu4e-context)
756 (:option message-kill-buffer-on-exit t
757 message-send-mail-function #'smtpmail-send-it
758 mu4e-change-filenames-when-moving t
759 mu4e-completing-read-function 'completing-read
760 mu4e-compose-context-policy 'ask-if-none
761 mu4e-context-policy 'ask-if-none
762 mu4e-contexts
763 (list
764 ;; Work
765 (make-mu4e-context
766 :name "Work"
767 :match-func (lambda (msg)
768 (when msg
769 (string-prefix-p
770 work-mail-dir
771 (mu4e-message-field msg :maildir))))
772 :vars `((user-mail-address . ,work-email)
773 (smtpmail-smtp-server . ,work-smtp-server)
774 (mu4e-compose-format-flowed . nil)
775 (mu4e-drafts-folder
776 . ,(concat work-mail-dir "/[Gmail]/Drafts"))
777 (mu4e-sent-folder
778 . ,(concat work-mail-dir "/[Gmail]/Sent Mail"))
779 (mu4e-refile-dir
780 . ,(concat work-mail-dir "/[Gmail]/All Mail"))
781 (mu4e-trash-folder
782 . ,(concat work-mail-dir "/[Gmail]/Trash"))
783 (mu4e-maildir-shortcuts
784 . ,(mapcar (lambda (cell)
785 (let ((dir (car cell))
786 (char (cdr cell)))
787 (cons (concat work-mail-dir dir) char)))
788 '(("/Inbox" . ?i)
789 ("/[Gmail]/All Mail" . ?a)
790 ("/[Gmail]/Sent" . ?s)
791 ("/[Gmail]/Drafts" . ?d)
792 ("/[Gmail]/Trash" . ?t))))))
793 ;; Home
794 (make-mu4e-context
795 :name "Home"
796 :match-func (lambda (msg)
797 (when msg
798 (string-prefix-p
799 home-mail-dir
800 (mu4e-message-field msg :maildir))))
801 :vars `((user-mail-address . ,home-email)
802 (smtpmail-smtp-server . ,home-smtp-server)
803 (mu4e-compose-signature . "~ Case")
804 (mu4e-compose-format-flowed . nil)
805 (mu4e-drafts-folder
806 . ,(concat home-mail-dir "/Drafts"))
807 (mu4e-sent-folder
808 . ,(concat home-mail-dir "/Sent"))
809 (mu4e-refile-folder
810 . ,(concat home-mail-dir "/Archive"))
811 (mu4e-trash-folder
812 . ,(concat home-mail-dir "/Trash"))
813 (mu4e-maildir-shortcuts
814 . ,(mapcar (lambda (cell)
815 (let ((dir (car cell))
816 (char (cdr cell)))
817 (cons (concat home-mail-dir dir) char)))
818 '(("/INBOX" . ?i)
819 ("/Archive" . ?a)
820 ("/Sent" . ?s)
821 ("/Drafts" . ?d)
822 ("/Trash" . ?t)))))))
823 mu4e-get-mail-command "mbsync -a"
824 mu4e-maildir "~/mail"
825 mu4e-update-interval (unless
826 ;; I just realized... there is probably a
827 ;; /much/ better way to do this.
828 (file-exists-p
829 (expand-file-name
830 "systemd/user/mbsync.timer"
831 (getenv "XDG_CONFIG_HOME")))
832 (* 60 5))
833 sendmail-program (seq-some #'executable-find
834 '("msmtp"
835 "sendmail"))
836 message-sendmail-f-is-evil t
837 message-sendmail-extra-arguments '("--read-envelope-from")
838 message-send-mail-function #'smtpmail-send-it
839 send-mail-function #'smtpmail-send-it
840 smtpmail-smtp-service 465
841 smtpmail-stream-type 'ssl)
842
843 (:with-mode mu4e-view-mode
844 (:hook #'reading-mode)))
845
846(setup page
847 (:option page-delimiter
848 (rx bol (or "\f" ";;;")
849 (not (any "#")) (* not-newline) "\n"
850 (* (* blank) (opt ";" (* not-newline)) "\n")))
851
852 (defun recenter-to-top (&rest _)
853 "Recenter the cursor to the top of the window."
854 (when (called-interactively-p 'any)
855 (recenter (if (or (null scroll-margin)
856 (zerop scroll-margin))
857 3
858 scroll-margin))))
859
860 (:advise forward-page :after #'recenter-to-top
861 backward-page :after #'recenter-to-top)
862
863 ;; I'm not sure where this is in /my/ version of Emacs
864 ;; (defvar page-navigation-repeat-map
865 ;; (let ((map (make-sparse-keymap)))
866 ;; (define-key map "]" #'forward-page)
867 ;; (define-key map "[" #'backward-page)
868 ;; map)
869 ;; "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.")
870
871 ;; (put 'forward-page 'repeat-map 'page-navigation-repeat-map)
872 ;; (put 'backward-page 'repeat-map 'page-navigation-repeat-map)
873 )
874
875(setup prog
876 (:option show-paren-delay 0
877 show-paren-style 'mixed
878 show-paren-when-point-inside-paren t
879 show-paren-when-point-in-periphery t
880 smie-indent-basic tab-width)
881
882 (:hook #'show-paren-mode
883 #'prettify-symbols-mode
884 ;; #'electric-pair-local-mode
885 #'acdw/setup-fringes
886 #'display-fill-column-indicator-mode
887
888 (defun prog-mode@auto-fill ()
889 (setq-local comment-auto-fill-only-comments t)
890 (turn-on-auto-fill))))
891
892(setup pulse
893 (:option pulse-flag nil
894 pulse-delay 0.5
895 pulse-iterations 1)
896
897 ;; XXX: this doesn't work yet. I only want to pulse the line in the active
898 ;; window, so when I have the same buffer viewed in multiple windows I can
899 ;; still see where my cursor is. To see the issue, C-x 2 then C-x o a few
900 ;; times.
901 (defun pulse-line-current-window (&rest _)
902 "Pulse the current line, but only if this window is active."
903 (pulse-momentary-highlight-one-line (window-point (selected-window))))
904
905 (dolist (func '(scroll-up-command
906 scroll-down-command
907 recenter-top-bottom
908 other-window
909 switch-to-buffer
910 redraw-frame))
911 (advice-add func :after #'pulse-line-current-window)))
912
913(setup re-builder
914 (require 'acdw-re)
915 (:global "C-M-5" #'re-builder
916 "C-M-%" #'re-builder)
917 (:with-map reb-mode-map
918 (:bind "C-c C-k" #'reb-quit
919 "RET" #'reb-replace-regexp))
920 (:with-map reb-lisp-mode-map
921 (:bind "RET" #'reb-replace-regexp)))
922
923(setup repeat
924 ;; new for Emacs 28!
925 (:only-if (fboundp #'repeat-mode))
926
927 (:option repeat-exit-key "g"
928 repeat-exit-timeout 5)
929
930 (repeat-mode +1))
931
932(setup saveplace
933 (:option save-place-file (acdw/dir "places.el")
934 save-place-forget-unreadable-files (acdw/system :home))
935
936 (save-place-mode +1))
937
938(setup scratch
939 (:option inhibit-startup-screen t
940 initial-buffer-choice t
941 initial-major-mode #'lisp-interaction-mode
942 lexical-binding t
943 initial-scratch-message
944 (concat ";; Howdy, "
945 (nth 0 (split-string
946 user-full-name))
947 "! "
948 "Welcome to GNU Emacs.\n\n"))
949
950 (add-hook 'kill-buffer-query-functions
951 (defun kill-buffer-query@immortal-scratch ()
952 (if (eq (current-buffer) (get-buffer "*scratch*"))
953 (progn (bury-buffer)
954 nil)
955 t))))
956
957(setup scrolling
958 (:option auto-window-vscroll nil
959 fast-but-imprecise-scrolling t
960 scroll-margin 3
961 scroll-conservatively 101
962 scroll-preserve-screen-position 1))
963
964(setup selection
965 (:option save-interprogram-paste-before-kill t
966 yank-pop-change-selection t
967 x-select-enable-clipboard t
968 x-select-enable-primary t
969 mouse-drag-copy-region t
970 kill-do-not-save-duplicates t)
971
972 (delete-selection-mode +1))
973
974(setup sh-mode
975 (:option sh-basic-offset tab-width
976 sh-indent-after-case 0
977 sh-indent-for-case-alt '+
978 sh-indent-for-case-label 0)
979
980 (:local-set indent-tabs-mode t)
981
982 (when (executable-find "shfmt")
983 (with-eval-after-load 'apheleia
984 (:option (append apheleia-formatters) '(shfmt . ("shfmt"))
985 (append apheleia-mode-alist) '(sh-mode . shfmt))))
986
987 (when (executable-find "shellcheck")
988 (:straight flymake-shellcheck)
989 (:hook flymake-mode
990 flymake-shellcheck-load)))
991
992(setup shell-command
993 (:option shell-command-switch (acdw/system
994 ;; I should be testing on some variable
995 (:home "-csi")
996 (:work "-c"))
997 shell-command-prompt-show-cwd t
998 shell-command-default-error-buffer "*shell-command-errors*"))
999
1000(setup shr
1001 (:option shr-width fill-column
1002 shr-max-image-proportion 0.6
1003 shr-image-animate t
1004 shr-discard-aria-hidden t))
1005
1006(setup text
1007 (:hook turn-on-auto-fill
1008 tildify-mode
1009 acdw/setup-fringes))
1010
1011(setup uniquify
1012 (:option uniquify-buffer-name-style 'forward
1013 uniquify-separator path-separator
1014 uniquify-after-kill-buffer-p t
1015 uniquify-ignore-buffers-re "^\\*"))
1016
1017(setup variable-pitch-mode
1018 ;; I might want to change this to `buffer-face-mode-hook'...
1019 (:advise variable-pitch-mode :after
1020 (defun variable-pitch-mode@setup (&rest _)
1021 "Set up `variable-pitch-mode' with my customizations."
1022 (display-fill-column-indicator-mode
1023 (if buffer-face-mode -1 +1)))))
1024
1025(setup view
1026 (:option view-read-only t)
1027
1028 (:hook (defun acdw/read-view-mode ()
1029 (reading-mode (if view-mode +1 -1)))))
1030
1031(setup w32
1032 (:option w32-allow-system-shell t
1033 w32-pass-lwindow-to-system nil
1034 w32-lwindow-modifier 'super
1035 w32-pass-rwindow-to-system nil
1036 w32-rwindow-modifier 'super
1037 w32-pass-apps-to-system nil
1038 w32-apps-modifier 'hyper))
1039
1040(setup whitespace
1041 (:option whitespace-style '(empty
1042 indentation
1043 space-before-tab
1044 space-after-tab)
1045 indent-tabs-mode nil
1046 tab-width 4
1047 backward-delete-char-untabify-method 'hungry)
1048
1049 (:global "M-SPC" #'cycle-spacing)
1050 ;; http://ruzkuku.com/emacs.d.html#orgc62eb58
1051 (:advise cycle-spacing :around
1052 (defun cycle-spacing@newlines-by-default (old arg &rest _)
1053 (funcall old (if (numberp arg) (- arg) arg)))))
1054
1055(setup windmove
1056 (:option windmove-wrap-around t)
1057 (:global
1058 ;; moving
1059 "C-x 4 <left>" #'windmove-left
1060 "C-x 4 <right>" #'windmove-right
1061 "C-x 4 <up>" #'windmove-up
1062 "C-x 4 <down>" #'windmove-down
1063 ;; swapping
1064 "C-x 4 S-<left>" #'windmove-swap-states-left
1065 "C-x 4 S-<right>" #'windmove-swap-states-right
1066 "C-x 4 S-<up>" #'windmove-swap-states-up
1067 "C-x 4 S-<down>" #'windmove-swap-states-down)
1068
1069 ;; (when (fboundp 'repeat-mode)
1070 ;; (defvar windmove-repeat-map
1071 ;; (let ((map (make-sparse-keymap)))
1072 ;; ;; moving
1073 ;; (define-key map [left] #'windmove-left)
1074 ;; (define-key map [right] #'windmove-right)
1075 ;; (define-key map [up] #'windmove-up)
1076 ;; (define-key map [down] #'windmove-down)
1077 ;; ;; swapping
1078 ;; (define-key map [S-left] #'windmove-swap-states-left)
1079 ;; (define-key map [S-right] #'windmove-swap-states-right)
1080 ;; (define-key map [S-up] #'windmove-swap-states-up)
1081 ;; (define-key map [S-down] #'windmove-swap-states-down)
1082 ;; map)
1083 ;; "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.")
1084
1085 ;; (dolist (sym '(windmove-left
1086 ;; windmove-right
1087 ;; windmove-up
1088 ;; windmove-down
1089 ;; windmove-swap-states-left
1090 ;; windmove-swap-states-right
1091 ;; windmove-swap-states-up
1092 ;; windmove-swap-states-down))
1093 ;; (put sym 'repeat-map 'windmove-repeat-map)))
1094 ) 118 )
1095 119
1096(setup window 120(setup (:straight anzu)
1097 ;; (require 'acdw-bell) 121 (:global [remap query-replace] 'anzu-query-replace-regexp
1098 (:option 122 [remap query-replace-regexp] 'anzu-query-replace-regexp)
1099 ;; Man-notify-method 'pushy 123 (global-anzu-mode +1)
1100 ;; display-buffer-alist ; from FrostyX 124 (:bind-into isearch
1101 ;; '(("shell.*" (display-buffer-same-window) ()) 125 [remap isearch-query-replace]
1102 ;; (".*" (display-buffer-reuse-window 126 'anzu-isearch-query-replace
1103 ;; display-buffer-same-window) 127 [remap isearch-query-replace-regexp]
1104 ;; (reusable-frames . t))) 128 'anzu-isearch-query-replace-regexp))
1105 recenter-positions '(top middle bottom)
1106 ;; ring-bell-function
1107 ;; (lambda ()
1108 ;; (acdw-bell/flash-mode-line
1109 ;; (acdw/system :home)))
1110 use-dialog-box nil
1111 use-file-dialog nil
1112 visible-bell nil)
1113
1114 (tooltip-mode -1))
1115
1116(setup winner
1117 ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html
1118 (:global "C-x 4 C-/" #'winner-undo
1119 "C-x 4 /" #'winner-undo
1120 "C-x 4 C-?" #'winner-redo
1121 "C-x 4 ?" #'winner-redo)
1122
1123 ;; add `winner-undo' and `winner-redo' to `repeat-mode'
1124 ;; (when (fboundp 'repeat-mode)
1125 ;; (defvar winner-mode-repeat-map
1126 ;; (let ((map (make-sparse-keymap)))
1127 ;; (define-key map "/" #'winner-undo)
1128 ;; (define-key map "?" #'winner-redo)
1129 ;; map)
1130 ;; "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.")
1131
1132 ;; (put 'winner-undo 'repeat-map 'winner-mode-repeat-map)
1133 ;; (put 'winner-redo 'repeat-map 'winner-mode-repeat-map))
1134
1135 (winner-mode +1))
1136
1137(setup (:straight (0x0
1138 :host gitlab
1139 :repo "willvaughn/emacs-0x0"))
1140 (:option 0x0-default-server 'ttm))
1141
1142(setup (:straight (actually-selected-window
1143 :host github
1144 :repo "duckwork/actually-selected-window.el"))
1145 (actually-selected-window-mode +1))
1146
1147(setup (:straight-when affe
1148 (and (or (executable-find "fd")
1149 (executable-find "find"))
1150 (executable-find "rg")))
1151 ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find'
1152 (:option affe-regexp-compiler
1153 (defun affe-orderless-regexp-compiler (input _type)
1154 (setq input (orderless-pattern-compiler input))
1155 (cons input (lambda (str) (orderless--highlight input str))))))
1156
1157(setup (:straight-when ahk-mode
1158 (acdw/system :work)))
1159
1160(setup (:straight alert)
1161 (:option alert-default-style (acdw/system
1162 (:home 'libnotify)
1163 (_ 'message))))
1164
1165(setup (:straight (apheleia
1166 :host github
1167 :repo "raxod502/apheleia"))
1168
1169 (require 'acdw-apheleia)
1170 (add-hook 'before-save-hook #'apheleia-dumb-auto-format)
1171
1172 ;; Aphelia can't find prettier on Windows (though I
1173 ;; installed it, I think), and it keeps trying to start
1174 ;; new processes until Emacs runs out of subprocess space.
1175 ;; So I just enable it at home.
1176 (unless (acdw/system :work)
1177 (apheleia-global-mode +1)))
1178
1179(setup (:straight async)
1180 (dired-async-mode +1))
1181 129
1182(setup (:straight avy) 130(setup (:straight avy)
1183 (:global "M-j" #'avy-goto-char-timer 131 (:also-load +avy)
1184 "C-c C-j" #'avy-resume) 132 (:global "M-j" 'avy-goto-char-timer)
133 (:bind-into isearch
134 "M-j" 'avy-isearch)
135 (:when-loaded
136 (setf (alist-get ?. avy-dispatch-alist) 'avy-action-embark)))
1185 137
1186 (:with-feature isearch 138(setup (:straight (capf-autosuggest
1187 (:bind "M-j" #'avy-isearch))) 139 :repo "https://repo.or.cz/emacs-capf-autosuggest.git"))
140 (:hook-into eshell-mode
141 comint-mode))
1188 142
1189(setup (:straight circe) 143(setup (:straight circe)
1190 (require 'circe) 144 (:require _circe)
1191 (require 'acdw-irc) 145 (:require +circe)
1192 (:also-load acdw-circe) 146 (autoload '+irc "+circe" "Connect to IRC." t)
1193
1194 (defun acdw-circe/format-meta (string)
1195 "Return a format string for `lui-format'."
1196 (format "{nick:%1$d.%1$ds} *** %s" (- acdw-irc/left-margin 3) string))
1197 147
1198 (:option acdw-irc/left-margin 20 148 ;; Formatting options
1199 circe-channel-killed-confirmation nil 149 (:option circe-format-action (format (format "%%%ds* {nick} {body}"
1200 circe-color-nicks-everywhere t 150 (- +circe-left-margin 2))
1201 circe-default-nick "acdw" 151 " ")
1202 circe-default-part-message "See You, Space Cowpokes . . ." 152 circe-format-say (format "{nick:%1$d.%1$ds} | {body}"
1203 circe-default-user "acdw" 153 (- +circe-left-margin 3))
1204 circe-format-action (format
1205 (format "%%%ds* {nick} {body}"
1206 (- acdw-irc/left-margin 2)) " ")
1207 circe-format-say (format
1208 "{nick:%1$d.%1$ds} | {body}"
1209 (- acdw-irc/left-margin 3))
1210 circe-format-self-action circe-format-action 154 circe-format-self-action circe-format-action
1211 circe-format-self-say (format 155 circe-format-self-say (replace-regexp-in-string "|" ">"
1212 "{nick:%1$d.%1$ds} > {body}" 156 circe-format-say)
1213 (- acdw-irc/left-margin 3)) 157 circe-format-server-part (+circe-format-meta
1214 circe-format-server-part (acdw-circe/format-meta
1215 "PART {channel}: {reason}") 158 "PART {channel}: {reason}")
1216 circe-format-server-quit (acdw-circe/format-meta "QUIT: {reason}") 159 circe-format-server-quit (+circe-format-meta "QUIT: {reason}")
1217 circe-format-server-quit-channel (acdw-circe/format-meta 160 circe-format-server-quit-channel (+circe-format-meta
1218 "QUIT {channel}: {reason}") 161 "QUIT {channel}: {reason}")
1219 circe-format-server-join (acdw-circe/format-meta "JOIN: {userinfo}") 162 circe-format-server-join (+circe-format-meta "JOIN: {userinfo}")
1220 circe-format-server-rejoin (acdw-circe/format-meta 163 circe-format-server-rejoin (+circe-format-meta
1221 (concat "REJOIN: {userinfo}" 164 (concat "REJOIN: {userinfo} "
1222 " after {departuredelta}")) 165 "after {departuredelta}"))
1223 circe-format-server-topic (acdw-circe/format-meta 166 circe-format-server-topic (+circe-format-meta
1224 "TOPIC: {new-topic}") 167 "TOPIC: {new-topic}")
1225 circe-prompt-string (format (format "%%%ds> " 168 circe-prompt-string (format (format "%%%ds> "
1226 (- acdw-irc/left-margin 2)) 169 (- +circe-left-margin 2))
1227 " ") 170 " "))
171
172 (:option +circe-network-inhibit-autoconnect _circe-network-inhibit-autoconnect
173 circe-network-options _circe-network-options
174 circe-color-nicks-everywhere t
175 circe-default-part-message "See You, Space Cowpokes . . ."
176 circe-default-user user-real-login-name
1228 circe-reduce-lurker-spam t 177 circe-reduce-lurker-spam t
1229 circe-server-auto-join-default-type :after-auth 178 circe-server-auto-join-default-type :after-auth)
1230 circe-server-buffer-action (lambda (buf) 179 (:bind "C-c C-p" 'circe-command-PART
1231 (message "Connected to %s" buf))) 180 "C-c C-t" '+circe-current-topic
1232 181 "C-l" 'lui-track-jump-to-indicator
1233 (with-eval-after-load 'circe 182 "C-<return>" '+circe-chat@set-prompt)
1234 (:face circe-nick-highlight-face
1235 ((t (:inherit (modus-themes-hl-line modus-themes-bold))))
1236 ;; circe-my-message-face
1237 ;; ((t (:inherit (modus-themes-slant))))
1238 ))
1239 183
1240 (with-eval-after-load 'topsy 184 (advice-add 'circe-command-PART :after '+circe-kill-buffer)
1241 (:option (append topsy-mode-functions) 185 (advice-add 'circe-command-QUIT :after '+circe-quit@kill-buffer)
1242 '(circe-channel-mode . circe-current-topic))) 186 (advice-add 'circe-command-GQUIT :after '+circe-gquit@kill-buffer)
1243 187
1244 (:bind "C-c C-p" #'circe-command-PART
1245 "C-c C-t" #'circe-current-topic ; in acdw-circe.el
1246 "C-l" #'lui-track-jump-to-indicator
1247 "<C-return>" #'circe-chat@set-prompt)
1248
1249 (:advise circe-command-PART :after #'circe-part@kill-buffer
1250 circe-command-QUIT :after #'circe-quit@kill-buffer
1251 circe-command-GQUIT :after #'circe-gquit@kill-buffer)
1252
1253 (:with-mode circe-chat-mode 188 (:with-mode circe-chat-mode
1254 (:hook #'acdw/stop-paren-annoyances 189 (:hook 'enable-circe-color-nicks
1255 #'enable-circe-color-nicks 190 'enable-circe-new-day-notifier
1256 ;; #'enable-circe-display-images 191 '+circe-chat@set-prompt)
1257 #'enable-circe-new-day-notifier 192 (:bind "C-c C-s" 'circe-command-SLAP))
1258 #'circe-chat@set-prompt
1259 #'topsy-mode))
1260 (:bind "C-c C-s" #'circe-command-SLAP)
1261
1262 (autoload 'circe-nick-color-reset "circe-color-nicks")
1263 (add-hook 'modus-themes-after-theme-hook
1264 #'circe-nick-color-reset)
1265 193
1266 (:with-mode lui-mode 194 (:with-mode lui-mode
1267 (:option lui-fill-column (+ fill-column acdw-irc/left-margin) 195 (:option lui-fill-column (+ fill-column +circe-left-margin)
1268 lui-fill-type nil ;;(repeat-string acdw-irc/left-margin " ") 196 lui-fill-type nil
1269 lui-time-stamp-position 'right-margin 197 lui-time-stamp-position 'right-margin
1270 lui-time-stamp-format "%H:%M" 198 lui-time-stamp-format "[ %H:%M"
1271 lui-track-behavior 'before-switch-to-buffer 199 lui-track-behavior 'before-switch-to-buffer
1272 lui-track-indicator 'fringe 200 lui-track-indicator 'fringe
1273 lui-fill-remove-face-from-newline nil) 201 lui-fill-remove-face-from-newline nil)
1274 202 (:hook 'visual-line-mode
1275 (:hook #'visual-fill-column-mode 203 'enable-lui-track
1276 #'visual-line-mode 204 'visual-fill-column-mode)
1277 #'enable-lui-track) 205 (:local-set fringes-outside-margins t
1278 206 right-margin-width (length lui-time-stamp-format)
1279 (:face lui-time-stamp-face
1280 ((t :inherit font-lock-comment-face)))
1281
1282 (:local-set visual-fill-column-extra-text-width
1283 (cons acdw-irc/left-margin 0)
1284 fringes-outside-margins t
1285 right-margin-width 5
1286 scroll-margin 0 207 scroll-margin 0
1287 word-wrap t 208 word-wrap t
1288 wrap-prefix (repeat-string acdw-irc/left-margin " ") 209 wrap-prefix (+string-repeat +circe-left-margin " ")
1289 nyan-mode nil
1290 line-number-mode nil 210 line-number-mode nil
1291 column-number-mode nil 211 column-number-mode nil
1292 file-percentage-mode nil)) 212 file-percentage-mode nil
213 visual-fill-column-extra-text-width
214 (cons +circe-left-margin 0)))
1293 215
1294 (add-hook 'kill-emacs-hook 216 (add-hook 'kill-emacs-hook
1295 (defun circe-quit-all () 217 (defun circe-quit-all ()
1296 (ignore-errors 218 (ignore-errors
1297 (advice-remove 'circe-command-GQUIT 'circe-gquit@kill-buffer) 219 (advice-remove 'circe-command-GQUIT
220 'circe-gquit@kill-buffer)
1298 (circe-command-GQUIT "Quitting Emacs, bye!"))))) 221 (circe-command-GQUIT "Quitting Emacs, bye!")))))
1299 222
1300(setup (:straight (command-log-mode 223(setup (:straight consult)
1301 :host github 224 (:also-load +consult)
1302 :repo "positron-solutions/command-log-mode")) 225 ;; from Consult wiki
1303 ;; I have many ideas as to how to change this.
1304 (:option clm-window-text-scale 0
1305 clm-logging-shows-buffer t
1306 clm-log-globally t
1307 clm-exceptions '(self-insert-command)
1308 clm-window-size 0.25)
1309 (el-patch-feature command-log-mode)
1310 (with-eval-after-load 'command-log-mode
1311 (el-patch-defun clm--show-buffer (&optional clear)
1312 "Displays the command log buffer in a window.
1313CLEAR will clear the buffer if it exists before returning it."
1314 (let ((buffer (clm--setup-buffer clear)))
1315 (let ((win (get-buffer-window buffer)))
1316 (unless (windowp win)
1317 (let ((new-win (el-patch-swap
1318 (split-window-horizontally
1319 (- 0 clm-window-size))
1320 (if (< (window-pixel-width) (window-pixel-height))
1321 (split-window-vertically
1322 (- (if (floatp clm-window-size)
1323 (floor (* (window-height) clm-window-size))
1324 clm-window-size)))
1325 (split-window-horizontally
1326 (- (if (floatp clm-window-size)
1327 (floor (* (window-width) clm-window-size))
1328 clm-window-size)))))))
1329 (set-window-buffer new-win buffer)
1330 (set-window-dedicated-p new-win t)
1331 (el-patch-add
1332 (with-current-buffer buffer
1333 (setq-local mode-line-format nil)))))
1334 buffer)))))
1335
1336(setup (:straight (consult
1337 :host github
1338 :repo "minad/consult"))
1339
1340 (:require acdw-consult)
1341 (:autoload consult-register-preview)
1342
1343 ;; Bindings
1344 (:global
1345 ;; C-c bindings (`mode-specific-map')
1346 ;; I don't use any of these right now.
1347 ;; "C-c h" #'consult-history
1348 ;; "C-c m" #'consult-mode-command
1349 ;; "C-c b" #'consult-bookmark
1350 ;; "C-c k" #'consult-kmacro
1351 ;; C-x bindings (`ctl-x-map')
1352 "C-x M-:" #'consult-complex-command
1353 "C-x b" #'consult-buffer
1354 "C-x 4 b" #'consult-buffer-other-window
1355 "C-x 5 b" #'consult-buffer-other-frame
1356 ;; Custom M-# bindings for fast register access
1357 "M-#" #'consult-register-load
1358 "M-'" #'consult-register-store
1359 "C-M-#" #'consult-register
1360 ;; M-g bindings (`goto-map')
1361 "M-g e" #'consult-compile-error
1362 "M-g g" #'consult-goto-line
1363 "M-g M-g" #'consult-goto-line
1364 "M-g o" #'consult-outline
1365 "M-g m" #'consult-mark
1366 "M-g k" #'consult-global-mark
1367 "M-g i" #'consult-imenu
1368 "M-g I" #'consult-project-imenu
1369 ;; M-s bindings (`search-map')
1370 "M-s g" #'acdw-consult/sensible-grep
1371 "M-s f" #'acdw-consult/sensible-find
1372 "M-s l" #'consult-line
1373 "M-s m" #'consult-multi-occur
1374 "M-s k" #'consult-keep-lines
1375 "M-s u" #'consult-focus-lines
1376 ;; Other bindings
1377 "M-y" #'consult-yank-pop
1378 "<help> a" #'consult-apropos
1379 ;; Isearch integration
1380 "M-s e" #'consult-isearch)
1381
1382 (:with-map isearch-mode-map
1383 (:bind "M-e" #'consult-isearch
1384 "M-s e" #'consult-isearch
1385 "M-s l" #'consult-line))
1386
1387 (:option (append consult-buffer-sources) #'circe-buffer-source)
1388
1389 (consult-history-to-modes ((minibuffer-local-map . nil)
1390 (shell-mode-map . shell-mode-hook)
1391 (term-mode-map . term-mode-hook)
1392 (term-raw-map . term-mode-hook)
1393 (comint-mode-map . comint-mode-hook)
1394 (sly-mrepl-mode-map . sly-mrepl-hook)))
1395
1396 (:option register-preview-delay 0 226 (:option register-preview-delay 0
1397 register-preview-function #'consult-register-format 227 register-preview-function 'consult-register-format
1398 xref-show-xrefs-function #'consult-xref 228 xref-show-xrefs-function 'consult-xref
1399 xref-show-definitions-function #'consult-xref 229 xref-show-definitions-function 'consult-xref
1400 consult-project-root-function #'vc-root-dir 230 tab-always-indent 'complete
1401 completion-in-region-function #'acdw-consult/complete-in-region 231 completion-in-region-function 'consult-completion-in-region)
1402 completion-cycle-threshold 3 232 (advice-add 'register-preview :override 'consult-register-window)
1403 consult-preview-key (kbd "M-.") 233 (advice-add 'completing-read-multiple :override
1404 tab-always-indent 'complete) 234 'consult-completing-read-multiple)
1405 235 (dolist (binding '(;; C-c bindings (mode-specific-map)
1406 (:advise register-preview :override #'consult-register-window) 236 ("C-c h" . consult-history)
1407 237 ("C-c m" . consult-mode-command)
1408 ;; Completing-read-multple 238 ("C-c b" . consult-bookmark)
1409 (if (fboundp #'consult-completing-read-multiple) 239 ("C-c k" . consult-kmacro)
1410 (:advise completing-read-multple :override 240 ;; C-x bindings (ctl-x-map)
1411 #'consult-completing-read-multiple) 241 ("C-x M-:" . consult-complex-command)
1412 (:advise completing-read-multiple :filter-args 242 ("C-x b" . consult-buffer)
1413 (defun crm-indicator (args) 243 ("C-x 4 b" . consult-buffer-other-window)
1414 (cons (concat "[CRM] " (car args)) (cdr args))))) 244 ("C-x 5 b" . consult-buffer-other-frame)
1415 245 ;; Custom M-# bindings for fast register access
1416 (with-eval-after-load 'orderless 246 ("M-#" . consult-register-load)
1417 (:option consult--regexp-compiler 247 ("M-'" . consult-register-store)
1418 #'consult--orderless-regexp-compiler)) 248 ("C-M-#" . consult-register)
1419 249 ;; Other custom bindings
1420 (with-eval-after-loads (vertico consult) 250 ("M-y" . consult-yank-pop)
1421 (:with-map consult-crm-map 251 ("<help> a" . consult-apropos)
1422 (:bind "RET" (defun +vertico-crm-exit () 252 ;; M-g bindings (goto-map)
1423 (interactive) 253 ("M-g e" . consult-compile-error)
1424 (run-at-time 0 nil #'vertico-exit) 254 ("M-g f" . consult-flymake) ; or consult-flycheck
1425 (funcall #'vertico-exit)) 255 ("M-g g" . consult-goto-line)
1426 "TAB" #'vertico-exit)))) 256 ("M-g M-g" . consult-goto-line)
1427 257 ("M-g o" . consult-outline) ; or consult-org-heading
1428(setup (:straight consult-dir) 258 ("M-g m" . consult-mark)
1429 (:with-feature project 259 ("M-g k" . consult-global-mark)
1430 (:autoload project--read-project-list)) 260 ("M-g i" . consult-imenu)
1431 (:global "C-x C-d" #'consult-dir) 261 ("M-g I" . consult-imenu-multi)
1432 (with-eval-after-load 'vertico 262 ;; M-s bindings (search-map)
1433 (:with-map vertico-map 263 ("M-s f" . consult-find)
1434 (:bind "C-x C-d" #'consult-dir 264 ("M-s F" . consult-locate)
1435 "C-x C-j" #'consult-dir-jump-file)))) 265 ("M-s g" . consult-grep)
1436 266 ("M-s G" . consult-git-grep)
1437(setup (:straight crux) 267 ("M-s r" . consult-ripgrep)
1438 (:global "C-o" #'crux-smart-open-line 268 ("M-s l" . consult-line)
1439 "M-o" #'open-paragraph 269 ("M-s L" . consult-line-multi)
1440 "C-M-\\" #'crux-cleanup-buffer-or-region 270 ("M-s m" . consult-multi-occur)
1441 "C-x 4 t" #'crux-transpose-windows) 271 ("M-s k" . consult-keep-lines)
1442 272 ("M-s u" . consult-focus-lines)
1443 (el-patch-feature crux) 273 ;; Isearch integration
1444 (with-eval-after-load 'crux 274 ("M-s e" . consult-isearch-history)))
1445 (el-patch-defun crux-reopen-as-root () 275 (global-set-key (kbd (car binding)) (cdr binding)))
1446 "Find file as root if necessary. 276 (with-eval-after-load 'isearch-mode
1447 277 (dolist (binding '(("M-e" . consult-isearch-history)
1448Meant to be used as `find-file-hook'. 278 ("M-s e" . consult-isearch-history)
1449See also `crux-reopen-as-root-mode'." 279 ("M-s l" . consult-line)
1450 (unless (or 280 ("M-s L" . consult-line-multi)))
1451 ;; This helps fix for `nov-mode', and possibly others. 281 (define-key isearch-mode-map (car binding) (cdr binding))))
1452 (el-patch-add (null buffer-file-name)) 282 (with-eval-after-load 'org-mode
1453 (tramp-tramp-file-p buffer-file-name) 283 (define-key org-mode-map "M-g o" 'consult-org-heading))
1454 (equal major-mode 'dired-mode) 284 (with-eval-after-load 'consult
1455 (not (file-exists-p (file-name-directory buffer-file-name))) 285 (:option consult-narrow-key "<"
1456 (file-writable-p buffer-file-name) 286 consult-project-root-function '+consult-project-root)
1457 (crux-file-owned-by-user-p buffer-file-name)) 287 (consult-customize
1458 (crux-find-alternate-file-as-root buffer-file-name)))) 288 consult-theme
1459 289 :preview-key '(:debounce 0.2 any)
1460 (crux-reopen-as-root-mode +1)) 290 consult-ripgrep consult-git-grep consult-grep
1461 291 consult-bookmark consult-recent-file consult-xref
1462;; (setup (:straight-when 292 consult--source-file consult--source-project-file
1463;; (define-repeat-map 293 consult--source-bookmark
1464;; :host nil 294 :preview-key (kbd "M-."))
1465;; :repo "https://tildegit.org/acdw/define-repeat-map.el") 295 (consult-history-to-modes ((minibuffer-local-map . nil)
1466;; (acdw/system :home)) 296 (shell-mode-map . shell-mode-hook)
1467 297 (term-mode-map . term-mode-hook)
1468;; (require 'define-repeat-map ; just for me 298 (term-raw-map . term-mode-hook)
1469;; (acdw/dir 299 (comint-mode-map . comint-mode-hook)
1470;; "straight/build/define-repeat-map/define-repeat-map.el")) 300 (sly-mrepl-mode-map . sly-mrepl-hook)))
1471 301 (with-eval-after-load 'orderless
1472;; (defun acdw/other-window-or-switch-buffer-backward () 302 (:option consult--regexp-compiler 'consult--orderless-regexp-compiler))))
1473;; (interactive)
1474;; (setq repeat-map 'other-window-repeat-map)
1475;; (acdw/other-window-or-switch-buffer -1))
1476
1477;; (define-repeat-map other-window
1478;; ("o" acdw/other-window-or-switch-buffer
1479;; "O" acdw/other-window-or-switch-buffer-backward))
1480
1481;; (define-repeat-map case
1482;; ("c" capitalize-word
1483;; "u" upcase-dwim
1484;; "l" downcase-dwim)
1485;; (:continue "f" forward-word
1486;; "b" backward-word)
1487;; (:enter capitalize-dwim
1488;; upcase-dwim
1489;; downcase-dwim))
1490
1491;; (define-repeat-map page-navigation
1492;; ("]" forward-page
1493;; "[" backward-page))
1494
1495;; (define-repeat-map windmove
1496;; (;; moving
1497;; "<left>" windmove-left
1498;; "<right>" windmove-right
1499;; "<up>" windmove-up
1500;; "<down>" windmove-down
1501;; ;; swapping
1502;; "<S-left>" windmove-swap-states-left
1503;; "<S-right>" windmove-swap-states-right
1504;; "<S-up>" windmove-swap-states-up
1505;; "<S-down>" windmove-swap-states-down))
1506
1507;; (define-repeat-map winner-mode
1508;; ("/" winner-undo
1509;; "?" winner-redo)))
1510 303
1511(setup (:straight dictionary) 304(setup (:straight dictionary)
1512 (:option dictionary-use-single-buffer t) 305 (:option dictionary-use-single-buffer t)
1513
1514 (autoload 'dictionary-search "dictionary" 306 (autoload 'dictionary-search "dictionary"
1515 "Ask for a word and search it in all dictionaries" t) 307 "Ask for a word and search it in all dictionaries" t)
1516 (autoload 'dictionary-match-words "dictionary" 308 (autoload 'dictionary-match-words "dictionary"
@@ -1526,226 +318,29 @@ See also `crux-reopen-as-root-mode'."
1526 (autoload 'dictionary-tooltip-mode "dictionary" 318 (autoload 'dictionary-tooltip-mode "dictionary"
1527 "Display tooltips for the current word" t) 319 "Display tooltips for the current word" t)
1528 (autoload 'global-dictionary-tooltip-mode "dictionary" 320 (autoload 'global-dictionary-tooltip-mode "dictionary"
1529 "Enable/disable dictionary-tooltip-mode for all buffers" t) 321 "Enable/disable dictionary-tooltip-mode for all buffers" t))
1530
1531 (define-key lookup-map "d" #'dictionary-search)
1532
1533 (:hook #'reading-mode))
1534
1535(setup (:straight (dogears
1536 :host github
1537 :repo "alphapapa/dogears.el"
1538 :files (:defaults
1539 (:exclude "helm-dogears.el"))))
1540 (:option (append savehist-additional-variables) 'dogears-list)
1541 (with-eval-after-load 'dogears
1542 (dolist (mode '(magit-status-mode
1543 elfeed-show-mode
1544 elfeed-search-mode))
1545 (:option (append dogears-ignore-modes) mode)))
1546 (:global "M-g d" dogears-go)
1547 (:autoload dogears-mode)
1548 (dogears-mode +1))
1549
1550(setup (:straight edit-indirect))
1551 322
1552;; requires extension: 323(setup (:straight electric-cursor)
1553;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/
1554(setup (:straight edit-server)
1555 (:require edit-server)
1556 (edit-server-start)
1557
1558 (:option edit-server-default-major-mode 'text-mode
1559 edit-server-url-major-mode-alist
1560 (list (cons (rx (| "reddit.com"
1561 "tildes.net"))
1562 'markdown-mode)
1563 (cons (rx "github.com")
1564 'gfm-mode)
1565 (cons "." 'text-mode)))
1566
1567 (:advise edit-server-make-frame :before
1568 (defun edit-server@set-a-variable (&rest _)
1569 (setq-local edit-server-frame-p t))))
1570
1571(setup (:straight (electric-cursor
1572 :host github
1573 :repo "duckwork/electric-cursor"))
1574 (electric-cursor-mode +1)) 324 (electric-cursor-mode +1))
1575 325
1576(setup (:straight (elfeed 326(setup (:straight electric-cursor)
1577 :host github 327 (electric-cursor-mode +1))
1578 :repo "skeeto/elfeed")
1579 elfeed-protocol)
1580 (:option elfeed-use-curl t
1581 elfeed-curl-extra-arguments '("--insecure")
1582 elfeed-feeds `(("fever+https://acdw@mf.acdw.net"
1583 :api-url "https://mf.acdw.net/fever/"
1584 :password ,(acdw/make-password-fetcher
1585 :host "mf.acdw.net")
1586 :autotags ; do I want to use elfeed-org ?
1587 '(("r/emacs" reddit social emacs)
1588 ("protesilaos.com/codelog.xml" emacs)
1589 ("tildes.net" social)
1590 ("catandgirl.com" comics)
1591 ("qwantz.com" comics)
1592 ("emacsninja.com" emacs)
1593 ("falseknees.com" comics)
1594 ("emacslife.com" emacs)
1595 ("lisp.org" lisp programming)
1596 ("scheme.org" scheme programming)
1597 ("smbc-comics.com" comics)
1598 ("youtube.com" video)
1599 ("tilde.news" social)
1600 ("xkcd.com" comics))))
1601 elfeed-show-unique-buffers t)
1602 (:autoload elfeed-set-timeout)
1603 (elfeed-set-timeout 3600)
1604 (elfeed-protocol-enable)
1605 (:advise elfeed :after
1606 (defun elfeed@protocol-update (&rest _)
1607 (elfeed-search-fetch nil)))
1608 (:with-mode elfeed-search-mode
1609 (:bind "G" (defun elfeed-protocol|update-first (arg)
1610 (interactive "P")
1611 (let ((first-proto (caar elfeed-feeds)))
1612 (if arg
1613 (call-interactively #'elfeed-protocol-fever-reinit)
1614 (with-temp-message (format "Updating %s" first-proto)
1615 (elfeed-protocol-fever-reinit first-proto)))))))
1616 (:with-mode elfeed-show-mode
1617 (:hook #'reading-mode)
1618 (:local-set shr-max-image-proportion 0.9
1619 visual-fill-column-width (+ fill-column 5))
1620 ;; see https://irreal.org/blog/?p=8885
1621 (:bind "SPC" (defun elfeed-scroll-up-command (&optional arg)
1622 "Scroll up or go to next feed item in Elfeed"
1623 (interactive "^P")
1624 (let ((scroll-error-top-bottom nil))
1625 (condition-case-unless-debug nil
1626 (scroll-up-command arg)
1627 (error (elfeed-show-next)))))
1628 "S-SPC" (defun elfeed-scroll-down-command (&optional arg)
1629 "Scroll up or go to next feed item in Elfeed"
1630 (interactive "^P")
1631 (let ((scroll-error-top-bottom nil))
1632 (condition-case-unless-debug nil
1633 (scroll-down-command arg)
1634 (error (elfeed-show-prev))))))))
1635
1636(setup (:straight elisp-slime-nav)
1637 (:hook-into emacs-lisp-mode
1638 ielm-mode))
1639
1640(setup (:straight (elpher
1641 :host nil
1642 :repo "git://thelambdalab.xyz/elpher.git"))
1643 (:option elpher-ipv4-always t
1644 elpher-certificate-directory (acdw/dir "elpher/")
1645 elpher-gemini-max-fill-width fill-column)
1646
1647 (:bind "n" #'elpher-next-link
1648 "p" #'elpher-prev-link
1649 "o" #'elpher-follow-current-link
1650 "G" #'elpher-go-current)
1651
1652 (:hook #'reading-mode)
1653
1654 (:autoload (elpher-bookmarks :interactive t)
1655 (elpher-go :interactive t))
1656
1657 ;; Make `eww' gemini/gopher aware. From Emacswiki.
1658 ;; (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher)
1659 ;; (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
1660 ;; (require 'elpher)
1661 ;; (elpher-go url))
1662 ;; (t (apply fn url args))))
1663 )
1664
1665(setup (:straight-when emacs-everywhere
1666 (and (executable-find "xclip")
1667 (executable-find "xdotool")
1668 (executable-find "xprop")
1669 (executable-find "xwininfo"))))
1670
1671(setup (:straight (embark ; gotta git that fresh fresh
1672 :host github
1673 :repo "oantolin/embark"))
1674 (:global "C-." #'embark-act)
1675 (:option prefix-help-command #'embark-prefix-help-command
1676 (append display-buffer-alist)
1677 `(,(rx (seq bos "*Embark Collect "
1678 (group (| "Live" "Completions"))
1679 "*"))
1680 nil
1681 (window-parameters (mode-line-format . none)))
1682 embark-prompter #'embark-keymap-prompter
1683 embark-verbose-indicator-display-action
1684 '(display-buffer-at-bottom (window-height . fit-window-to-buffer))
1685 embark-action-indicator
1686 (lambda (map _target)
1687 (which-key--show-keymap "Embark" map nil nil 'no-paging)
1688 #'which-key--hide--ignore-command)
1689 embark-become-indicator embark-action-indicator)
1690
1691 (with-eval-after-loads (embark consult)
1692 (:straight embark-consult)
1693 (add-hook 'embark-collect-mode-hook
1694 #'consult-preview-at-point-mode)))
1695 328
1696(setup (:straight epithet) 329(setup (:straight embark)
1697 (dolist (hook '(Info-selection-hook 330 (:option prefix-help-command 'embark-prefix-help-command)
1698 eww-after-render-hook 331 (:global "C-." 'embark-act
1699 help-mode-hook 332 "M-." 'embark-dwim
1700 occur-mode-hook)) 333 "C-h B" 'embark-bindings))
1701 (add-hook hook #'epithet-rename-buffer)))
1702 334
1703;; TODO: look into emms or something related for this 335(setup (:straight embark-consult)
1704(setup (:straight-when eradio 336 (:load-after consult embark)
1705 (executable-find "mpv")) 337 (add-hook 'embark-collect-mode-hook 'consult-preview-at-point-mode))
1706 (:option
1707 eradio-player '("mpv" "--no-video" "--no-terminal")
1708 eradio-channels `(("KLSU" .
1709 "http://130.39.238.143:8010/stream.mp3")
1710 ("Soma FM Synphaera" .
1711 "https://somafm.com/synphaera256.pls")
1712 ("SomaFM BAGel Radio" .
1713 "https://somafm.com/bagel.pls")
1714 ("SomaFM Boot Liquor" .
1715 "https://somafm.com/bootliquor320.pls")
1716 ("SomaFM Deep Space One" .
1717 "https://somafm.com/deepspaceone.pls")
1718 ("SomaFM Fluid" .
1719 "https://somafm.com/fluid.pls")
1720 ("SomaFM Underground 80s" .
1721 "https://somafm.com/u80s256.pls")
1722 ("WBRH: Jazz & More" .
1723 "http://wbrh.streamguys1.com/wbrh-mp3")
1724 ("KBRH Blues & Rhythm Hits" .
1725 "http://wbrh.streamguys1.com/kbrh-mp3")
1726 ("WRKF HD-2" .
1727 ,(concat "https://playerservices.streamtheworld.com/"
1728 "api/livestream-redirect/WRKFHD2.mp3"))
1729 ("WRKF: NPR for the Capital Region" .
1730 ,(concat "https://playerservices.streamtheworld.com/"
1731 "api/livestream-redirect/WRKFFM.mp3"))
1732 ("BadRadio: 24/7 PHONK" .
1733 "https://s2.radio.co/s2b2b68744/listen")
1734 ("tilderadio" .
1735 "https://azuracast.tilderadio.org/radio/8000/radio.ogg")
1736 ("vantaradio" .
1737 "https://vantaa.black/radio")))
1738 (:global "C-c r r" #'eradio-play ; mnemonic: radio
1739 "C-c r s" #'eradio-stop ; mnemonic: stop
1740 "C-c r p" #'eradio-toggle ; mnemonic: play/pause
1741 ))
1742 338
1743(setup (:straight eros) 339(setup (:straight eshell-syntax-highlighting)
1744 (:hook-into emacs-lisp-mode 340 (:hook-into eshell-mode))
1745 lisp-interaction-mode))
1746 341
1747(setup (:straight-when exec-path-from-shell 342(setup (:straight-when exec-path-from-shell
1748 (acdw/system :home)) 343 (eq system-type 'gnu/linux))
1749 (when (daemonp) 344 (when (daemonp)
1750 (exec-path-from-shell-initialize)) 345 (exec-path-from-shell-initialize))
1751 (exec-path-from-shell-copy-envs '("XDG_CONFIG_HOME" 346 (exec-path-from-shell-copy-envs '("XDG_CONFIG_HOME"
@@ -1755,250 +350,83 @@ See also `crux-reopen-as-root-mode'."
1755 "XDG_CACHE_HOME"))) 350 "XDG_CACHE_HOME")))
1756 351
1757(setup (:straight expand-region) 352(setup (:straight expand-region)
1758 (:global "C-=" #'er/expand-region)) 353 (:global "C-=" 'er/expand-region))
1759
1760(setup (:straight-when fennel-mode
1761 (executable-find "fennel"))
1762 (:autoload (fennel-repl :interactive t))
1763 (:file-match (rx ".fnl" eos)))
1764
1765(setup (:straight flyspell-correct)
1766 (:option flyspell-correct-interface #'flyspell-correct-completing-read
1767 flyspell-correct--cr-key ";")
1768 354
1769 (:with-feature flyspell 355(setup (:straight (filldent
1770 (:bind "C-." #'flyspell-correct-wrapper 356 :host github
1771 "<f7>" (defun acdw/flyspell-correct-f7 () 357 :repo "duckwork/filldent.el"))
1772 "Run a full spell correction on the current buffer." 358 (:global "M-q" 'filldent-dwim))
1773 (interactive)
1774 (save-mark-and-excursion
1775 (flyspell-correct-move 0 :forward :rapid))))
1776 (:unbind "C-;" "C-," "C-." "C-M-i")))
1777
1778(setup (:straight-when forge
1779 (acdw/system :home))
1780 ;; make sure to read Info manual with Forge (and Ghub) for setup
1781 ;; instructions.
1782 (with-eval-after-load 'magit
1783 (require 'forge)
1784 (add-to-list 'forge-alist ; tildegit is a gitea server
1785 '("tildegit.org" "tildegit.org/api/v1" "tildegit.org"
1786 forge-gitea-repository))))
1787 359
1788(setup (:straight (frowny 360(setup (:straight (frowny
1789 :host github 361 :host github
1790 :repo "duckwork/frowny.el")) 362 :repo "duckwork/frowny.el"))
1791 (:option frowny-eyes (rx (| ":" ":-" ":'" "="))
1792 frowny-eyes-looking-back-limit 2)
1793 (global-frowny-mode +1)) 363 (global-frowny-mode +1))
1794 364
1795(setup (:straight gcmh) 365(setup (:straight gcmh)
1796 (:option gcmh-idle-delay 'auto) 366 (:option gcmh-idle-delay 'auto)
1797 (gcmh-mode +1)) 367 (gcmh-mode +1))
1798 368
1799(setup (:straight-when geiser
1800 (progn
1801 (defvar acdw/schemes
1802 (let (schemes)
1803 (dolist (scheme '(("scheme" . geiser-chez) ; chez
1804 ("petite" . geiser-chez) ; petite
1805 ("csi" . geiser-chez) ; chicken
1806 ("gsi" . geiser-gambit)
1807 ("gosh" . geiser-gauche)
1808 ("guile" . geiser-guile)
1809 ("kawa" . geiser-kawa)
1810 ("mit-scheme" . geiser-mit)
1811 ("racket" . geiser-racket)
1812 ("stklos" . geiser-stklos)))
1813 (when-let (binary (executable-find (car scheme)))
1814 (push binary schemes)
1815 ;; and install the proper helper package
1816 (straight-use-package (cdr scheme))))
1817 (nreverse schemes)))
1818 acdw/schemes))
1819 (:file-match (rx ".rkt" eos)
1820 (rx ".scm" eos)))
1821
1822(setup (:straight (gemini-mode
1823 :host nil
1824 :repo "https://git.carcosa.net/jmcbray/gemini.el.git"))
1825 (:file-match (rx (seq "." (or "gemini" "gmi") eos)))
1826 (:hook turn-off-auto-fill))
1827
1828(setup (:straight (gemini-write
1829 :host nil
1830 :repo "https://alexschroeder.ch/cgit/gemini-write"
1831 :branch "main"))
1832 (with-eval-after-load 'elpher
1833 (require 'gemini-write)))
1834
1835(setup (:straight git-modes))
1836
1837(setup (:straight helpful) 369(setup (:straight helpful)
1838 (:require-after 3) 370 (:global "<help> f" 'helpful-callable
1839 (:global "<help> f" #'helpful-callable 371 "<help> v" 'helpful-variable
1840 "<help> v" #'helpful-variable 372 "<help> k" 'helpful-key
1841 "<help> k" #'helpful-key 373 "C-c C-d" 'helpful-at-point))
1842 "<help> o" #'helpful-symbol)) 374
1843 375
1844(setup (:straight (hippie-completing-read 376(setup (:straight (hippie-completing-read
1845 :host github 377 :host github
1846 :repo "duckwork/hippie-completing-read")) 378 :repo "duckwork/hippie-completing-read"))
1847 (:global "M-/" #'hippie-completing-read)) 379 (:global "M-/" 'hippie-completing-read))
1848 380
1849(setup (:straight hungry-delete) 381(setup (:straight hungry-delete)
1850 (:option hungry-delete-chars-to-skip " \t" 382 (:option hungry-delete-chars-to-skip " \t"
1851 hungry-delete-join-reluctantly nil) 383 hungry-delete-join-reluctantly nil)
1852 384 (:bind-into paredit
1853 (global-hungry-delete-mode +1) 385 [remap paredit-backward-delete]
1854 386 (defun acdw/paredit-hungry-delete-backward (arg)
1855 (:with-feature paredit 387 (interactive "P")
1856 (:bind [remap paredit-backward-delete] 388 (if (looking-back "[ \t]" 1)
1857 (defun acdw/paredit-hungry-delete-backward (arg) 389 (hungry-delete-backward (or arg 1))
1858 (interactive "P") 390 (paredit-backward-delete arg)))
1859 (if (looking-back "[ \t]" 1) 391 [remap paredit-forward-delete]
1860 (hungry-delete-backward (or arg 1)) 392 (defun acdw/paredit-hungry-delete-forward (arg)
1861 (paredit-backward-delete arg))) 393 (interactive "P")
1862 394 (if (looking-at "[ \t]")
1863 [remap paredit-forward-delete] 395 (hungry-delete-forward (or arg 1))
1864 (defun acdw/paredit-hungry-delete-forward (arg) 396 (paredit-forward-delete arg))))
1865 (interactive "P") 397 (global-hungry-delete-mode +1))
1866 (if (looking-at "[ \t]") 398
1867 (hungry-delete-forward (or arg 1)) 399(setup (:straight isearch-mb)
1868 (paredit-forward-delete arg)))))) 400 ;; This complicatedness is an attempt to make it easier to add and
1869 401 ;; subtract `isearch-mb' bindings using the suggestions in the
1870(setup (:straight iscroll) 402 ;; project's README.
1871 (define-globalized-minor-mode global-iscroll-mode iscroll-mode 403 (with-eval-after-load 'isearch-mb
1872 (lambda () (iscroll-mode +1))) 404 (dolist (spec '((isearch-mb--with-buffer
1873 405 ("M-e" . consult-isearch)
1874 (global-iscroll-mode +1)) 406 ("C-o" . loccur-isearch))
1875 407 (isearch-mb--after-exit
1876(setup (:straight (kaomoji-insert 408 ("M-%" . anzu-isearch-query-replace)
1877 :host nil 409 ("M-s l" . consult-line))))
1878 :repo "https://tildegit.org/acdw/kaomoji-insert")) 410 (let ((isearch-mb-list (car spec))
1879 (require 'kaomoji-insert) 411 (isearch-mb-binds (cdr spec)))
1880 (dolist (km '(("(Ծ‸ Ծ)" "suspicious") 412 (dolist (cell isearch-mb-binds)
1881 ("(¬‿¬)═ɜ ɛ═(⌐‿⌐ )" "pound it" "fist bump") 413 (let ((key (car cell))
1882 ("▬▬▬▬▬▬▬▋ Ò╭╮Ó" "hammer") 414 (command (cdr cell)))
1883 ("👁👄👁" "lewk") 415 (when (fboundp command)
1884 ("( ͡~ ͜ʖ ͡°)" "wink") 416 (add-to-list isearch-mb-list command)
1885 (" (づ ̄ ³ ̄)づ " "party") 417 (define-key isearch-mb-minibuffer-map (kbd key) command)))))))
1886 ("⊙﹏⊙" "uhhh" "unsure"))) 418 (isearch-mb-mode +1))
1887 (add-to-list 'kaomoji-insert-alist km))
1888 (:global "C-x 8 k" #'kaomoji-insert))
1889
1890;; (setup (:straight wrap-region)
1891;; (:hook-into org-mode)
1892;; (with-eval-after-load 'org
1893;; (dolist (punc '("=" "*" "/" "_" "+"))
1894;; (wrap-region-add-wrapper punc punc nil 'org-mode))))
1895 419
1896(setup (:straight lacarte) 420(setup (:straight lacarte)
1897 (:global "<f10>" #'lacarte-execute-menu-command)) 421 (:global "<f10>" 'lacarte-execute-menu-command))
1898
1899(setup (:straight-when ledger-mode
1900 (executable-find "ledger")))
1901
1902(setup (:straight link-hint)
1903 ;; Browse web URLs with a browser with a prefix argument.
1904 (dolist (type '(gnus-w3m-image-url
1905 gnus-w3m-url
1906 markdown-link
1907 mu4e-attachment
1908 mu4e-url
1909 notmuch-hello
1910 nov-link
1911 org-link
1912 shr-url
1913 text-url
1914 w3m-link
1915 w3m-message-link))
1916 (link-hint-define-type type
1917 :open-secondary browse-url-secondary-browser-function
1918 :open-secondary-multiple t))
1919
1920 (defun acdw/link-hint-open-all-links (prefix)
1921 "Open all visible links.
1922When PREFIX is non-nil, open links with
1923`browse-url-secondary-browser-function'."
1924 (interactive "P")
1925 (avy-with link-hint-open-all-links
1926 (link-hint--all (if prefix :open-secondary :open))))
1927
1928 (defun acdw/link-hint-open-multiple-links (prefix)
1929 "Use `avy' to open multiple visible links at once.
1930When PREFIX is non-nil, open links with
1931`browse-url-secondary-browser-function'."
1932 (interactive "P")
1933 (avy-with link-hint-open-multiple-links
1934 (link-hint--multiple (if prefix :open-secondary :open))))
1935
1936 (:option link-hint-avy-style 'at-full)
1937 (:global "C-j"
1938 (defun acdw/link-hint-open-link (arg)
1939 "Open a link using `link-hint-open-link', prefix-aware.
1940That is, a prefix argument (\\[universal-argument]) will open the
1941browser defined in `browse-url-secondary-browser-function'."
1942 (interactive "P")
1943 (avy-with link-hint-open-link
1944 (link-hint--one (if arg :open-secondary :open))))))
1945
1946(setup (:straight lua-mode)
1947 (:file-match (rx ".lua" eos)))
1948
1949(setup (:straight macrostep)
1950 (define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand)
1951 (define-key lisp-interaction-mode-map (kbd "C-c e") #'macrostep-expand))
1952
1953(setup (:straight magit)
1954 (:global "C-x g" #'magit-status)
1955
1956 (:option magit-display-buffer-function
1957 (defun magit-display-buffer-same-window (buffer)
1958 "Display BUFFER in the selected window like God intended."
1959 (display-buffer buffer '(display-buffer-same-window)))
1960 magit-popup-display-buffer-action '((display-buffer-same-window))
1961 magit-refresh-status-buffer nil))
1962 422
1963(setup (:straight marginalia) 423(setup (:straight marginalia)
1964 (:option marginalia-annotators '(marginalia-annotators-heavy
1965 marginalia-annotators-light))
1966 (marginalia-mode +1)) 424 (marginalia-mode +1))
1967 425
1968(setup (:straight markdown-mode) 426(setup (:straight minions)
1969 (:file-match (rx ".md" eos) 427 (:option minions-prominent-modes
1970 (rx ".markdown" eos)) 428 '(tracking-mode))
1971 (:hook #'variable-pitch-mode 429 (minions-mode +1))
1972 #'visual-fill-column-mode)
1973
1974 (:with-mode gfm-mode
1975 (:file-match (rx "README.md" eos))
1976 (:hook #'variable-pitch-mode))
1977
1978 (when (executable-find "markdownfmt")
1979 (with-eval-after-load 'apheleia
1980 (:option (append apheleia-formatters) '(markdownfmt . ("markdownfmt"))
1981 (append apheleia-mode-alist) '(markdown-mode . markdownfmt)
1982 (append apheleia-mode-alist) '(gfm-mode . markdownfmt)))))
1983
1984(setup (:straight (mastodon
1985 :host github
1986 :repo "mooseyboots/mastodon.el"))
1987 (:option mastodon-instance-url "https://writing.exchange"
1988 mastodon-auth-source-file (car auth-sources)
1989 mastodon-client--token-file (acdw/dir "mastodon.plstore")
1990 mastodon-tl--enable-proportional-fonts t
1991 mastodon-tl--enable-relative-timestamps nil)
1992
1993 (:hook #'hl-line-mode
1994 #'reading-mode)
1995
1996 (defun mastodon-goto-toot@recenter ()
1997 "Recenter the current toot."
1998 (recenter -1))
1999
2000 (:advise mastodon-tl--goto-next-toot :after #'mastodon-goto-toot@recenter
2001 mastodon-tl--goto-prev-toot :after #'mastodon-goto-toot@recenter))
2002 430
2003(setup (:straight mode-line-bell) 431(setup (:straight mode-line-bell)
2004 (:option mode-line-bell-flash-time 0.1) 432 (:option mode-line-bell-flash-time 0.1)
@@ -2007,164 +435,14 @@ browser defined in `browse-url-secondary-browser-function'."
2007(setup (:straight (modus-themes 435(setup (:straight (modus-themes
2008 :host gitlab 436 :host gitlab
2009 :repo "protesilaos/modus-themes")) 437 :repo "protesilaos/modus-themes"))
2010 (:option modus-themes-slanted-constructs t 438 (load-theme 'modus-operandi t))
2011 modus-themes-bold-constructs t
2012 modus-themes-fringes nil
2013 modus-themes-mode-line '(borderless)
2014 modus-themes-region '(bg-only)
2015 modus-themes-org-blocks 'gray-background
2016 modus-themes-headings '((t . (background)))
2017 modus-themes-lang-checkers '(straight-underline)
2018 modus-themes-scale-headings nil)
2019
2020 (acdw/sunrise-sunset #'modus-themes-load-operandi
2021 #'modus-themes-load-vivendi)
2022
2023 (add-hook 'modus-themes-after-load-theme-hook
2024 (defun modus-themes@customize-faces ()
2025 "Customize faces of modus-themes."
2026 ;; (dolist (face '(font-lock-builtin-face
2027 ;; ;; font-lock-comment-delimiter-face
2028 ;; ;; font-lock-coment-face
2029 ;; font-lock-constant-face
2030 ;; ;; font-lock-doc-face
2031 ;; font-lock-function-name-face
2032 ;; font-lock-keyword-face
2033 ;; font-lock-negation-char-face
2034 ;; font-lock-preprocessor-face
2035 ;; font-lock-regexp-grouping-backslash
2036 ;; font-lock-regexp-goruping-construct
2037 ;; font-lock-string-face
2038 ;; font-lock-type-face
2039 ;; font-lock-variable-name-face
2040 ;; font-lock-warning-face))
2041 ;; (modus-themes-with-colors
2042 ;; (custom-set-faces
2043 ;; `(,face
2044 ;; ((,class :foreground ,fg-main
2045 ;; :weight normal
2046 ;; :slant normal))))))
2047 ;; Other faces
2048 (modus-themes-with-colors
2049 (custom-set-faces
2050 `(org-level-1
2051 ((,class :inherit (modus-themes-heading-1 fixed-pitch)
2052 :extend t)))
2053 `(org-level-2
2054 ((,class :inherit (modus-themes-heading-2 fixed-pitch)
2055 :extend t)))
2056 `(org-level-3
2057 ((,class :inherit (modus-themes-heading-3 fixed-pitch)
2058 :extend t)))
2059 `(org-level-4
2060 ((,class :inherit (modus-themes-heading-4 fixed-pitch)
2061 :extend t)))
2062 `(org-level-5
2063 ((,class :inherit (modus-themes-heading-5 fixed-pitch)
2064 :extend t)))
2065 `(org-level-6
2066 ((,class :inherit (modus-themes-heading-6 fixed-pitch)
2067 :extend t)))
2068 `(org-level-7
2069 ((,class :inherit (modus-themes-heading-7 fixed-pitch)
2070 :extend t)))
2071 `(org-level-8
2072 ((,class :inherit (modus-themes-heading-8 fixed-pitch)
2073 :extend t))))))))
2074 439
2075(setup (:straight mwim) 440(setup (:straight mwim)
2076 (:global "C-a" #'mwim-beginning 441 (:global "C-a" #'mwim-beginning
2077 "C-e" #'mwim-end)) 442 "C-e" #'mwim-end))
2078 443
2079(setup (:straight nov) 444(setup (:straight orderless)
2080 (:option nov-text-width fill-column) 445 (:option completion-styles '(orderless)))
2081 (:file-match (rx ".epub" eos)))
2082
2083(setup (:straight (nyan-mode
2084 :host github :repo "TeMPOraL/nyan-mode"
2085 :fork (:host github :repo "duckwork/nyan-mode")
2086 :files ("nyan-mode.el" "img")))
2087 (:option nyan-animate-nyancat nil
2088 nyan-bar-length 20
2089 nyan-minimum-window-width (+ fill-column (/ nyan-bar-length 2)))
2090 (nyan-mode +1)
2091 (defun disable-nyan-mode ()
2092 "Disable `nyan-mode' in current buffer."
2093 (setq-local nyan-mode -1))
2094 (dolist (mode '(eshell-mode
2095 comint-mode))
2096 (add-hook mode #'disable-nyan-mode)))
2097
2098;; (setup (:straight olivetti)
2099;; (:option olivetti-body-width (+ fill-column 4)
2100;; olivetti-minimum-body-width fill-column)
2101
2102;; (:hook (defun olivetti-mode@setup ()
2103;; (if olivetti-mode
2104;; (setq-local indicate-empty-lines nil
2105;; indicate-buffer-boundaries nil)
2106;; (acdw/setup-fringes)))))
2107
2108(setup (:straight (orderless
2109 :host github
2110 :repo "oantolin/orderless"))
2111 (require 'orderless)
2112
2113 (:option (append completion-styles) 'orderless
2114 orderless-component-separator #'orderless-escapable-split-on-space
2115 orderless-matching-styles '(orderless-literal
2116 orderless-regexp
2117 ;; orderless-flex
2118 )
2119 orderless-style-dispatchers '(acdw/orderless-dispatch))
2120
2121 (:advise orderless-regexp :filter-args
2122 (defun fix-dollar (args)
2123 (if (string-suffix-p "$" (car args))
2124 (list (concat (substring (car args) 0 -1)
2125 "[\x100000-\x10FFFD]*$"))
2126 args)))
2127
2128 (defun acdw/orderless-dispatch (pattern _index _total)
2129 "My custom dispatcher for `orderless'."
2130 (cond
2131 ;; Ensure that $ works with Consult commands, which add disambiguation
2132 ;; suffixes -- see `fix-dollar'
2133 ((string-suffix-p "$" pattern)
2134 `(orderless-regexp . ,(concat (substring pattern 0 -1)
2135 "[\x100000-\x10FFFD]*$")))
2136 ;; File extensions
2137 ((string-match-p "\\`\\.." pattern)
2138 `(orderless-regexp . ,(concat "\\." (substring pattern 1)
2139 "[\x100000-\x10FFFD]*$")))
2140 ;; Ignore single !
2141 ((string= "!" pattern)
2142 `(orderless-literal . ""))
2143 ;; Character folding
2144 ((string-prefix-p "%" pattern)
2145 `(char-fold-to-regexp . ,(substring pattern 1)))
2146 ((string-suffix-p "%" pattern)
2147 `(char-fold-to-regexp . ,(substring pattern 0 -1)))
2148 ;; Without literal
2149 ((string-prefix-p "!" pattern)
2150 `(orderless-without-literal . ,(substring pattern 1)))
2151 ((string-suffix-p "!" pattern)
2152 `(orderless-without-literal . ,(substring pattern 0 -1)))
2153 ;; Initialism matching
2154 ((string-prefix-p "`" pattern)
2155 `(orderless-initialism . ,(substring pattern 1)))
2156 ((string-suffix-p "`" pattern)
2157 `(orderless-initialism . ,(substring pattern 0 -1)))
2158 ;; Literal matching
2159 ((string-prefix-p "=" pattern)
2160 `(orderless-literal . ,(substring pattern 1)))
2161 ((string-suffix-p "=" pattern)
2162 `(orderless-literal . ,(substring pattern 0 -1)))
2163 ;; Flex matching
2164 ((string-prefix-p "~" pattern)
2165 `(orderless-flex . ,(substring pattern 1)))
2166 ((string-suffix-p "~" pattern)
2167 `(orderless-flex . ,(substring pattern 0 -1))))))
2168 446
2169(setup (:straight (org 447(setup (:straight (org
2170 :type git 448 :type git
@@ -2179,10 +457,13 @@ browser defined in `browse-url-secondary-browser-function'."
2179 (org-contrib 457 (org-contrib
2180 :type git 458 :type git
2181 :repo "https://git.sr.ht/~bzg/org-contrib")) 459 :repo "https://git.sr.ht/~bzg/org-contrib"))
2182 (:also-load acdw-org) 460 ;; DO NOT load system-installed org !!!
2183 (require 'chd nil 'noerror) 461 (setq load-path (cl-remove-if (lambda (path)
462 (string-match-p "lisp/org\\'" path))
463 load-path))
464 (:also-load +org
465 ox-md)
2184 (:option org-adapt-indentation nil 466 (:option org-adapt-indentation nil
2185 ;; org-agenda-files nil ; only until I set this up
2186 org-catch-invisible-edits 'show-and-error 467 org-catch-invisible-edits 'show-and-error
2187 org-clock-clocked-in-display 'mode-line 468 org-clock-clocked-in-display 'mode-line
2188 org-clock-frame-title-format (cons 469 org-clock-frame-title-format (cons
@@ -2194,7 +475,7 @@ browser defined in `browse-url-secondary-browser-function'."
2194 org-confirm-babel-evaluate nil 475 org-confirm-babel-evaluate nil
2195 org-cycle-separator-lines 0 476 org-cycle-separator-lines 0
2196 org-directory "~/org" 477 org-directory "~/org"
2197 org-ellipsis " …" 478 org-ellipsis "…"
2198 org-export-coding-system 'utf-8-unix 479 org-export-coding-system 'utf-8-unix
2199 org-export-headline-levels 8 480 org-export-headline-levels 8
2200 org-export-with-section-numbers nil 481 org-export-with-section-numbers nil
@@ -2206,7 +487,8 @@ browser defined in `browse-url-secondary-browser-function'."
2206 org-fontify-whole-heading-line t 487 org-fontify-whole-heading-line t
2207 org-hide-emphasis-markers t 488 org-hide-emphasis-markers t
2208 org-html-coding-system 'utf-8-unix 489 org-html-coding-system 'utf-8-unix
2209 org-image-actual-width '(300) 490 org-image-actual-width (list (* (window-font-width)
491 (- fill-column 8)))
2210 org-imenu-depth 3 492 org-imenu-depth 3
2211 org-list-demote-modify-bullet '(("-" . "+") 493 org-list-demote-modify-bullet '(("-" . "+")
2212 ("+" . "*") 494 ("+" . "*")
@@ -2224,116 +506,16 @@ browser defined in `browse-url-secondary-browser-function'."
2224 org-startup-truncated nil 506 org-startup-truncated nil
2225 org-startup-with-inline-images t 507 org-startup-with-inline-images t
2226 org-tags-column (- (- fill-column (length org-ellipsis)))) 508 org-tags-column (- (- fill-column (length org-ellipsis))))
2227 509 (:bind "RET" '+org-return-dwim
2228 (:bind "RET" #'acdw-org/return-dwim 510 "<S-return>" '+org-table-copy-down
2229 "<S-return>" #'acdw-org/org-table-copy-down 511 "C-c C-l" '+org-insert-link-dwim
2230 ;; "M-SPC M-SPC" #'insert-zero-width-space 512 "C-c C-n" '+org-next-heading-widen
2231 "C-c C-l" #'org-insert-link-dwim 513 "C-c C-p" '+org-previous-heading-widen)
2232 "C-c w" #'chd/do-the-thing 514 (:local-set unfill-fill-function 'org-fill-paragraph)
2233 "C-c C-n" #'acdw/org-next-heading-widen 515 (:local-hook before-save-hook '+org-before-save@prettify-buffer)
2234 "C-c C-p" #'acdw/org-previous-heading-widen 516 (advice-add 'org-delete-backward-char :override '+org-delete-backward-char)
2235 "C-x n t" #'org-narrow-to-task)
2236
2237 (:unbind "C-j" ; org-return-and-maybe-indent
2238 "M-j")
2239
2240 (:local-set unfill-fill-function #'org-fill-paragraph
2241 wc-count-words-function
2242 (lambda (start end) "Count words stupidly with a limit."
2243 (acdw-org/count-words-stupidly start
2244 end
2245 999)))
2246
2247 (with-eval-after-load 'org-export
2248 (:option (append org-export-filter-final-output-functions)
2249 #'org-export-remove-zero-width-spaces))
2250
2251 (:local-hook before-save-hook
2252 (defun org/before-save@prettify-buffer ()
2253 (save-mark-and-excursion
2254 (mark-whole-buffer)
2255 (org-fill-paragraph nil t))
2256 (acdw-org/fix-blank-lines t)
2257 (org-align-tags :all)))
2258
2259 (with-eval-after-load 'org 517 (with-eval-after-load 'org
2260 (org-clock-persistence-insinuate)) 518 (org-clock-persistence-insinuate)))
2261
2262 (with-eval-after-load 'consult
2263 (defun consult-clock-in (&optional match scope resolve)
2264 "Clock into an Org heading."
2265 (interactive (list nil nil current-prefix-arg))
2266 (require 'org-clock)
2267 (org-clock-load)
2268 (save-window-excursion
2269 (consult-org-heading
2270 match
2271 (or scope
2272 (thread-last org-clock-history
2273 (mapcar 'marker-buffer)
2274 (mapcar 'buffer-file-name)
2275 (delete-dups)
2276 (delq nil))
2277 (user-error "No recent clocked tasks")))
2278 (org-clock-in nil (when resolve
2279 (org-resolve-clocks)
2280 (org-read-date t t)))))
2281
2282 (consult-customize consult-clock-in
2283 :prompt "Clock in: "
2284 :preview-key (kbd "M-.")
2285 :group
2286 (lambda (cand transform)
2287 (if transform
2288 (substring
2289 cand
2290 (next-single-property-change
2291 0 'consult-org--buffer cand))
2292 (let ((m (car (get-text-property
2293 0 'consult-org--heading cand))))
2294 (if (member m org-clock-history)
2295 "*Recent*"
2296 (buffer-name (marker-buffer m))))))))
2297
2298 (:advise org-delete-backward-char :override #'acdw-org/delete-backward-char)
2299
2300 (el-patch-feature org)
2301 (with-eval-after-load 'org
2302 (el-patch-defun org-format-outline-path (path &optional
2303 width prefix separator)
2304 "Format the outline path PATH for display.
2305WIDTH is the maximum number of characters that is available.
2306PREFIX is a prefix to be included in the returned string,
2307such as the file name.
2308SEPARATOR is inserted between the different parts of the path,
2309the default is \"/\"."
2310 (setq width (or width 79))
2311 (setq path (delq nil path))
2312 (unless (> width 0)
2313 (user-error "Argument `width' must be positive"))
2314 (setq separator (or separator "/"))
2315 (let* ((org-odd-levels-only nil)
2316 (fpath (concat
2317 prefix (and prefix path separator)
2318 (mapconcat
2319 (lambda (s) (replace-regexp-in-string "[ \t]+\\'" "" s))
2320 (cl-loop for head in path
2321 for n from 0
2322 collect
2323 (el-patch-swap
2324 (org-add-props
2325 head nil 'face
2326 (nth (% n org-n-level-faces)
2327 org-level-faces))
2328 head))
2329 separator))))
2330 (when (> (length fpath) width)
2331 (if (< width 7)
2332 ;; It's unlikely that `width' will be this small, but don't
2333 ;; waste characters by adding ".." if it is.
2334 (setq fpath (substring fpath 0 width))
2335 (setf (substring fpath (- width 2)) "..")))
2336 fpath))))
2337 519
2338(setup (:straight org-appear) 520(setup (:straight org-appear)
2339 (:option org-appear-autoemphasis t 521 (:option org-appear-autoemphasis t
@@ -2344,24 +526,10 @@ the default is \"/\"."
2344 org-appear-delay 0) 526 org-appear-delay 0)
2345 (:hook-into org-mode)) 527 (:hook-into org-mode))
2346 528
2347(setup (:straight org-sticky-header)
2348 (:hook-into org-mode))
2349
2350(setup (:straight package-lint
2351 package-lint-flymake))
2352
2353(setup (:straight page-break-lines)
2354 (global-page-break-lines-mode +1))
2355
2356(setup (:straight paredit) 529(setup (:straight paredit)
2357 (:bind "DEL" #'paredit-backward-delete 530 (:bind "DEL" 'paredit-backward-delete
2358 "C-<backspace>" #'paredit-backward-kill-word 531 "C-<backspace>" 'paredit-backward-kill-word)
2359 "M-w" #'paredit-copy-as-kill
2360 "RET" #'paredit-newline)
2361 (:unbind "C-j" ; paredit-newline
2362 )
2363 (:hook-into emacs-lisp-mode lisp-interaction-mode 532 (:hook-into emacs-lisp-mode lisp-interaction-mode
2364 ielm-mode sly-repl-mode
2365 lisp-mode scheme-mode) 533 lisp-mode scheme-mode)
2366 (:also-load eldoc) 534 (:also-load eldoc)
2367 (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)) 535 (eldoc-add-command 'paredit-backward-delete 'paredit-close-round))
@@ -2373,163 +541,28 @@ the default is \"/\"."
2373 lisp-interaction-mode 541 lisp-interaction-mode
2374 scheme-mode)) 542 scheme-mode))
2375 543
2376(setup (:straight-when (pdf-tools
2377 :host github
2378 :repo "vedang/pdf-tools")
2379 (acdw/system :home))
2380 (:file-match (rx ".pdf" eos))
2381 (pdf-loader-install))
2382
2383(setup (:straight popper)
2384 (:option popper-reference-buffers
2385 `(,(rx "*Messages*")
2386 ,(rx "Output*" eol)
2387 ,(rx "*Async Shell Command*")
2388 help-mode helpful-mode
2389 compilation-mode)
2390 popper-mode-line nil
2391 popper-display-control t
2392 popper-display-function
2393 (defun popper/select-popup-smartly (buffer &optional _alist)
2394 (let* ((widep (> (frame-pixel-width) (frame-pixel-height)))
2395 (window (display-buffer-in-side-window
2396 buffer
2397 `((side . ,(if widep 'right 'bottom))
2398 (slot . 1)
2399 ,(if widep
2400 (cons 'window-width
2401 popper-window-height)
2402 (cons 'window-height
2403 popper-window-height))))))
2404 (select-window window)))
2405 popper-window-height
2406 (defun popper/figure-window-height (window)
2407 (let* ((widep (> (frame-pixel-width) (frame-pixel-height)))
2408 (fit-window-to-buffer-horizontally widep))
2409 (fit-window-to-buffer
2410 window
2411 (floor (frame-pixel-height) 2)
2412 (floor (frame-pixel-height) 4)
2413 fill-column
2414 fill-column))))
2415 (:global "M-`" #'popper-toggle-latest
2416 "C-`" #'popper-cycle)
2417 (popper-mode +1)
2418 (when (fboundp 'popper-echo-mode)
2419 (popper-echo-mode +1)))
2420
2421(setup (:straight-when (powershell
2422 :host github
2423 :repo "jschaf/powershell.el")
2424 (acdw/system :work)))
2425
2426(setup (:straight (shell-command+ 544(setup (:straight (shell-command+
2427 :host nil 545 :host nil
2428 :repo "https://git.sr.ht/~pkal/shell-command-plus")) 546 :repo "https://git.sr.ht/~pkal/shell-command-plus"))
2429 (:option shell-command-prompt "$ ") 547 (:option shell-command-prompt "$ ")
2430 (:with-feature dired 548 (:bind-into dired
2431 (:bind "M-!" shell-command+)) 549 "M-!" 'shell-command+)
2432 (:global "M-!" shell-command+)) 550 (:global "M-!" 'shell-command+))
2433
2434(setup (:straight sicp))
2435 551
2436(setup (:straight simple-modeline 552(setup (:straight (sophomore
2437 minions)
2438 (:also-load acdw-modeline)
2439 (:option simple-modeline-segments
2440 ;; Yeah this is laid out like poo. It's so I can easily change
2441 ;; things around if need be.
2442 '((;; left
2443 acdw-modeline/winum
2444 acdw-modeline/modified
2445 acdw-modeline/buffer-name
2446 acdw-modeline/vc-branch
2447 acdw-modeline/wc
2448 acdw-modeline/nyan-cat
2449 acdw-modeline/position
2450 ) (;; right
2451 acdw-modeline/track
2452 simple-modeline-segment-misc-info
2453 acdw-modeline/text-scale
2454 simple-modeline-segment-process
2455 acdw-modeline/god-mode-indicator
2456 acdw-modeline/minions
2457 acdw-modeline/reading-mode
2458 acdw-modeline/narrowed
2459 acdw-modeline/major-mode
2460 )))
2461
2462 (:option tab-bar-mode t
2463 tab-bar-show 1)
2464
2465 ;; I've put in a pull request to add the (- 0 right-margin) bit here.
2466 (el-patch-feature simple-modeline)
2467 (with-eval-after-load 'simple-modeline
2468 (el-patch-defun simple-modeline--format (left-segments right-segments)
2469 "Return a string of `window-width' length containing LEFT-SEGMENTS and RIGHT-SEGMENTS, aligned respectively."
2470 (let* ((left (simple-modeline--format-segments left-segments))
2471 (right (simple-modeline--format-segments right-segments))
2472 (reserve (length right)))
2473 (concat
2474 left
2475 (propertize " "
2476 'display (el-patch-swap
2477 `((space :align-to (- right ,reserve)))
2478 `((space :align-to
2479 (- right
2480 (- 1 right-fringe right-margin)
2481 ,reserve))))
2482 'face '(:inherit simple-modeline-space))
2483 right))))
2484
2485 (simple-modeline-mode +1))
2486
2487(setup (:straight-when sly
2488 (progn
2489 (defvar acdw/lisps
2490 (let (lisps)
2491 (dolist (lisp '("sbcl" ; TODO: add more lisps
2492 "clisp"))
2493 (when-let (binary (executable-find lisp))
2494 (push binary lisps)))
2495 (nreverse lisps)))
2496 acdw/lisps))
2497 (:also-load sly-autoloads)
2498 (:straight clhs)
2499
2500 (:option inferior-lisp-program acdw/lisp-bin
2501 sly-kill-without-query-p t)
2502
2503 (:with-feature sly-mrepl
2504 (defun sly-mrepl-return-at-end ()
2505 (interactive)
2506 (if (<= (point-max) (point))
2507 (sly-mrepl-return)
2508 (if (bound-and-true-p paredit-mode)
2509 (paredit-newline)
2510 (electric-newline-and-maybe-indent))))
2511
2512 (dolist (key '("RET" "<return>"))
2513 (:bind key #'sly-mrepl-return-at-end))
2514
2515 (:bind "C-c C-c" #'sly-mrepl-return)))
2516
2517(setup (:straight (spongebob-case
2518 :host github 553 :host github
2519 :repo "duckwork/spongebob-case.el")) 554 :repo "duckwork/sophomore.el"))
2520 (:global "C-c c s" #'spongebob-case-dwim)) 555 (:option disabled-command-function 'sophomore-dispatch
556 sophomore-dispatch-alist '((fatfinger . sophomore-fat-finger)))
557 (put 'save-buffers-kill-terminal 'disabled 'fatfinger))
2521 558
2522(setup (:straight ssh-config-mode) 559(setup (:straight ssh-config-mode)
2523 (:file-match (rx "/.ssh/config" eos) 560 (:file-match (rx "/.ssh/config" eos)
2524 (rx "/ssh" (? "d") "_config" eos)) 561 (rx "/ssh" (? "d") "_config" eos))
2525
2526 (:with-mode ssh-known-hosts-mode 562 (:with-mode ssh-known-hosts-mode
2527 (:file-match (rx "/knownhosts" eos))) 563 (:file-match (rx "/knownhosts" eos)))
2528
2529 (:with-mode ssh-authorized-keys-mode 564 (:with-mode ssh-authorized-keys-mode
2530 (:file-match (rx "/authorized_keys" (? "2") eos))) 565 (:file-match (rx "/authorized_keys" (? "2") eos))))
2531
2532 (:hook #'turn-on-font-lock))
2533 566
2534(setup (:straight super-save) 567(setup (:straight super-save)
2535 (:option auto-save-default nil 568 (:option auto-save-default nil
@@ -2540,72 +573,9 @@ the default is \"/\"."
2540 (auto-save-visited-mode -1) 573 (auto-save-visited-mode -1)
2541 (super-save-mode +1)) 574 (super-save-mode +1))
2542 575
2543(setup (:straight-when system-packages
2544 (seq-some #'executable-find
2545 ;; I can't use `system-packages-supported-package-managers'
2546 ;; because, well, the package isn't installed yet. So
2547 ;; ... update this list if any package managers are added.
2548 '("guix" "nix"
2549 "brew" "macports"
2550 "pacman" "emerge"
2551 "zypper" "dnf"
2552 "apt" "aptitude"
2553 "xbps"))))
2554
2555(setup (:straight-when systemd
2556 (executable-find "systemd")))
2557
2558(setup (:straight (topsy
2559 :host github
2560 :repo "alphapapa/topsy.el"))
2561 (:hook-into prog-mode)
2562 (:when-loaded
2563 (:option topsy-header-line-format
2564 `(:eval
2565 (list
2566 (propertize " "
2567 'display
2568 `((space
2569 :align-to
2570 ,(unless
2571 (bound-and-true-p visual-fill-column-mode)
2572 0))))
2573 (funcall topsy-fn))))))
2574
2575(setup (:straight trashed) 576(setup (:straight trashed)
2576 (:option trashed-action-confirmer #'y-or-n-p)) 577 (:option trashed-action-confirmer #'y-or-n-p))
2577 578
2578(setup (:straight typo)
2579
2580 ;; Enable C-c 8 map in all buffers
2581 (typo-global-mode +1)
2582
2583 (add-hook 'text-mode-hook
2584 (defun text-mode@typo-unless ()
2585 "Start `typo-mode' UNLESS the buffer matches a predicate."
2586 ;; I implement this instead of using
2587 ;; `typo-disable-electricity-functions' because the latter checks
2588 ;; on every pertinent keypress. I know I want /no/ typo-ing in
2589 ;; these certain buffers, so I won't even turn on the mode.
2590 (unless (or ; predicates here
2591 (string-match-p "COMMIT_EDITMSG"
2592 (or (buffer-name) "")))
2593 (typo-mode +1))))
2594
2595 ;; jlf & cvandusen on #emacs make a great point: ’ (RIGHT SINGLE QUOTATION
2596 ;; MARK) is /not/ an apostrophe. Making it curly is a typographical
2597 ;; consideration, not an input consideration. (I suppose you could make
2598 ;; the argument that all of these are typographical considerations, but
2599 ;; .. bleh.)
2600 (:bind "'" (define-typo-cycle typo-cycle-apostrophe
2601 "Cycle through apostrophe-like graphemes.
2602If used with a numeric prefix argument N, N apostrophes will be inserted."
2603 ("'" "′" "″" "’"))
2604 "`" (define-typo-cycle typo-cycle-backtick
2605 "Cycle through backtick and left single quotation mark.
2606If used with a numeric prefix argument N, N backticks will be inserted."
2607 ("`" "‘"))))
2608
2609(setup (:straight undo-fu) 579(setup (:straight undo-fu)
2610 (:global "C-/" #'undo-fu-only-undo 580 (:global "C-/" #'undo-fu-only-undo
2611 "C-?" #'undo-fu-only-redo)) 581 "C-?" #'undo-fu-only-redo))
@@ -2613,146 +583,40 @@ If used with a numeric prefix argument N, N backticks will be inserted."
2613(setup (:straight undo-fu-session) 583(setup (:straight undo-fu-session)
2614 (:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" 584 (:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'"
2615 "/git-rebase-todo\\'") 585 "/git-rebase-todo\\'")
2616 undo-fu-session-directory (acdw/dir "undo/" t) 586 undo-fu-session-directory (.etc "undo/" t)
2617 undo-fu-session-compression (acdw/system :home)) 587 undo-fu-session-compression (eq system-type 'gnu/linux))
2618
2619 (global-undo-fu-session-mode +1)) 588 (global-undo-fu-session-mode +1))
2620 589
2621(setup (:straight (unfill :host github :repo "purcell/unfill" 590(setup (:straight (unfill :host github :repo "purcell/unfill"
2622 :fork (:host github :repo "duckwork/unfill"))) 591 :fork (:host github :repo "duckwork/unfill")))
2623 (:global "M-q" #'unfill-toggle)) 592 (:global "M-q" #'unfill-toggle))
2624 593
2625(setup (:straight (unfocused
2626 :host github
2627 :repo "duckwork/unfocused"))
2628 (unfocused-mode +1)
2629
2630 (:with-hook unfocused-hook
2631 (:hook #'garbage-collect)))
2632
2633(setup (:straight (vertico 594(setup (:straight (vertico
2634 :host github 595 :host github
2635 :repo "minad/vertico" 596 :repo "minad/vertico"
2636 :files ("*" "extensions/*" 597 :files ("*" "extensions/*"
2637 (:exclude ".git")))) 598 (:exclude ".git"))))
2638
2639 (:option resize-mini-windows 'grow-only 599 (:option resize-mini-windows 'grow-only
2640 vertico-count-format nil 600 vertico-count-format nil
2641 vertico-cycle t) 601 vertico-cycle t)
2642
2643 (when (boundp 'native-comp-deferred-compilation-deny-list) 602 (when (boundp 'native-comp-deferred-compilation-deny-list)
2644 (add-to-list 'native-comp-deferred-compilation-deny-list "vertico")) 603 (add-to-list 'native-comp-deferred-compilation-deny-list "vertico"))
2645
2646 (vertico-mode +1) 604 (vertico-mode +1)
2647 605 ;; Extensions
2648 ;; Extensions! 606 (:also-load vertico-directory)
2649 (:also-load vertico-mouse
2650 vertico-directory)
2651 (vertico-mouse-mode +1)
2652 (:with-map vertico-map 607 (:with-map vertico-map
2653 (:bind "RET" #'vertico-directory-enter 608 (:bind "RET" 'vertico-directory-enter
2654 "DEL" #'vertico-directory-delete-char 609 "DEL" 'vertico-directory-delete-char
2655 "M-DEL" #'vertico-directory-delete-word)) 610 "M-DEL" 'vertico-directory-delete-word))
2656 (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy)) 611 (add-hook 'rfn-eshadow-update-overlay-hook 'vertico-directory-tidy))
2657 612
2658(setup (:straight visual-fill-column) 613(setup (:straight visual-fill-column)
2659 (:option visual-fill-column-width (1+ fill-column) 614 (:option visual-fill-column-center-text t)
2660 visual-fill-column-center-text t
2661 (append reading-modes) '(visual-fill-column-mode . +1)
2662 (append reading-modes) '(visual-line-mode . +1)
2663 (append reading-vars) '(fill-column . 0))
2664 (:hook-into org-mode) 615 (:hook-into org-mode)
2665 (:hook (defun visual-fill-column@setup () 616 (with-eval-after-load 'visual-fill-column
2666 (if visual-fill-column-mode 617 (advice-add 'text-scale-adjust :after 'visual-fill-column-adjust)))
2667 (setq-local indicate-empty-lines nil
2668 indicate-buffer-boundaries nil)
2669 (acdw/setup-fringes))))
2670 (:advise text-scale-adjust :after #'visual-fill-column-adjust)
2671 ;; Fix bindings
2672 (when (bound-and-true-p mouse-wheel-mode)
2673 (with-eval-after-load 'visual-fill-column
2674 (dolist (margin '(right-margin left-margin))
2675 (dolist (event '(wheel-down wheel-up))
2676 (define-key visual-fill-column-mode-map
2677 (vector margin event)
2678 #'mwheel-scroll))))))
2679
2680(setup (:straight visual-regexp)
2681 (:global "M-%" #'vr/query-replace))
2682
2683(setup (:straight-when vterm
2684 (acdw/system :home))
2685 (:straight (eshell-vterm
2686 :host github
2687 :repo "iostapyshyn/eshell-vterm"))
2688 (eshell-vterm-mode +1)
2689 (defalias 'eshell/v 'eshell-exec-visual))
2690
2691(setup (:straight wc-mode)
2692 (:option wc-modeline-format "[%tww]"
2693 wc-idle-wait 2)
2694 (:hook-into text-mode)
2695 (:unbind "C-c C-w a"
2696 "C-c C-w c"
2697 "C-c C-w l"
2698 "C-c C-w w"
2699 "C-c C-w"))
2700
2701(setup (:straight web-mode)
2702 (:option css-level-offset 2
2703 js-indent-level 2
2704 sgml-indent-offset 2)
2705
2706 (:file-match (rx ".htm" (? "l") eos)
2707 (rx "." (? "tpl.") "php" eos)
2708 (rx "." (| "asp" "gsp" "jsp") eos)
2709 (rx "." (| "ascx" "aspx") eos)
2710 (rx ".erb" eos)
2711 (rx ".mustache" eos)))
2712
2713(setup (:straight wgrep)
2714 (wgrep-setup))
2715
2716;; (setup (:straight which-key)
2717;; (:option which-key-show-early-on-C-h t
2718;; which-key-idle-delay 1
2719;; which-key-idle-secondary-delay 0.5
2720;; which-key-sort-order 'which-key-prefix-then-key-order)
2721
2722;; (:global "C-h m" #'which-key-show-major-mode)
2723
2724;; (which-key-setup-side-window-right-bottom)
2725;; (which-key-mode +1))
2726 618
2727(setup (:straight whitespace-cleanup-mode) 619(setup (:straight whitespace-cleanup-mode)
620 (:option whitespace-cleanup-mode-preserve-point t)
621 (remove-hook 'before-save-hook 'whitespace-cleanup)
2728 (global-whitespace-cleanup-mode +1)) 622 (global-whitespace-cleanup-mode +1))
2729
2730(setup (:straight winum)
2731 (:option winum-scope 'frame-local
2732 winum-auto-setup-mode-line nil
2733 winum-ignored-buffers '(" *which-key*")
2734 winum-format " %s")
2735
2736 (winum-mode +1))
2737
2738(setup (:straight xr))
2739
2740(setup (:straight-when ytdious
2741 (executable-find "mpv"))
2742 (:also-load acdw-ytel) ; so named because I used ytel first
2743 (:option ytdious-invidious-api-url "https://invidious.snopyta.org")
2744 (:hook #'hl-line-mode)
2745 (:global "C-c y" #'ytdious)
2746 (:bind "v" #'acdw/ytdious-watch
2747 "w" #'acdw/ytdious-copy-link
2748 "q" #'acdw/ytdious-quit))
2749
2750(setup (:straight zzz-to-char)
2751
2752 (:global "M-z"
2753 (defun acdw/zzz-up-to-char (prefix)
2754 "Call `zzz-up-to-char' or `zzz-to-char', PREFIX-depending."
2755 (interactive "P")
2756 (if prefix
2757 (call-interactively #'zzz-up-to-char)
2758 (call-interactively #'zzz-to-char)))))