summary refs log tree commit diff stats
path: root/init.el
diff options
context:
space:
mode:
authorCase Duckworth2022-10-17 21:41:28 -0500
committerCase Duckworth2022-10-17 21:41:28 -0500
commitaab5bfd074e57d06a79e39d7c7c4760e1f385a06 (patch)
tree7b111190a44458a970355f7a327cc5278c850293 /init.el
parentasoi (diff)
downloademacs-aab5bfd074e57d06a79e39d7c7c4760e1f385a06.tar.gz
emacs-aab5bfd074e57d06a79e39d7c7c4760e1f385a06.zip
Bankruptcy 9
Diffstat (limited to 'init.el')
-rw-r--r--init.el2900
1 files changed, 166 insertions, 2734 deletions
diff --git a/init.el b/init.el index bed69ee..d7a55d4 100644 --- a/init.el +++ b/init.el
@@ -1,2744 +1,176 @@
1;;; init.el --- Emacs initiation file -*- lexical-binding: t -*- 1;;; emacs init --- an init for emacs -*- lexical-binding: t; -*-
2 2;; by C. Duckworth <acdw@acdw.net>
3;; Author: Case Duckworth <acdw@acdw.net> 3;; URL: https://git.acdw.net/emacs
4;; Created: Sometime during Covid-19, 2020 4;; Bankruptcy: 9
5;; Keywords: configuration 5;;
6;; URL: https://tildegit.org/acdw/emacs
7;; Bankruptcy: 8
8
9;;; License:
10
11;; Everyone is permitted to do whatever they like with this software 6;; Everyone is permitted to do whatever they like with this software
12;; without limitation. This software comes without any warranty 7;; without limitation. This software comes without any warranty
13;; whatsoever, but with two pieces of advice: 8;; whatsoever, but with two pieces of advice:
14;; - Be kind to yourself. 9;; - Be kind to yourself.
15;; - Make good choices. 10;; - Make good choices.
16 11
17;;; Commentary 12(progn
18 13 ;; Settings
19;; My init.el. There are many like it, but this one is mine. 14 (setq truncate-string-ellipsis "…"
20 15 ring-bell-function #'ignore
21;; Ideas: 16 read-file-name-completion-ignore-case t)
22;; [[https://emacs.stackexchange.com/questions/17278/truncate-only-certain-lines-and-use-continuation-lines-elsewhere][Truncate org-mode headings]] 17 ;; Keys
23;; [[https://emacs.stackexchange.com/questions/7432/make-visual-line-mode-more-compatible-with-org-mode][another link that might be useful for truncating]] 18 (define-keys (current-global-map)
24 19 "C-x C-k" #'kill-current-buffer
25;;; Code: 20 "C-/" #'undo-only
26 21 "C-?" #'undo-redo
27(let ((early-features `((early-init . ,(locate-user-emacs-file "early-init")) 22 "M-j" nil
28 acdw private +key))) 23 "<Scroll_Lock>" nil)
29 (dolist (feature early-features)
30 (require (or (car-safe feature) feature) (cdr-safe feature) :noerror)))
31
32(setup (:require +casing)
33 (:global "M-u" #'universal-argument)
34 (+casing-mode +1))
35
36(setup (:require +emacs)
37 ;; +emacs.el contains super-basic defaults that are basically necessary for
38 ;; good functioning. In this block, I add extra things or more "experimental"
39 ;; ones that might not belong in a separate file.
40 (:also-load +lisp)
41 (:option truncate-string-ellipsis "…"
42 ring-bell-function 'ignore
43 read-file-name-completion-ignore-case t)
44 ;; Bindings
45 (:global "C-x C-k" #'kill-current-buffer
46 "C-M--" #'+goto-matching-paren
47 "C-c v" #'visible-mode
48 "C-M-;" #'+lisp-comment-or-uncomment-sexp
49 "C-x C-o" #'+switch-to-last-buffer
50 "C-x o" #'+switch-to-last-buffer
51 "C-x C-l" #'+open-paragraph ; original: downcase-region
52 "C-w" #'+kill-word-backward-or-region
53 "C-<backspace>" #'+backward-kill-word
54 "C-x TAB" #'+indent-rigidly
55 "<f7>" #'flyspell-mode
56 "C-\\" nil ; original: toggle-input-method
57 "C-/" #'undo-only
58 "C-?" #'undo-redo)
59 ;; Disable bindings
60 (:global "M-j" nil
61 "<Scroll_Lock>" nil)
62 (:+leader "C-d e" #'toggle-debug-on-error
63 "C-d q" #'toggle-debug-on-quit)
64 ;; C-h deletes backward - see https://idiomdrottning.org/bad-emacs-defaults
65 (global-set-key (kbd "C-h") 'delete-backward-char)
66 (keyboard-translate ?\C-h ?\C-?)
67 ;; Faces
68 (dolist (face '(line-number
69 line-number-major-tick
70 line-number-minor-tick
71 line-number-current-line))
72 (:face face '((t (:inherit fixed-pitch)))))
73 ;; Hooks
74 (add-hook 'prog-mode-hook #'turn-on-auto-fill)
75 (add-hook 'prog-mode-hook #'font-lock-todo-insinuate)
76 (add-hook 'text-mode-hook #'turn-on-auto-fill) ; XXX: do I want this ??
77 (add-hook 'special-mode-hook #'turn-off-auto-fill)
78 ;; Advice 24 ;; Advice
79 (advice-add #'completing-read-multiple :filter-args #'+crm-indicator)
80 ;; https://old.reddit.com/r/emacs/comments/rlli0u/whats_your_favorite_defadvice/hph14un/
81 (define-advice keyboard-escape-quit (:around (fn &rest r)) 25 (define-advice keyboard-escape-quit (:around (fn &rest r))
82 "Don't close splits on `keyboard-escape-quit'." 26 "Don't close quits on `keyboard-escape-quit'."
83 (let ((buffer-quit-function #'ignore)) 27 (let ((buffer-quit-function #'ignore))
84 (apply fn r)))) 28 (apply fn r)))
85 29 ;; Themes
86(setup (:require +init) 30 (load-theme 'modus-operandi))
87 (:local-hook user-save-before-save-hook #'+init-sort) 31
88 (+with-ensure-after-init 32(yoke auth-source nil
89 (:hook #'+init-add-setup-to-imenu))) 33 (setq auth-sources `(default "secrets:passwords"))
90 34 (setq-local-hook authinfo-mode-hook
91(setup (:require +window)) 35 truncate-lines t))
92 36
93(setup (:require auth-source) 37(yoke consult "https://github.com/minad/consult"
94 (:option auth-sources (list 'default 38 (require 'consult)
95 "secrets:passwords" 39 (setq register-preview-delay 0
96 (private/ "authinfo"))) 40 register-preview-function #'consult-register-format
97 (:with-mode authinfo-mode 41 xref-show-xrefs-function #'consult-xref
98 (:local-set truncate-lines t))) 42 tab-always-indent 'complete
99 43 completion-in-region-function #'consult-completion-in-region
100(setup (:require autoinsert) 44 consult-narrow-key "<"
101 ;; (auto-insert-mode +1) 45 consult--regexp-compiler #'consult--orderless-regexp-compiler)
102 )
103
104(setup (:require cus-edit)
105 ;; I don't use Custom to actually /make/ any customizations, but it's handy to
106 ;; (A) see what options are available and (B) persist some changes across
107 ;; restarts, for example, `safe-local-variables'.
108 (:require +cus-edit)
109 (:option custom-file (private/ "custom.el")
110 custom-magic-show nil
111 custom-magic-show-button t
112 custom-raised-buttons nil
113 custom-unlispify-tag-names nil
114 custom-variable-default-form 'lisp)
115 (dolist (var '(safe-local-variable-values
116 warning-suppress-types))
117 (add-to-list '+custom-variable-allowlist var))
118 ;; Load customizations now, and after init (to capture other possible
119 ;; variables I want to load) XXX: this is dumb
120 (+with-ensure-after-init
121 (+custom-load-ignoring-most-customizations))
122 (advice-add #'custom-buffer-create-internal :after #'+cus-edit-expand-widgets)
123 (:with-mode Custom-mode
124 (:local-set imenu-generic-expression +cus-edit-imenu-generic-expression)))
125
126(setup (:require find-script))
127
128(setup (:require goto-addr)
129 (if (fboundp #'global-goto-address-mode)
130 (global-goto-address-mode)
131 (add-hook 'after-change-major-mode-hook #'goto-address-mode)))
132
133(setup (:require pulse)
134 (:also-load +pulse)
135 (:option pulse-flag nil
136 pulse-delay 0.5
137 pulse-iterations 1)
138 (dolist (command '(+ace-window-or-switch-buffer
139 pop-mark pop-global-mark
140 Info-history-back Info-history-forward
141 ))
142 (add-to-list '+pulse-location-commands command))
143 (+ensure-after-init #'+pulse-location-mode))
144
145(setup (:require reading)
146 ;;(:hook-into view-mode) ; XXX doesn't go back
147 )
148
149(setup (:require user-save)
150 (add-hook 'user-save-before-save-hook #'+clean-empty-lines)
151 (add-hook 'user-save-before-save-hook (defun user-save@save-some-buffers ()
152 (save-some-buffers t t)))
153 (user-save-global-mode +1))
154
155(setup (:require winner)
156 (winner-mode +1))
157
158(setup +key
159 (+ensure-after-init #'+key-global-mode))
160
161(setup _work
162 (with-eval-after-load 'bbdb
163 (require '_work)))
164
165(setup abbrev
166 (:option abbrev-file-name (sync/ "abbrev.el")
167 save-abbrevs 'silent)
168 (with-eval-after-load 'user-save
169 (:with-mode edit-abbrevs-mode
170 (:hook #'user-save-mode-disable)))
171 (:hook-into text-mode
172 circe-chat-mode))
173
174(setup autorevert
175 (:option global-auto-revert-non-file-buffers t
176 auto-revert-verbose nil)
177 (global-auto-revert-mode +1))
178
179(setup awk-mode
180 (:apheleia gawk '("gawk" "-f-" "-o-")))
181
182(setup bookmark
183 (:option bookmark-save-flag 1
184 bookmark-watch-bookmark-file 'silent
185 bookmark-set-fringe-mark nil))
186
187(setup browse-url
188 (:require +browse-url)
189 (:option
190 browse-url-browser-function 'browse-url-default-browser
191 +browse-url-browser-function #'eww-browse-url
192 browse-url-generic-program (seq-some #'executable-find
193 '("firefox"
194 "chromium"
195 "chrome"))
196 browse-url-chrome-program (seq-some #'executable-find
197 '("chromium"
198 "chrome"
199 "google-chrome-stable"))
200 browse-url-generic-args (seq-some (lambda (e)
201 (when (equal (executable-find (car e))
202 browse-url-generic-program)
203 (cdr e)))
204 '(("firefox" "--new-tab")))
205 browse-url-secondary-browser-function (if (executable-find "firefox")
206 #'browse-url-firefox
207 #'browse-url-default-browser)
208 browse-url-new-window-flag nil
209 browse-url-firefox-arguments '("--new-tab")
210 browse-url-firefox-new-window-is-tab t)
211 (defvar +invidious-host
212 ;; TODO: Add variables for other transformations and what-not.
213 ;; ... or enable trying multiple servers
214 ;; "yewtu.be"
215 "youtube.com"
216 "Host for invidious instance.")
217 ;; Set up external browsing URLs.
218 (add-to-list '+custom-variable-allowlist
219 '+browse-url-secondary-browser-regexps)
220 (dolist (domain '("github.com" "gitlab.com" "google.com"
221 "imgur.com" "twitch.tv"
222 "pixelfed" "instagram.com" "bibliogram.art"
223 "reddit.com" "teddit.net"
224 "twitter.com" "nitter.net" "t.co"
225 "streamable.com" "spotify.com"
226 "hetzner.cloud"
227 "melpa.org"))
228 (add-to-list '+browse-url-secondary-browser-regexps
229 (replace-regexp-in-string "\\." "\\\\." domain)))
230 ;; Set up URL handlers.
231 (:option browse-url-handlers
232 (list
233 (cons (rx bos (or "gemini:" "gopher:")) #'elpher-browse-url-elpher)
234 (cons (rx ; images
235 "." (or "jpeg" "jpg" "png" "bmp" "webp") eos)
236 (lambda (&rest args)
237 (apply
238 (cond ((executable-find "mpv") #'+browse-image-with-mpv)
239 (t #'eww-browse-url))
240 args)))
241 (cons (rx (or ;; videos
242 "youtube.com" "youtu.be" "invidious" "yewtu.be"
243 (seq "." (or "mp4" "gif" "mov" "MOV" "webm") eos)
244 ;; music
245 "soundcloud.com" "bandcamp.com"
246 (seq "." (or "ogg" "mp3" "opus" "m4a") eos)))
247 (lambda (&rest args)
248 (apply (if (executable-find "mpv")
249 #'+browse-url-with-mpv
250 browse-url-secondary-browser-function)
251 args)))
252 (cons (+browse-url-secondary-browser-regexps-combine) ; non-text websites
253 (lambda (&rest args)
254 (apply browse-url-secondary-browser-function args)))
255 (cons "xkcd\\.com"
256 (lambda (&rest args)
257 (apply (if (fboundp #'xkcd-get)
258 (progn (require '+xkcd)
259 #'+xkcd-get-from-url)
260 +browse-url-browser-function)
261 args)))
262 (cons "." ; everything else
263 (lambda (&rest args)
264 (apply +browse-url-browser-function args)))))
265 (with-eval-after-load 'chd
266 (add-to-list 'browse-url-handlers
267 (cons chd/url-regexps #'browse-url-chrome)))
268 ;; Transform URLs before passing to `browse-url'
269 (:option +browse-url-transformations `((,(rx (or "youtube.com"
270 "youtu.be"))
271 . ,+invidious-host)
272 ("twitter\\.com" . "nitter.net")
273 ("instagram\\.com" . "bibilogram.art")
274 (,(rx (or "reddit.com"
275 "old.reddit.com"))
276 . "teddit.net")
277 ("medium\\.com" . "scribe.rip")
278 ("www\\.npr\\.org" . "text.npr.org")
279 ;;TODO: Various paste sites
280 ))
281 (+browse-url-transform-url-global-mode +1))
282
283(setup c-mode
284 (:with-hook c-mode-common-hook
285 (:hook #'indent-tabs-mode)))
286
287(setup calendar
288 (require '_location)
289 (:option diary-file (private/ "diary")))
290
291(setup compile
292 (:require +compile)
293 (:+key "<f5>" #'+compile-dispatch)
294 (:option compilation-always-kill t
295 compilation-ask-about-save nil
296 compilation-scroll-output t))
297
298(setup dired
299 (:require dired-x +dired)
300 (:straight dired+)
301 (:option dired-recursive-copies 'always
302 dired-recursive-deletes 'always
303 dired-create-destination-dirs 'always
304 dired-do-revert-buffer t
305 dired-hide-details-hide-symlink-targets nil
306 dired-isearch-filenames 'dwim
307 delete-by-moving-to-trash t
308 dired-auto-revert-buffer t
309 dired-listing-switches "-AlF"
310 ls-lisp-dirs-first t
311 dired-ls-F-marks-symlinks t
312 dired-clean-confirm-killing-deleted-buffers nil
313 dired-no-confirm '(byte-compile
314 load chgrp chmod chown
315 copy move hardlink symlink
316 shell touch)
317 dired-dwim-target t)
318 (:local-set truncate-lines t)
319 (:bind "<backspace>" #'dired-up-directory
320 "j" #'+dired-goto-file
321 "C-j" #'dired-up-directory)
322 (:hook #'dired-hide-details-mode
323 #'hl-line-mode
324 #'lin-mode
325 #'+dired-dim-git-ignores)
326 (+with-ensure-after-init ; Necessary because jabber loads later
327 (:+key "C-x C-j" #'dired-jump))
328 (dolist (refresh-after-func '(dired-do-flagged-delete))
329 (advice-add refresh-after-func :after #'revert-buffer))
330 (with-eval-after-load 'frowny
331 (add-to-list 'frowny-inhibit-modes #'dired-mode)))
332
333(setup eldoc
334 (:hook-into elisp-mode
335 lisp-interaction-mode))
336
337(setup elisp-mode
338 (:also-load +elisp)
339 (:option eval-expression-print-length nil
340 eval-expression-print-level nil)
341 (:with-mode emacs-lisp-mode
342 (:hook #'checkdoc-minor-mode))
343 (:bind-into (emacs-lisp-mode-map lisp-interaction-mode-map)
344 "C-c C-c" #'eval-defun
345 "C-c C-k" #'+elisp-eval-region-or-buffer
346 "C-c C-z" #'ielm)
347 (advice-add #'eval-region :around #'+eval-region@pulse))
348
349(setup eshell
350 (:also-load em-smart
351 em-tramp)
352 (:require +eshell
353 esh-module)
354 (+define-dir eshell/ (locate-user-emacs-file "eshell")
355 "Where to place Eshell-specific files.")
356 (:option eshell-aliases-file (eshell/ "aliases")
357 ;; What are these for???
358 eshell-rc-script (eshell/ "profile")
359 eshell-login-script (eshell/ "login")
360 eshell-destroy-buffer-when-process-dies t
361 eshell-directory-name eshell/
362 eshell-error-if-no-glob t
363 eshell-hist-ignore-dups t
364 eshell-kill-on-exit nil
365 eshell-prefer-lisp-functions t
366 eshell-prefer-lisp-variables t
367 eshell-review-quick-commands nil
368 eshell-save-history-on-exit t
369 eshell-scroll-to-bottom-on-input 'all
370 eshell-smart-space-goes-to-end t
371 eshell-where-to-jump 'begin
372 eshell-banner-message ""
373 eshell-prompt-regexp (rx bol (* (not (any ?# ?$ ?\n)))
374 " " (any ?# ?$)
375 (* " ")))
376 (:+leader "s" #'+eshell-here
377 "C-s" #'+eshell-here)
378 (:global "C-c C-z" #'+eshell-here)
379 (add-to-list 'eshell-modules-list 'eshell-tramp)
380 (with-eval-after-load 'mwim
381 (setf (alist-get 'eshell-mode mwim-beginning-of-line-function)
382 #'eshell-bol))
383 (:hook #'eshell-smart-initialize)
384 (+eshell-eval-after-load
385 ;; Local modes
386 (dolist (mode '((hungry-delete-mode . -1)))
387 (funcall (car mode) (cdr mode)))
388 ;; Set local settings
389 (dolist (setting `((outline-regexp . ,eshell-prompt-regexp)
390 (page-delimiter . ,eshell-prompt-regexp)
391 (imenu-generic-expression "Prompt"
392 ,(concat eshell-prompt-regexp
393 "\\(.*\\)")
394 1)
395 (truncate-lines . t)
396 (scroll-margin . 0)))
397 (set (make-local-variable (car setting)) (cdr setting)))
398 ;; Bind keys
399 (dolist (binding '(("C-d" . +eshell-quit-or-delete-char)))
400 (define-key eshell-mode-map
401 (kbd (car binding)) (cdr binding)))
402 ;; Environment variables
403 (dolist (environment '(("PAGER" . "cat")))
404 (setenv (car environment) (cdr environment)))))
405
406(setup eww
407 (:also-load +eww)
408 (:option eww-search-prefix "https://duckduckgo.com/html?q="
409 url-privacy-level '(email agent cookies lastloc)
410 eww-use-browse-url (rx bos (or "mailto:"
411 "gemini:"
412 "gopher:")))
413 (add-hook 'eww-after-render-hook #'reading-mode)
414 (:hook #'+eww-bookmark-setup
415 #'+eww-track-readable-mode)
416 (:bind "b" #'bookmark-set
417 "B" #'bookmark-jump
418 "M-n" nil
419 "M-p" nil))
420
421(setup hideshow
422 (:also-load +hideshow)
423 (:with-mode hs-minor-mode
424 (:hook-into prog-mode)
425 (:bind "C-<tab>" #'+hs-cycle
426 "C-S-<tab>" #'+hs-global-cycle
427 ;; but y tho
428 "C-S-<iso-lefttab>" #'+hs-global-cycle)))
429
430(setup ibuffer
431 (:also-load ibuf-ext)
432 (:option ibuffer-expert t
433 ibuffer-show-empty-filter-groups nil
434 ibuffer-saved-filter-groups
435 '(("default"
436 ("Org" (mode . org-mode))
437 ("emacs" (or (name . "^\\*scratch\\*$")
438 (name . "^\\*Messages\\*$")
439 (name . "^\\*Warnings\\*$")
440 (name . "^\\*straight-process\\*$")
441 (name . "^\\*Calendar\\*$")))
442 ("customize" (mode . Custom-mode))
443 ("emacs-config" (or (filename . ".emacs.d")
444 (mode . +init-mode)))
445 ("git" (or (name . "^\*magit")
446 (name . "^\magit")))
447 ("help" (or (mode . help-mode)
448 (mode . Info-mode)
449 (mode . helpful-mode)))
450 ("chat" (or (mode . erc-mode)
451 (mode . circe-server-mode)
452 (mode . circe-channel-mode)
453 (mode . jabber-chat-mode)
454 (mode . jabber-browse-mode)
455 (mode . jabber-roster-mode)))
456 ("shell" (or (mode . eshell-mode)
457 (mode . shell-mode)
458 (mode . vterm-mode)))
459 ("web" (or (mode . elpher-mode)
460 (mode . eww-mode))))))
461 (:hook (defun ibuffer@filter-to-default ()
462 (ibuffer-auto-mode +1)
463 (ibuffer-switch-to-saved-filter-groups "default"))))
464
465(setup info
466 (:also-load +Info)
467 (dolist (dir (split-string (getenv "INFOPATH") ":" t))
468 (add-to-list 'Info-additional-directory-list dir))
469 (:with-mode Info-mode ; -_-
470 (:hook #'reading-mode)
471 (:local-set +modeline-buffer-position #'+Info-modeline-breadcrumbs
472 +modeline-position-function #'ignore)
473 (:bind "c" #'+Info-copy-current-node-name
474 "w" #'+Info-copy-current-node-name)))
475
476(setup ispell
477 (:also-load +ispell)
478 (:option ispell-program-name (or (executable-find "ispell")
479 (executable-find "aspell")))
480 (put 'ispell-buffer-session-localwords
481 'safe-local-variable #'+ispell-safe-local-p)
482 (add-hook 'user-save-before-save-hook #'+ispell-move-buffer-words-to-dir-locals-hook))
483
484(setup kmacro
485 (:also-load +kmacro)
486 (with-eval-after-load '+kmacro
487 ;; (+kmacro-recording-indicator-mode +1)
488 (+kmacro-block-undo-mode +1)))
489
490(setup make-mode
491 (:hook (defun +make-remove-warnings ()
492 (dolist (f '(makefile-warn-continuations
493 makefile-warn-suspicious-lines))
494 (remove-hook 'write-file-functions f t)))))
495
496(setup midnight
497 (midnight-mode +1)
498 (add-hook 'midnight-hook #'recentf-cleanup))
499
500(setup minibuffer
501 (:require +minibuffer)
502 (:with-map minibuffer-local-map
503 (:bind "M-/" #'+minibuffer-complete-history)))
504
505(setup mouse
506 ;; Brand new for Emacs 28: see https://ruzkuku.com/texts/emacs-mouse.html
507 ;; Actually, look at this as well: https://www.emacswiki.org/emacs/Mouse3
508 (when (fboundp 'context-menu-mode)
509 (:option context-menu-functions
510 '(context-menu-ffap
511 context-menu-region
512 context-menu-undo
513 ;; context-menu-dictionary
514 ))
515 (context-menu-mode +1))
516 (dolist (click '(;; Fix scrolling in the margin
517 wheel-down double-wheel-down triple-wheel-down
518 wheel-up double-wheel-up triple-wheel-up))
519 (global-set-key (vector 'right-margin click) 'mwheel-scroll)
520 (global-set-key (vector 'left-margin click) 'mwheel-scroll)))
521
522(setup net-utils
523 (:needs "traceroute")
524 (:require +finger) ; fixes `finger' to use var below
525 (:option finger-X.500-host-regexps '(".") ; only send username
526 )
527 (with-eval-after-load 'transient
528 (transient-define-prefix net-utils ()
529 "Networking utilities"
530 ["Actions"
531 ("p" "Ping" ping)
532 ("i" "Ifconfig" ifconfig)
533 ("w" "Iwconfig" iwconfig)
534 ("n" "Netstat" netstat)
535 ("a" "Arp" arp)
536 ("r" "Route" route)
537 ("h" "Nslookup host" nslookup-host)
538 ("d" "Dig" dig)
539 ("s" "Smb Client" smbclient)
540 ("t" "Traceroute" traceroute)])
541 (:+key "C-z M-n" #'net-utils)))
542
543(setup notmuch
544 (:load-from "~/usr/share/emacs/site-lisp/")
545 (:load-after bbdb)
546 (:also-load +notmuch +message)
547 (+define-dir notmuch/ (sync/ "emacs/notmuch")
548 "Notmuch configuration and data.")
549 (:option notmuch-init-file (notmuch/ "notmuch-init.el" t)
550 notmuch-address-save-filename (notmuch/ "addresses" t)
551 notmuch-address-use-company (featurep 'company)
552 notmuch-search-oldest-first nil
553 notmuch-archive-tags '("-inbox" "-unread")
554 notmuch-draft-tags '("+draft" "-inbox" "-unread"))
555 ;; Reading mail
556 (:option notmuch-show-indent-content nil)
557 (add-hook 'notmuch-show-mode-hook #'visual-fill-column-mode)
558 (:with-mode notmuch-search-mode
559 (:bind "RET" #'notmuch-search-show-thread
560 "M-RET" #'notmuch-tree-from-search-thread
561 "!" #'+notmuch-search-mark-spam))
562 (:with-mode notmuch-tree-mode
563 (:bind "!" #'+notmuch-tree-mark-spam-then-next))
564 ;; Composing mail
565 (:option message-kill-buffer-on-exit t
566 message-auto-save-directory nil)
567 ;; Sending mail
568 (:option send-mail-function #'sendmail-send-it
569 mail-specify-envelope-from t
570 message-sendmail-envelope-from 'header
571 mail-envelope-from 'header)
572 ;; Extras and fixes
573 (with-eval-after-load 'notmuch
574 (load notmuch-init-file :noerror)
575 (add-hook 'message-setup-hook #'+message-signature-setup)
576 (add-hook 'message-send-hook #'+send-mail-dispatch)
577 (advice-add 'notmuch-tag :filter-args #'+notmuch-correct-tags)
578 (:option notmuch-saved-searches (list
579 (list :name "inbox+unread"
580 :query (+notmuch-query-concat
581 "tag:inbox"
582 "tag:unread"
583 "NOT tag:Spam")
584 :key "m"
585 :search-type 'tree)
586 (list :name "inbox"
587 :query (+notmuch-query-concat
588 "tag:inbox"
589 "NOT tag:Spam")
590 :key "i"
591 :search-type 'tree)
592 (list :name "lists+unread"
593 :query (+notmuch-query-concat
594 "tag:/List/"
595 "tag:unread")
596 :key "l"
597 :search-type 'tree)
598 (list :name "lists"
599 :query "tag:/List/"
600 :key "L"
601 :search-type 'tree)
602 (list :name "unread"
603 :query (+notmuch-query-concat
604 "tag:unread"
605 "NOT tag:Spam")
606 :key "u"
607 :search-type 'tree)
608 (list :name "flagged"
609 :query "tag:flagged"
610 :key "f"
611 :search-type 'tree)
612 (list :name "sent"
613 :query "tag:sent"
614 :key "t"
615 :search-type 'tree)
616 (list :name "drafts"
617 :query "tag:draft"
618 :key "d"
619 :search-type 'tree)
620 (list :name "all mail"
621 :query "*"
622 :key "a"
623 :search-type 'tree))))
624 (:+leader "m" #'notmuch-mua-new-mail "C-m" #'notmuch-jump-search
625 "n" #'notmuch "C-n" #'notmuch)
626 ;; For `focus'
627 (put 'notmuch-message 'bounds-of-thing-at-point 'notmuch-show-message-extent))
628
629(setup org
630 ;; Plain org with the `setup' form for sorting, but I install with straight.
631 (:straight (org
632 :type git :host nil
633 :repo "https://git.savannah.gnu.org/git/emacs/org-mode.git"
634 :local-repo "org"
635 :depth full
636 :pre-build (straight-recipes-org-elpa--build)
637 :build (:not autoloads)
638 :files (:defaults
639 "lisp/*.el"
640 ("etc/styles/" "etc/styles/*"))))
641 (:straight (org-contrib
642 :type git :host nil
643 :repo "https://git.sr.ht/~bzg/org-contrib"))
644 ;; DO NOT load system-installed org !!!
645 (setq load-path
646 (cl-remove-if (lambda (path) (string-match-p "lisp/org\\'" path)) load-path))
647 (:also-load +org)
648 (with-eval-after-load '+org (+org-agenda-inhibit-hooks-mode +1))
649 (:option org-adapt-indentation nil
650 org-auto-align-tags t
651 org-archive-mark-done t
652 org-fold-catch-invisible-edits 'show-and-error
653 org-clock-clocked-in-display 'mode-line
654 org-clock-frame-title-format (cons
655 '(t org-mode-line-string)
656 (cons " --- " frame-title-format))
657 org-clock-string-limit 7 ; just the clock bit
658 ;; org-clock-string-limit 25 ; gives enough information
659 org-clock-persist nil
660 org-confirm-babel-evaluate nil
661 org-cycle-separator-lines 0
662 org-directory (sync/ "org/" t)
663 org-ellipsis (or truncate-string-ellipsis "…")
664 org-fontify-done-headline t
665 org-fontify-quote-and-verse-blocks t
666 org-fontify-whole-heading-line t
667 org-hide-emphasis-markers t
668 org-html-coding-system 'utf-8-unix
669 org-image-actual-width (list (* (window-font-width)
670 (- fill-column 8)))
671 org-imenu-depth 3
672 org-indent-indentation-per-level 0
673 org-indent-mode-turns-on-hiding-stars nil
674 org-insert-heading-respect-content t
675 org-list-demote-modify-bullet '(("-" . "+")
676 ("+" . "-"))
677 org-log-done 'time
678 org-log-into-drawer t
679 org-num-skip-commented t
680 org-num-skip-unnumbered t
681 org-num-skip-footnotes t
682 org-outline-path-complete-in-steps nil
683 org-pretty-entities t
684 org-pretty-entities-include-sub-superscripts nil
685 org-refile-targets '((nil . (:maxlevel . 2))
686 (org-agenda-files . (:maxlevel . 1)))
687 org-refile-use-outline-path 'file
688 org-special-ctrl-a/e t
689 org-special-ctrl-k t
690 org-src-fontify-natively t
691 org-src-tab-acts-natively t
692 org-src-window-setup 'current-window
693 org-startup-truncated nil
694 org-startup-with-inline-images t
695 org-tags-column -77 ;; (- (- fill-column 1 (length org-ellipsis)))
696 org-todo-keywords
697 '((sequence "TODO(t)" "WAIT(w@/!)" "ONGOING(o@)"
698 "|" "DONE(d!)" "ASSIGNED(a@/!)")
699 (sequence "|" "CANCELED(k@)")
700 (sequence "MEETING(m)"))
701 org-use-speed-commands t
702 org-emphasis-alist '(("*" org-bold)
703 ("/" org-italic)
704 ("_" org-underline)
705 ("=" org-verbatim)
706 ("~" org-code)
707 ("+" org-strikethrough)))
708 ;; (setq org-todo-keywords
709 ;; '((sequence
710 ;; "TODO(t)"
711 ;; "NEXT(n!)" ; next action
712 ;; "DONE(d)" ; done)
713 ;; (sequence
714 ;; "WAIT(w@)" ; waiting to be actionable again
715 ;; "HOLD(h@/!)" ; actinable, but will do later
716 ;; "IDEA(i)" ; maybe someday
717 ;; "KILL(k@/!)" ; cancelled, aborted or is no longer applicable
718 ;; ))))
719 (:bind "RET" #'+org-return-dwim
720 "<S-return>" #'+org-table-copy-down
721 "M-RET" #'+org-meta-return
722 "C-c C-l" #'+org-insert-link-dwim
723 "C-c C-n" #'+org-next-heading-widen
724 "C-c C-p" #'+org-previous-heading-widen
725 "C-c C-o" #'+org-open-at-point-dwim
726 "`" #'+org-insert-tilde
727 "~" #'+org-insert-backtick
728 "C-c C-x l" #'org-toggle-link-display
729 "C-c C-x m" #'+org-toggle-view-emphasis
730 "C-c C-x r" #'+org-drawer-list-add-resource
731 "C-M-k" #'kill-paragraph
732 "C-M-t" #'transpose-paragraphs)
733 (:global [f8] #'org-clock-in
734 [f9] #'org-clock-out
735 "C-c l" #'org-store-link)
736 (+with-ensure-after-init
737 (:hook #'variable-pitch-mode
738 #'visual-fill-column-mode
739 #'turn-off-auto-fill
740 #'org-indent-mode ;; Needed for proper hanging indents in lists
741 #'prettify-symbols-mode
742 #'+org-wrap-on-hyphens))
743 (:local-set prettify-symbols-alist '(("DEADLINE:" . ?→)
744 ("SCHEDULED:" . ?↷)
745 ("CLOSED:" . ?✓))
746 ;; electric-pair-pairs
747 ;; (append electric-pair-pairs
748 ;; (mapcar (lambda (emph)
749 ;; (let ((ch (string-to-char (car emph))))
750 ;; (cons ch ch)))
751 ;; org-emphasis-alist))
752 )
753 (:local-hook user-save-before-save-hook #'+org-before-save@prettify-buffer)
754 (advice-add #'org-delete-backward-char :override #'+org-delete-backward-char)
755 ;; (define-advice org-open-at-point (:around (fn &rest r) open-external)
756 ;; "Open links from org externally."
757 ;; (let ((browse-url-browser-function browse-url-secondary-browser-function))
758 ;; (apply fn r)))
759 ;; (add-to-list '+custom-variable-allowlist 'org-agenda-files)
760 (with-eval-after-load 'org
761 (setf (alist-get "\\.x?html?\\'" org-file-apps nil nil #'equal)
762 #'+org-open-html)
763 (org-clock-persistence-insinuate)
764 (org-link-set-parameters "tel" :follow #'+org-tel-open)
765 (org-link-set-parameters "sms" :follow #'+org-sms-open)
766 (setf (alist-get "\\.x?html?\\'" org-file-apps nil nil #'equal)
767 #'+org-open-html)
768 (advice-add 'org-agenda :before
769 (defun +org-agenda-files-uniquify (&rest _)
770 (setq org-agenda-files
771 (seq-uniq org-agenda-files)))))
772 (:face 'org-done '((t (:inherit (modus-themes-subtle-green))))
773 'org-tag '((t (:inherit (secondary-selection))))
774 'org-todo '((t (:inherit (modus-themes-subtle-red)))))
775 ;; Extra keywords
776 (font-lock-add-keywords
777 'org-mode
778 '(;; Fancy list bullets
779 ;; NOTE: these `progn' and `default's are necessary; otherwise Emacs
780 ;; complains about "Invalid face reference: t" in org-mode buffers, because
781 ;; `compose-region' returns t.
782 ("^[ \t]*\\([-]\\) "
783 (0 (progn (compose-region (match-beginning 1) (match-end 1) "–") 'fixed-pitch)
784 ;; 'fixed-pitch t
785 ))
786 ("^[ \t]*\\([+]\\) "
787 (0 (progn (compose-region (match-beginning 1) (match-end 1) "•") 'fixed-pitch)
788 ;; 'fixed-pitch t
789 ))
790 ("^[ \t]+\\([*]\\) "
791 (0 ;; (progn (compose-region (match-beginning 1) (match-end 1) "→") 'fixed-pitch)
792 'fixed-pitch t))
793 ;; Fancy numbered lists (well, monospaced)
794 ("^[ \t]*\\(\\(?:[0-9]+\\|[A-Za-z]\\)[.)]\\) " 0 'fixed-pitch t)
795 ;; Make leading org-heading stars fixed-pitch
796 ("^\*+ " 0 'fixed-pitch t)
797 ))
798 (with-eval-after-load 'form-feed
799 ;; Horizontal lines
800 (font-lock-add-keywords
801 'org-mode
802 '(("^-----+" . form-feed--font-lock-face))))
803 (put 'browse-url-browser-function 'safe-local-variable
804 (lambda (val)
805 (eq (function-get val 'browse-url-browser-kind :autoload)
806 'external))))
807
808(setup org-agenda
809 (:option org-agenda-skip-deadline-if-done t
810 org-agenda-skip-scheduled-if-done t
811 org-agenda-span 10
812 org-agenda-block-separator ?─
813 org-agenda-time-grid
814 '((daily today require-timed)
815 (800 1000 1200 1400 1600 1800 2000)
816 " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
817 org-agenda-current-time-string
818 "← now ─────────────────────────────────────────────────"
819 org-agenda-include-diary nil ; I use the org-diary features
820 org-agenda-todo-ignore-deadlines 'near
821 org-agenda-todo-ignore-scheduled 'future
822 org-agenda-include-deadlines t
823 org-deadline-warning-days 0
824 org-agenda-show-future-repeats 'next
825 org-agenda-window-setup 'current-window)
826 (unless after-init-time
827 (:option org-agenda-files (list (sync/ "org/"))))
828 (dolist (var '(org-agenda-files
829 org-agenda-file-regexp
830 org-agenda-templates))
831 (add-to-list '+custom-variable-allowlist var))
832 (define-advice org-agenda-files (:filter-return (ret))
833 "Remove SyncThing's sync-conflict files from the org agenda."
834 (seq-remove (lambda (f) (string-match-p "sync-conflict" f)) ret))
835 (:+leader "a" #'org-agenda "C-a" #'org-agenda)
836 (:hook #'hl-line-mode)
837 (:local-set truncate-lines t)
838 (add-hook 'org-agenda-after-show-hook #'org-narrow-to-subtree))
839
840(setup org-attach
841 (:also-load +org-attach)
842 (:option org-attach-method 'lns)
843 (with-eval-after-load '+org-attach
844 (+org-attach-fix-args-mode +1)))
845
846(setup org-capture
847 (:require +org-capture)
848 (:+leader "c" #'org-capture "C-c" #'org-capture)
849 (+org-capture-templates-setf "t" "Todo")
850 (+org-capture-templates-setf "tt"
851 `("Today!" entry (file "todo.org")
852 ,(concat "* TODO %^{Title}\n"
853 "DEADLINE: %t\n"
854 "\n%?")))
855 (+org-capture-templates-setf "ts"
856 `("Someday..." entry (file "todo.org")
857 ,(concat "* TODO %^{Title}\n"
858 ":PROPERTIES:\n"
859 ":CREATED: [%<%F %T>]\n"
860 ":END:\n"
861 "\n%?")))
862 (+org-capture-templates-setf "tm"
863 `("Media" entry (file "todo.org")
864 ,(concat "* TODO %^{TITLE}\n"
865 ":PROPERTIES:\n"
866 ":TITLE: %\\1\n"
867 ":AUTHOR: %^{AUTHOR}\n"
868 ":END:\n"
869 "\n%?")))
870 (+org-capture-templates-setf "l"
871 `("Link" entry (file "links.org")
872 "* %(+org-insert-link-dwim) %^g\n\n"))
873 (+org-capture-templates-setf "w" "Work")
874 (+org-capture-templates-setf "j"
875 '("Journal entry" plain
876 (file+olp+datetree "journal.org")
877 "**** %U\n%i\n%?"))
878 ;; TODO: Prompt for identity file from ~/.ssh and try to guess the hostname
879 ;; from there.
880 (+org-capture-templates-setf "s"
881 `("SSH Config" plain (file "~/.ssh/config")
882 ,(concat "\n\nHost %^{Host}"
883 "\n Hostname %\\1"
884 "\n User %^{User|%(user-login-name)}"
885 "\n IdentityFile %(read-file-name \"IdentityFile: \" \"~/.ssh/\")"
886 "\n IdentitiesOnly yes"
887 "\n PubkeyAuthentication yes"
888 "\n Port %^{Port|22}")
889 ))
890 (+org-capture-templates-setf "r"
891 `("Radio station" plain (file "~/.config/radio/stations")
892 ,(concat "%^{URL} %^{Description} %^{Tags [space delimited]}")
893 :immediate-finish t))
894 (+org-capture-sort))
895
896(setup org-id
897 (:load-after org)
898 ;; https://helpdeskheadesk.net/2022-03-13/
899 (:option org-id-method 'ts
900 org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
901 org-attach-id-uuid-folder-format)))
902
903(setup ox ; org-export
904 (:also-load +ox
905 ox-md)
906 (:option org-export-coding-system 'utf-8-unix
907 org-export-headline-levels 8
908 org-export-with-drawers nil
909 org-export-with-section-numbers nil
910 org-export-with-smart-quotes t
911 org-export-with-sub-superscripts t
912 org-export-with-toc nil)
913 (with-eval-after-load 'ox
914 (+org-export-pre-hooks-insinuate)))
915
916(setup password-cache
917 (:option password-cache t
918 password-cache-expiry (* 60 60)))
919
920(setup prettify-symbols-mode
921 (:option prettify-symbols-unprettify-at-point t))
922
923(setup prog
924 (:local-set comment-auto-fill-only-comments t)
925 (:hook #'prettify-symbols-mode))
926
927(setup scheme
928 ;; I use CHICKEN
929 (:require +chicken)
930 (:with-mode scheme-mode
931 (:file-match (rx ".scm" eos)))
932 (setq scheme-mit-dialect nil
933 scheme-program-name (executable-find "csi")
934 scheme-default-implementation 'chicken)
935 ;; Scheme complete
936 (straight-use-package 'scheme-complete)
937 (autoload 'scheme-smart-complete "scheme-complete" nil t)
938 (with-eval-after-load 'scheme
939 (define-key scheme-mode-map (kbd "TAB") #'scheme-complete-or-indent))
940 (autoload 'scheme-get-current-symbol-info "scheme-complete" nil t)
941 (:local-set eldoc-documentation-function #'scheme-get-current-symbol-info
942 lisp-indent-function #'scheme-smart-indent-function)
943 (:hook #'eldoc-mode))
944
945(setup scratch
946 (:require +scratch)
947 (:option initial-major-mode #'lisp-interaction-mode
948 initial-scratch-message ";;; What good will you work in the world today?\n\n")
949 (:+leader "." #'+scratch-switch-to-scratch
950 "C-." #'+scratch-switch-to-scratch
951 "," #'+scratch-switch-to-text
952 "C-," #'+scratch-switch-to-text)
953 (+with-ensure-after-init
954 (+scratch-text-scratch))
955 (add-hook 'kill-buffer-query-functions #'+scratch-immortal))
956
957(setup sh
958 (:option sh-indentation tab-width)
959 (:hook #'indent-tabs-mode)
960 (:apheleia shfmt '("shfmt")))
961
962(setup shell
963 (:option shell-command-prompt-show-cwd t)
964 (:local-set +modeline-position-function
965 (lambda () (string-replace (getenv "HOME")
966 "~"
967 default-directory)))
968 (:hook #'form-feed-mode))
969
970(setup shr
971 (:also-load +shr)
972 (:option shr-width (- fill-column 5) ; pad out for wide letters
973 shr-use-fonts t)
974 (dolist (mode '(eww-mode
975 elfeed-show-mode))
976 (add-hook (intern (format "%s-hook" mode)) #'+shr-heading-setup-imenu)))
977
978(setup tab-bar
979 (:require +tab-bar)
980 (:option tab-bar-tab-name-function '+tab-bar-basename
981 tab-bar-tab-name-truncated-max 20
982 tab-bar-tab-name-ellipsis truncate-string-ellipsis
983 tab-bar-show t
984 tab-bar-close-button-show t
985 tab-bar-new-button-show t
986 +tab-bar-menu-bar-icon " ; "
987 tab-bar-close-button (propertize " × "
988 'display t
989 'close-tab nil)
990 tab-bar-new-button (propertize "+ " 'display t))
991 ;; I need to set these here so that they take effect /before/ `display-time-mode'
992 (:option display-time-format "%H:%M"
993 display-time-mail-file :disable
994 display-time-load-average-threshold 50)
995 (:option tab-bar-format '(;;+tab-bar-format-menu-bar
996 tab-bar-format-history
997 tab-bar-format-tabs
998 tab-bar-separator
999 tab-bar-format-add-tab
1000 +tab-bar-format-align-right
1001 ;;+tab-bar-misc-info
1002 +tab-bar-org-clock
1003 +tab-bar-bongo
1004 ;;+tab-bar-emms
1005 +tab-bar-tracking-mode
1006 +tab-bar-notmuch-count
1007 +tab-bar-timer
1008 +tab-bar-date
1009 +tab-bar-space))
1010 (tab-bar-mode +1)
1011 (display-time-mode +1))
1012
1013(setup text-mode
1014 (:bind "C-M-k" #'kill-paragraph))
1015
1016(setup timer-list
1017 (:bind "d" #'timer-list-cancel)
1018 (:hook #'hl-line-mode
1019 #'lin-mode))
1020
1021(setup tramp
1022 (el-patch-feature tramp)
1023 (with-eval-after-load 'tramp
1024 (el-patch-defun tramp-debug-buffer-command-completion-p (_symbol buffer)
1025 "A predicate for Tramp interactive commands.
1026 They are completed by \"M-x TAB\" only in Tramp debug buffers."
1027 (with-current-buffer buffer
1028 (el-patch-wrap 2
1029 (save-restriction
1030 (widen)
1031 (string-equal (buffer-substring 1 10) ";; Emacs:")))))))
1032
1033(setup whitespace
1034 (:option whitespace-line-column nil
1035 whitespace-style '(face trailing tabs tab-mark))
1036 ;; I want trailing whitespace to be cleaned up, but I don't need to know about it.
1037 (:face 'whitespace-trailing '((t :inherit nil)))
1038 (:hook-into text-mode prog-mode))
1039
1040(setup (:straight 0x0)
1041 (:option 0x0-default-server 'ttm)
1042 (with-eval-after-load 'embark
1043 (define-key embark-region-map (kbd "U") #'0x0-dwim)))
1044
1045(setup (:straight ace-window)
1046 (:require +ace-window)
1047 (:option aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
1048 aw-display-mode-overlay nil
1049 aw-scope 'frame
1050 aw-minibuffer-flag t)
1051 (:+key "M-o" #'+ace-window-or-switch-buffer)
1052 (:face 'aw-mode-line-face '((t (:foreground "red"))))
1053 (+ace-window-display-mode +1))
1054
1055(setup (:straight (actually-selected-window :host github
1056 :repo "duckwork/actually-selected-window.el"))
1057 (actually-selected-window-mode +1))
1058
1059(setup (:straight adaptive-wrap)
1060 (:with-mode adaptive-wrap-prefix-mode
1061 (:hook-into visual-column-mode)))
1062
1063(setup (:straight affe
1064 (or (executable-find "rg")
1065 (and (executable-find "find")
1066 (executable-find "grep"))))
1067 (:load-after consult orderless vertico)
1068 (setq affe-regexp-compiler (defun affe-orderless-regexp-compiler (input &rest _)
1069 (setq input (orderless-pattern-compiler input))
1070 (cons input (lambda (str) (orderless--highlight input str)))))
1071 (+with-eval-after-loads (affe)
1072 (setq affe-regexp-compiler (defun affe-orderless-regexp-compiler (input &rest _)
1073 (setq input (orderless-pattern-compiler input))
1074 (cons input (lambda (str) (orderless--highlight input str)))))
1075 (:+key "M-s g" #'affe-grep
1076 "M-s f" #'affe-find)))
1077
1078(setup (:straight alert)
1079 (:option alert-default-style 'libnotify))
1080
1081(setup (:straight anzu)
1082 (:option anzu-cons-mode-line-p nil)
1083 (:+key [remap query-replace] #'anzu-query-replace-regexp
1084 [remap query-replace-regexp] #'anzu-query-replace-regexp)
1085 (global-anzu-mode +1)
1086 (:bind-into isearch
1087 [remap isearch-query-replace] #'anzu-isearch-query-replace
1088 [remap isearch-query-replace-regexp] #'anzu-isearch-query-replace-regexp))
1089
1090(setup (:straight apheleia)
1091 (:require apheleia +apheleia)
1092 (+apheleia/user-save-global-mode +1)
1093 (add-to-list 'apheleia-formatters `(fmt . ("fmt"
1094 "-s" ; split long lines but don't refill
1095 "-u" ; one space words, two space sentences
1096 "-w" ; set width (fill-column)
1097 ,(number-to-string (floor (* fill-column 1.1)))
1098 "-g" ; goal width
1099 ,(number-to-string fill-column)))))
1100
1101(setup (:straight avy)
1102 (:require avy +avy)
1103 (:option avy-background t
1104 avy-lead-faces
1105 '(avy-lead-face
1106 avy-lead-face-1 avy-lead-face-1 avy-lead-face-1
1107 avy-lead-face-1 avy-lead-face-1 avy-lead-face-1))
1108 (:face 'avy-background-face
1109 '((t (:foreground "#888888"))))
1110 (:+key "M-j" #'avy-goto-char-timer)
1111 (:bind-into isearch
1112 "M-j" #'avy-isearch)
1113 (setf (alist-get ?. avy-dispatch-alist) #'avy-action-embark)
1114 ;; (+avy-buffer-face-mode +1)
1115 )
1116
1117(setup (:straight bbdb)
1118 (:straight bbdb-vcard)
1119 (add-hook '+custom-after-load-hook
1120 (defun +bbdb-load ()
1121 (:require bbdb-autoloads
1122 bbdb)
1123 (bbdb-initialize 'gnus 'message)
1124 (bbdb-insinuate-message)
1125 (setq bbdb-complete-mail-allow-cycling t))))
1126
1127(setup (:straight (bongo :type git
1128 :flavor melpa
1129 :files ("*.el" "*.texi" "images" "*.rb" "bongo-pkg.el" "*.info")
1130 :pre-build ("makeinfo" "--no-split" "bongo.texi")
1131 :host github
1132 :repo "dbrock/bongo"))
1133 (:also-load +bongo)
1134 (:option bongo-default-directory "~/var/music"
1135 bongo-custom-backend-matchers '((mpv . (("https:") . t)))
1136 +bongo-radio-stations ; use `+bongo-radio' for these
1137 `(;; Local radio
1138 ("KLSU"
1139 . "http://130.39.238.143:8010/stream.mp3")
1140 ("WRKF: NPR for the Capital Region"
1141 . ,(concat "https://playerservices.streamtheworld.com/api/"
1142 "livestream-redirect/WRKFFM.mp3"))
1143 ("WRKF HD-2"
1144 . ,(concat "https://playerservices.streamtheworld.com/api/"
1145 "livestream-redirect/WRKFHD2.mp3"))
1146 ("WBRH: Jazz & More"
1147 . "http://wbrh.streamguys1.com/wbrh-mp3")
1148 ("KBRH Blues & Rhythm Hits"
1149 . "http://wbrh.streamguys1.com/kbrh-mp3")
1150 ;; Soma FM
1151 ("Soma FM Synphaera"
1152 . "https://somafm.com/synphaera256.pls")
1153 ("SomaFM BAGel Radio"
1154 . "https://somafm.com/bagel.pls")
1155 ("SomaFM Boot Liquor"
1156 . "https://somafm.com/bootliquor320.pls")
1157 ("SomaFM Deep Space One"
1158 . "https://somafm.com/deepspaceone.pls")
1159 ("SomaFM Fluid"
1160 . "https://somafm.com/fluid.pls")
1161 ("SomaFM Underground 80s"
1162 . "https://somafm.com/u80s256.pls")
1163 ;; Tildeverse & Friends
1164 ("tilderadio"
1165 . "https://azuracast.tilderadio.org/radio/8000/radio.ogg")
1166 ("vantaradio"
1167 . "https://vantaa.black/radio")
1168 ;; Other online radio
1169 ("BadRadio: 24/7 PHONK"
1170 . "https://s2.radio.co/s2b2b68744/listen")
1171 ("Cafe - lainon.life"
1172 . "https://lainon.life/radio/cafe.ogg.m3u")
1173 ("Everything - lainon.life"
1174 . "https://lainon.life/radio/everything.ogg.m3u")
1175 ("Swing - lainon.life"
1176 . "https://lainon.life/radio/swing.ogg.m3u")
1177 ("Cyberia - lainon.life"
1178 . "https://lainon.life/radio/cyberia.ogg.m3u")
1179 ("Nightwave Plaza - Online Vaporwave Radio"
1180 . "http://radio.plaza.one/opus")))
1181 (advice-add 'bongo-play :before #'+bongo-stop-all)
1182 (with-eval-after-load 'notifications
1183 (add-hook 'bongo-player-metadata-changed-hook #'+bongo-notify)))
1184
1185(setup (:straight brainfuck-mode))
1186
1187(setup (:straight browse-kill-ring)
1188 (:+key "C-M-y" #'browse-kill-ring)
1189 (:option browse-kill-ring-highlight-current-entry t
1190 browse-kill-ring-highlight-inserted-item 'pulse
1191 browse-kill-ring-separator " ")
1192 (:hook #'form-feed-mode))
1193
1194(setup (:straight burly)
1195 (:require burly +burly)
1196 (:global "C-x C-c" #'+burly-save-then-close-frame-remembering))
1197
1198(setup (:straight (cape :host github :repo "minad/cape"))
1199 (let
1200 ;; All available cape capfs listed here. Add them to the front since
1201 ;; they're reversed with `add-to-list'.
1202 ((append-fns '(cape-file
1203 cape-dabbrev
1204 cape-keyword))
1205 (remove-fns '(cap-abbrev
1206 cape-ispell
1207 cape-dict)))
1208 (dolist (fn append-fns)
1209 (add-to-list 'completion-at-point-functions fn :append))
1210 (dolist (fn remove-fns)
1211 (setq completion-at-point-functions
1212 (delete fn completion-at-point-functions)))
1213 ;; Fix position of t
1214 (when (memq t completion-at-point-functions)
1215 (setq completion-at-point-functions
1216 (append (delq t completion-at-point-functions)
1217 '(t))))))
1218
1219(setup (:straight circe)
1220 (:require _circe
1221 +circe)
1222 ;; (:also-load circe-chanop)
1223 ;; (+ensure-after-init (lambda () (defalias 'irc '+irc "Start IRC.")))
1224
1225 ;; Formatting options
1226 ;; (:option
1227 ;; ;; Messages between users
1228 ;; circe-format-action (format (format "%%%ds* {nick} {body}"
1229 ;; (- +circe-left-margin 2))
1230 ;; " ")
1231 ;; circe-format-say (format "{nick:%1$d.%1$ds} | {body}"
1232 ;; (- +circe-left-margin 3))
1233 ;; circe-format-self-action circe-format-action
1234 ;; circe-format-self-say (replace-regexp-in-string "|" ">" circe-format-say)
1235 ;; circe-format-notice (format "-{nick:%1$d.%1$ds}---{body}"
1236 ;; (- +circe-left-margin 4))
1237 ;; circe-format-message (format (format "%%%ds@ *{nick}* {body}"
1238 ;; (- +circe-left-margin 2))
1239 ;; " ")
1240 ;; circe-format-message-action (replace-regexp-in-string "@" "*"
1241 ;; circe-format-message)
1242 ;; circe-format-self-message (format (format "%%%ds> *{chattarget}* {body}"
1243 ;; (- +circe-left-margin 2))
1244 ;; " ")
1245 ;; ;; Meta messages
1246 ;; circe-format-server-channel-creation-time (+circe-format-meta
1247 ;; (concat "Channel {channel}"
1248 ;; " created on {date}") t)
1249 ;; circe-format-server-ctcp (+circe-format-meta
1250 ;; (concat "CTCP PING request to {target} from"
1251 ;; " {userhost}: {body}"))
1252 ;; circe-format-server-ctcp-ping-reply (+circe-format-meta
1253 ;; (concat
1254 ;; "CTCP PING reply to {target} from"
1255 ;; " {userhost}: {body}"))
1256 ;; circe-format-server-part (+circe-format-meta "PART {channel}: {reason}")
1257 ;; circe-format-server-quit (+circe-format-meta "QUIT: {reason}")
1258 ;; circe-format-server-quit-channel (+circe-format-meta
1259 ;; "QUIT {channel}: {reason}")
1260 ;; circe-format-server-join (+circe-format-meta "JOIN: {userinfo}")
1261 ;; circe-format-server-join-in-channel (+circe-format-meta
1262 ;; "JOIN {channel}: {userinfo}")
1263 ;; circe-format-server-lurker-activity (+circe-format-meta
1264 ;; "(JOINED {joindelta} ago)")
1265 ;; circe-format-server-message (+circe-format-meta "{body}" t)
1266 ;; circe-fromat-server-mode-change (+circe-format-meta
1267 ;; (concat "MODE: {target} {change}"
1268 ;; " by {setter} ({userhost})") t)
1269 ;; circe-format-server-netmerge (+circe-format-meta
1270 ;; (concat "NETMERGE: {split} at {date}"
1271 ;; " (/WL to see who's still missing)") t)
1272 ;; circe-format-server-netsplit (+circe-format-meta
1273 ;; (concat "NETSPLIT: {split}"
1274 ;; " (/WL to see who left)") t)
1275 ;; circe-format-server-nick-change (+circe-format-meta
1276 ;; "NICK WAS {old-nick} ({userhost})"
1277 ;; "new-nick")
1278 ;; circe-format-server-nick-regain (+circe-format-meta
1279 ;; "NICK REGAINED: {old-nick} ({userhost})"
1280 ;; "new-nick")
1281 ;; circe-format-server-notice (+circe-format-meta "-SERVER NOTICE- {body}" t)
1282 ;; circe-format-server-topic-time (+circe-format-meta
1283 ;; "TOPIC SET BY {setter} on {topic-date}")
1284 ;; circe-format-server-topic-time-for-channel (+circe-format-meta
1285 ;; (concat
1286 ;; "TOPIC ({channel}) SET BY"
1287 ;; " {setter} on {topic-date}"))
1288 ;; circe-format-server-whois-idle (+circe-format-meta "IDLE FOR {idle-duration}"
1289 ;; "whois-nick")
1290 ;; circe-format-server-whois-idle-with-signon (+circe-format-meta
1291 ;; (concat
1292 ;; "IDLE FOR {idle-duration}"
1293 ;; " (signon: {signon-date})")
1294 ;; "whois-nick")
1295 ;; circe-format-server-rejoin (+circe-format-meta
1296 ;; (concat "REJOIN: {userinfo} "
1297 ;; "after {departuredelta}"))
1298 ;; circe-format-server-topic (+circe-format-meta "TOPIC: {new-topic}")
1299 ;; circe-prompt-string (format (format "%%%ds> "
1300 ;; (- +circe-left-margin 2))
1301 ;; " "))
1302
1303 ;; (:option +circe-server-buffer-action (lambda (buf)
1304 ;; (message "Connected to %s" buf))
1305 ;; +circe-network-inhibit-autoconnect _circe-network-inhibit-autoconnect
1306 ;; circe-network-options _circe-network-options
1307 ;; circe-color-nicks-everywhere t
1308 ;; circe-default-part-message "See You, Space Cowpokes . . ."
1309 ;; circe-default-user user-real-login-name
1310 ;; circe-reduce-lurker-spam t
1311 ;; circe-server-auto-join-default-type :after-auth)
1312 ;; (:bind "C-c C-p" #'circe-command-PART
1313 ;; "C-c C-t" #'+circe-current-topic
1314 ;; "C-l" #'lui-track-jump-to-indicator
1315 ;; "C-<return>" #'+circe-chat@set-prompt)
1316
1317 ;; XXX: this doesn't quite work right.
1318 ;; (advice-add #'circe-command-PART :after #'+circe-kill-buffer)
1319 ;; (advice-add #'circe-command-QUIT :after #'+circe-quit@kill-buffer)
1320 ;; (advice-add #'circe-command-GQUIT :after #'+circe-gquit@kill-buffer)
1321
1322 ;; (:with-mode circe-chat-mode
1323 ;; (:local-set lui-input-function #'+lui-filter
1324 ;; +modeline-position-function #'ignore)
1325 ;; (:hook #'enable-circe-color-nicks
1326 ;; #'enable-circe-new-day-notifier
1327 ;; #'+circe-chat@set-prompt
1328 ;; ;; Filters
1329 ;; ;;#'+circe-F/C-mode
1330 ;; ;; For some reason `+circe-shorten-url-mode' won't work right out of
1331 ;; ;; the gate.
1332 ;; ;;(lambda () (run-at-time 0.25 nil #'+circe-shorten-url-mode))
1333 ;; )
1334 ;; (:bind "C-c C-s" #'circe-command-SLAP))
1335
1336 ;; (:with-mode lui-mode
1337 ;; (:option lui-fill-column (+ fill-column +circe-left-margin)
1338 ;; lui-fill-type nil
1339 ;; lui-max-buffer-size (+bytes 10 :kb)
1340 ;; lui-time-stamp-position 'right-margin
1341 ;; lui-time-stamp-format "| %H:%M"
1342 ;; lui-track-behavior 'before-switch-to-buffer
1343 ;; lui-track-indicator 'bar
1344 ;; lui-fill-remove-face-from-newline nil
1345 ;; lui-formatting-list `((,(+lui-make-formatting-list-rx "*")
1346 ;; 1 lui-strong-face)
1347 ;; (,(+lui-make-formatting-list-rx "_")
1348 ;; 1 lui-emphasis-face)
1349 ;; (,(+lui-make-formatting-list-rx "/")
1350 ;; 1 lui-emphasis-face))
1351 ;; lui-autopaste-function
1352 ;; (defun +0x0-upload-string (string)
1353 ;; "Upload a string using 0x0."
1354 ;; (with-temp-buffer
1355 ;; (insert string)
1356 ;; (0x0-upload-text (0x0--choose-server)))
1357 ;; (current-kill 0)))
1358 ;; (add-to-list '+pulse-location-commands #'lui-track-jump-to-indicator)
1359 ;; (:face 'lui-track-bar '((t ( :height 10
1360 ;; :underline ( :color foreground-color
1361 ;; :style line
1362 ;; :position line)
1363 ;; :extend t :inhert (default)))))
1364 ;; (:hook #'visual-line-mode
1365 ;; #'enable-lui-track
1366 ;; #'visual-fill-column-mode
1367 ;; #'enable-lui-autopaste
1368 ;; (defun turn-off-+nyan-mode () (+nyan-local-mode -1))
1369 ;; (defun turn-off-electric-pair-mode () (electric-pair-mode -1)))
1370 ;; (:local-set fringes-outside-margins t
1371 ;; right-margin-width (length lui-time-stamp-format)
1372 ;; scroll-margin 0
1373 ;; scroll-step 1
1374 ;; word-wrap t
1375 ;; wrap-prefix (+string-repeat +circe-left-margin " ")
1376 ;; line-number-mode nil
1377 ;; column-number-mode nil
1378 ;; file-percentage-mode nil
1379 ;; visual-fill-column-extra-text-width
1380 ;; (cons +circe-left-margin 0)))
1381
1382 (tracking-mode +1)
1383 (:with-mode tracking-mode
1384 (:option tracking-position 'before-modes)
1385 (:bind "C-c C-SPC" (lambda () (interactive)
1386 (if (and +tracking-hide-when-org-clocking
1387 (fboundp 'org-clocking-p)
1388 (org-clocking-p))
1389 (message "Bro, get back to work!")
1390 (call-interactively #'tracking-next-buffer))))
1391 (add-to-list 'mode-line-misc-info
1392 '(tracking-mode
1393 tracking-mode-line-buffers)))
1394
1395 ;; (with-eval-after-load 'topsy
1396 ;; (:option (append topsy-mode-functions)
1397 ;; '(circe-channel-mode . +circe-current-topic)))
1398
1399 ;; (with-eval-after-load 'circe-color-nicks
1400 ;; (add-hook 'modus-themes-after-load-theme-hook #'circe-nick-color-reset))
1401 ;; (add-hook 'kill-emacs-hook #'+circe-quit-all@kill-emacs)
1402 )
1403
1404(setup (:straight (clean-kill-ring :host github
1405 :repo "NicholasBHubbard/clean-kill-ring.el"))
1406 (:require)
1407 (:option clean-kill-ring-prevent-duplicates t)
1408 (clean-kill-ring-mode +1))
1409
1410(setup (:straight clhs))
1411
1412(setup (:straight consult)
1413 (+with-ensure-after-init
1414 (:require consult +consult))
1415 ;; from Consult wiki
1416 (:option register-preview-delay 0
1417 register-preview-function #'consult-register-format
1418 xref-show-xrefs-function #'consult-xref
1419 xref-show-definitions-function #'consult-xref
1420 tab-always-indent 'complete
1421 completion-in-region-function #'consult-completion-in-region
1422 )
1423 (:with-mode minibuffer-mode
1424 (:local-set completion-in-region-function #'consult-completion-in-region))
1425 (advice-add #'register-preview :override #'consult-register-window) 46 (advice-add #'register-preview :override #'consult-register-window)
1426 (dolist (binding '(;; C-c bindings (mode-specific-map) 47 (define-keys (current-global-map)
1427 ("C-c h" . consult-history) 48 ;; C-c bindings (mode-specific-map)
1428 ("C-c m" . consult-mode-command) 49 "C-c h" #'consult-history
1429 ("C-c b" . consult-bookmark) 50 "C-c m" #'consult-mode-command
1430 ("C-c k" . consult-kmacro) 51 "C-c b" #'consult-bookmark
1431 ;; C-x bindings (ctl-x-map) 52 "C-c k" #'consult-kmacro
1432 ("C-x M-:" . consult-complex-command) 53 ;; C-x bindings (ctl-x-map)
1433 ("<f2>" . consult-buffer) 54 "C-x M-:" #'consult-complex-command
1434 ("C-x b" . consult-buffer) 55 "<f2>" #'consult-buffer
1435 ("C-x 4 b" . consult-buffer-other-window) 56 "C-x b" #'consult-buffer
1436 ("C-x 5 b" . consult-buffer-other-frame) 57 "C-x 4 b" #'consult-buffer-other-window
1437 ;; Custom M-# bindings for fast register access 58 "C-x 5 b" #'consult-buffer-other-frame
1438 ("M-#" . consult-register-load) 59 ;; Custom M-# bindings for fast register access
1439 ("M-'" . consult-register-store) 60 "M-#" #'consult-register-load
1440 ("C-M-#" . consult-register) 61 "M-'" #'consult-register-store
1441 ;; Other custom bindings 62 "C-M-#" #'consult-register
1442 ("M-y" . consult-yank-pop) 63 ;; Other custom bindings
1443 ;;("<f1> a" . consult-apropos) 64 "M-y" #'consult-yank-pop
1444 ;; M-g bindings (goto-map) 65 ;;("<f1> a" . consult-apropos)
1445 ("M-g e" . consult-compile-error) 66 ;; M-g bindings (goto-map)
1446 ("M-g f" . consult-flymake) ; or consult-flycheck 67 "M-g e" #'consult-compile-error
1447 ("M-g g" . consult-goto-line) 68 "M-g f" #'consult-flymake ; or consult-flycheck
1448 ("M-g M-g" . consult-goto-line) 69 "M-g g" #'consult-goto-line
1449 ("M-g o" . consult-outline) ; or consult-org-heading 70 "M-g M-g" #'consult-goto-line
1450 ("M-g m" . consult-mark) 71 "M-g o" #'consult-outline ; or consult-org-heading
1451 ("M-g k" . consult-global-mark) 72 "M-g m" #'consult-mark
1452 ("M-g i" . consult-imenu) 73 "M-g k" #'consult-global-mark
1453 ("M-g M-i" . consult-imenu) 74 "M-g i" #'consult-imenu
1454 ("M-g I" . consult-imenu-multi) 75 "M-g M-i" #'consult-imenu
1455 ;; M-s bindings (search-map) 76 "M-g I" #'consult-imenu-multi
1456 ("M-s f" . consult-find) 77 ;; M-s bindings (search-map)
1457 ("M-s F" . consult-locate) 78 "M-s f" #'consult-find
1458 ("M-s g" . consult-grep) 79 "M-s F" #'consult-locate
1459 ("M-s G" . consult-git-grep) 80 "M-s g" #'consult-grep
1460 ("M-s r" . consult-ripgrep) 81 "M-s G" #'consult-git-grep
1461 ("M-s l" . consult-line) 82 "M-s r" #'consult-ripgrep
1462 ("M-s L" . consult-line-multi) 83 "M-s l" #'consult-line
1463 ("M-s m" . consult-multi-occur) 84 "M-s L" #'consult-line-multi
1464 ("M-s k" . consult-keep-lines) 85 "M-s m" #'consult-multi-occur
1465 ("M-s u" . consult-focus-lines) 86 "M-s k" #'consult-keep-lines
1466 ;; Isearch integration 87 "M-s u" #'consult-focus-lines
1467 ("M-s e" . consult-isearch-history))) 88 ;; Isearch integration
1468 (global-set-key (kbd (car binding)) (cdr binding))) 89 "M-s e" #'consult-isearch-history)
1469 (with-eval-after-load 'isearch-mode 90 (eval-after isearch-mode
1470 (dolist (binding '(("M-e" . consult-isearch-history) 91 (define-keys isearch-mode-map
1471 ("M-s e" . consult-isearch-history) 92 "M-e" #'consult-isearch-history
1472 ("M-s l" . consult-line) 93 "M-s e" #'consult-isearch-history
1473 ("M-s L" . consult-line-multi))) 94 "M-s l" #'consult-line
1474 (define-key isearch-mode-map (car binding) (cdr binding)))) 95 "M-s L" #'consult-line-multi))
1475 (:+menu "b" #'consult-buffer 96 (eval-after org
1476 "f" #'find-file) 97 (define-key org-mode-map (kbd "M-g o") #'consult-org-heading)))
1477 (:bind-into org 98
1478 "M-g o" #'consult-org-heading) 99(yoke orderless "https://github.com/oantolin/orderless"
1479 (advice-add 'consult-yank-pop :after #'+yank@indent) 100 (require 'orderless)
1480 (+with-eval-after-loads (consult +consult) 101 (setq completion-styles '(substring orderless basic)
1481 (:option consult-narrow-key "<" 102 completion-category-defaults nil
1482 consult-project-root-function '+consult-project-root) 103 completion-category-overrides '((file (styles basic partial-completion)))
1483 (add-to-list 'consult-buffer-filter 104 orderless-component-separator #'orderless-escapable-split-on-space))
1484 (rx "*" (or "scratch" "text") "*")) 105
1485 (consult-customize consult-theme 106(yoke vertico "https://github.com/minad/vertico"
1486 :preview-key '(:debounce 0.2 any)) 107 (require 'vertico)
1487 (consult-customize consult-ripgrep consult-git-grep consult-grep 108 (setq resize-mini-windows 'grow-only
1488 consult-bookmark consult-recent-file consult-xref 109 vertico-count-format nil
1489 consult--source-recent-file 110 vertico-cycle t)
1490 consult--source-project-recent-file 111 (vertico-mode))
1491 consult--source-bookmark consult-buffer 112
1492 :preview-key (kbd "M-,")) 113(yoke marginalia "https://github.com/minad/marginalia/"
1493 (consult-history-to-modes ((minibuffer-local-map . nil) 114 (marginalia-mode))
1494 (shell-mode-map . shell-mode-hook) 115
1495 (term-mode-map . term-mode-hook) 116(yoke slime "https://github.com/slime/slime"
1496 (term-raw-map . term-mode-hook) 117 ;; r7rs-swank
1497 (comint-mode-map . comint-mode-hook) 118 (let ((r7rsloc (yoke-git "https://github.com/ecraven/r7rs-swank")))
1498 (sly-mrepl-mode-map . sly-mrepl-hook))) 119 (cond
1499 (with-eval-after-load 'orderless 120 ((executable-find "chibi-scheme")
1500 (:option consult--regexp-compiler #'consult--orderless-regexp-compiler)))) 121 (defun chibi-scheme-start-swank (file encoding)
1501 122 (format "%S\n\n" `(start-swank ,file)))
1502(setup (:straight crux) 123 (setq slime-lisp-implementations
1503 ;; yes it's silly I have an addon to this addon. 124 (cons `(chibi-scheme
1504 (:require crux +crux) 125 ("chibi-scheme" ,(format "-A%s" r7rsloc)
1505 (:option crux-shell-func #'crux-eshell 126 "-m" "(chibi-swank)")
1506 crux-shell-buffer-name "eshell" 127 :init chibi-scheme-start-swank)
1507 +crux-default-date-format "%F") 128 (bound-and-true-p slime-lisp-implementations)))))))
1508 (:global "C-o" #'crux-smart-open-line 129
1509 "C-x 4 t" #'crux-transpose-windows 130(yoke puni "https://github.com/amaikinono/puni"
1510 "M-w" #'+crux-kill-ring-save 131 (puni-global-mode)
1511 "C-k" #'+crux-kill-and-join-forward 132 (electric-pair-mode)
1512 "C-c d" #'+crux-insert-date-or-time) 133 (define-keys puni-mode-map
1513 (crux-with-region-or-buffer indent-region) 134 "C-)" #'puni-slurp-forward
1514 135 "C-(" #'puni-slurp-backward
1515 (el-patch-feature crux) 136 "C-}" #'puni-barf-forward
1516 (with-eval-after-load 'crux 137 "C-{" #'puni-barf-backward))
1517 (el-patch-defun crux-reopen-as-root () 138
1518 "Find file as root if necessary. 139(yoke hungry-delete "https://github.com/nflath/hungry-delete"
1519 140 (setq hungry-delete-chars-to-skip " \t"
1520 Meant to be used as `find-file-hook'. 141 hungry-delete-join-reluctantly nil)
1521 See also `crux-reopen-as-root-mode'." 142 (eval-after hungry-delete
1522 (unless (or 143 (add-to-list* 'hungry-delete-except-modes
1523 ;; This helps fix for `nov-mode', and possibly others. 144 'eshell-mode
1524 (el-patch-add (null buffer-file-name)) 145 'nim-mode
1525 (tramp-tramp-file-p buffer-file-name) 146 'python-mode))
1526 (equal major-mode 'dired-mode) 147 (defun +hungry-delete-or (hd-fn fn arg)
1527 (not (file-exists-p (file-name-directory buffer-file-name))) 148 (funcall (if (looking-back (format "[%s]" hungry-delete-chars-to-skip) arg)
1528 (file-writable-p buffer-file-name) 149 hd-fn
1529 (crux-file-owned-by-user-p buffer-file-name)) 150 fn)
1530 (crux-find-alternate-file-as-root buffer-file-name)))) 151 arg))
1531 (crux-reopen-as-root-mode +1)) 152 (define-keys puni-mode-map
1532 153 [remap puni-backward-delete-char]
1533(setup (:straight csv-mode)) 154 (defun puni@hungry-delete-backward (arg)
1534 155 (interactive "p")
1535(setup (:straight denote) 156 (+hungry-delete-or #'hungry-delete-backward
1536 (:option denote-directory (expand-file-name "~/var/notes"))) 157 #'puni-backward-delete-char
1537 158 arg))
1538(setup (:straight dictionary) 159 [remap puni-forward-delete-char]
1539 (:option dictionary-use-single-buffer t) 160 (defun puni@hungry-delete-forward (arg)
1540 (autoload 'dictionary-search "dictionary" 161 (interactive "p")
1541 "Ask for a word and search it in all dictionaries" t) 162 (+hungry-delete-or #'hungry-delete-forward
1542 (:hook #'reading-mode)) 163 #'puni-forward-delete-char
1543 164 arg)))
1544(setup (:straight diff-hl) 165 (global-hungry-delete-mode))
1545 (global-diff-hl-mode +1)) 166
1546 167(yoke cape "https://github.com/minad/cape"
1547(setup (:straight dired-git-info) 168 (defun cape-insinuate ()
1548 (:bind-into dired 169 (add-to-list* 'completion-at-point-functions
1549 ")" #'dired-git-info-mode)) 170 #'cape-dabbrev
1550 171 #'cape-file))
1551(setup (:straight dired-open) 172 (add-hook* '(text-mode-hook prog-mode-hook)
1552 (:load-after dired)) 173 #'cape-insinuate))
1553 174
1554(setup (:straight dired-rsync) 175(yoke minions "https://github.com/tarsius/minions"
1555 (:load-after dired) 176 (minions-mode))
1556 (:bind-into dired-mode
1557 "r" #'dired-rsync))
1558
1559(setup (:straight dired-subtree)
1560 (:load-after dired)
1561 (:bind-into dired
1562 "TAB" #'dired-subtree-cycle
1563 "i" #'dired-subtree-toggle))
1564
1565(setup (:straight (discord :host github
1566 :repo "davep/discord.el"
1567 :fork (:repo "duckwork/discord.el"))))
1568
1569(setup (:straight dumb-jump)
1570 (add-hook 'xref-backend-functions #'dumb-jump-xref-activate))
1571
1572(setup (:straight ebuku
1573 (executable-find "buku"))
1574 (:option ebuku-display-on-startup 'recent
1575 ebuku-recent-count 100))
1576
1577(setup (:straight edit-server)
1578 (:option edit-server-url-major-mode-alist `(("github\\.com" . ,(if (fboundp 'gfm-mode)
1579 #'gfm-mode
1580 #'markdown-mode))
1581 ("reddit\\.com" . markdown-mode)
1582 ("notabug\\.org" . markdown-mode)
1583 ("tildes\\.net" . markdown-mode)))
1584 (+with-ensure-after-init
1585 (edit-server-start)))
1586
1587(setup (:straight editorconfig)
1588 (:with-mode conf-mode
1589 (:file-match (rx ".editorconfig" eos)))
1590 (with-eval-after-load 'editorconfig
1591 (dolist (m '(emacs-lisp-mode
1592 lisp-mode
1593 scheme-mode))
1594 (add-to-list 'editorconfig-exclude-modes m)))
1595 (editorconfig-mode +1))
1596
1597(setup (:straight electric-cursor)
1598 (:option electric-cursor-alist '((overwrite-mode . hbar)
1599 (god-local-mode . box)
1600 (t . bar)))
1601 (electric-cursor-mode +1))
1602
1603;; (setup (:straight elfeed)
1604;; (:require +elfeed)
1605;; (+define-dir elfeed/ (sync/ "emacs/elfeed/" t))
1606;; (:option
1607;; elfeed-curl-program-name (executable-find "curl")
1608;; elfeed-use-curl elfeed-curl-program-name
1609;; elfeed-curl-extra-arguments '("--insecure")
1610;; elfeed-enclosure-default-dir (cl-loop for dir in '("~/var/download/"
1611;; "~/Downloads/")
1612;; if (file-exists-p dir)
1613;; return dir)
1614;; elfeed-search-filter "@10-days-ago +unread"
1615;; elfeed-search-trailing-width 24
1616;; elfeed-search-title-min-width 24
1617;; elfeed-search-title-max-width 78
1618;; elfeed-search-remain-on-entry t
1619;; elfeed-show-unique-buffers t
1620;; elfeed-db-directory (elfeed/ "db/" t))
1621;; (:+leader "f" #'elfeed "C-f" #'elfeed)
1622;; (advice-add #'elfeed-search-fetch :after #'beginning-of-buffer)
1623;; (:with-mode elfeed-search-mode
1624;; (:bind "&" #'+elfeed-search-browse-generic
1625;; "w" #'elfeed-search-yank
1626;; "y" nil
1627;; "a" #'+elfeed-show-mark-read-and-advance)
1628;; (:hook #'hl-line-mode)
1629;; ;; https://old.reddit.com/r/emacs/comments/rlli0u/whats_your_favorite_defadvice/hphfh4e/
1630;; (advice-add #'elfeed-search-update--force :after #'elfeed-db-save)
1631;; (advice-add #'elfeed :before #'elfeed-db-load))
1632;; (:with-mode elfeed-show-mode
1633;; (:bind "SPC" #'+elfeed-scroll-up-command
1634;; "S-SPC" #'+elfeed-scroll-down-command
1635;; "&" #'+elfeed-show-browse-generic
1636;; "RET" #'shr-browse-url
1637;; "w" #'elfeed-show-yank
1638;; "y" nil)
1639;; (:hook #'reading-mode)
1640;; (:option +elfeed--update-repeat (* 60 30) ; 1/2 hour
1641;; +elfeed--update-first-time 60))
1642;; (+elfeed-update-async-mode +1)
1643;; (add-hook '+elfeed-update-proceed-hook (defun non-work-hours? ()
1644;; "Return nil if during work hours, t otherwise."
1645;; (let* ((now (current-time))
1646;; (now* (decode-time now))
1647;; (work-start* (append '(0 0 8) (cdddr now*))) ; 8:00 AM
1648;; (work-end* (append '(0 0 18) (cdddr now*))) ; 6:00 PM
1649;; (work-start (encode-time work-start*))
1650;; (work-end (encode-time work-end*)))
1651;; (or (time-less-p now work-start)
1652;; (time-less-p work-end now))))))
1653
1654;; (setup (:straight elfeed-org)
1655;; (:also-load +org-capture)
1656;; (:option rmh-elfeed-org-files (list (elfeed/ "elfeed.org" t)))
1657;; (elfeed-org)
1658;; (+org-capture-templates-setf "f"
1659;; `("Feed" entry
1660;; (file+olp ,(car rmh-elfeed-org-files) "Feeds")
1661;; "* %? %^g")))
1662
1663;; (setup (:straight (elfeed-tube :host github :repo "karthink/elfeed-tube")
1664;; (or (executable-find "youtube-dl")
1665;; (executable-find "yt-dlp")))
1666;; (:straight (elfeed-tube-mpv :host github :repo "karthink/elfeed-tube"))
1667;; (:load-after elfeed)
1668;; (with-eval-after-load 'elfeed
1669;; (elfeed-tube-setup)
1670;; (:bind-into (elfeed-show-mode-map elfeed-search-mode-map)
1671;; "F" #'elfeed-tube-fetch
1672;; [remap save-buffer] #'elfeed-tube-save)
1673;; (:bind-into elfeed-show-mode-map
1674;; "C-c C-f" #'elfeed-tube-mpv-follow-mode
1675;; "C-c C-w" #'elfeed-tube-mpv-where)))
1676
1677(setup (:straight elpher)
1678 (:bind "l" #'elpher-back))
1679
1680(setup (:straight emacs-everywhere
1681 (cl-loop for prog in '("xclip" "xdotool" "xprop" "xwininfo")
1682 if (executable-find prog)
1683 return prog
1684 finally return nil)))
1685
1686(setup (:straight embark)
1687 (:require embark
1688 +embark)
1689 (:option prefix-help-command 'embark-prefix-help-command
1690 embark-keymap-prompter-key ";")
1691 (:+key "C-." #'embark-act
1692 "M-." #'embark-dwim
1693 "<f1> B" #'embark-bindings)
1694 (:with-map minibuffer-local-map
1695 (:bind "C-." #'embark-act
1696 "M-." #'embark-dwim))
1697 (:with-map embark-file-map
1698 (:bind "l" #'vlf)))
1699
1700(setup (:straight embark-consult)
1701 (:load-after consult embark)
1702 (add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode))
1703
1704(setup (:straight embrace)
1705 (dolist (mode '(LaTeX-mode org-mode ruby-mode))
1706 (add-hook (intern (format "%s-hook" mode))
1707 (intern (format "embrace-%s-hook" mode))))
1708 (:face 'embrace-help-pair-face '((t ( :inverse-video nil
1709 :inherit font-lock-keyword-face))))
1710 (:+key "C-," #'embrace-commander))
1711
1712(setup (:straight (ement :host github
1713 :repo "alphapapa/ement.el")
1714 ;; `plz' is a requirement, but isn't on an elpa.
1715 (setup (:straight (plz :host github
1716 :repo "alphapapa/plz.el"))
1717 t)))
1718
1719(setup (:straight epithet)
1720 (dolist (hook '(Info-selection-hook
1721 ;; eww-after-render-hook
1722 help-mode-hook
1723 occur-mode-hook))
1724 (add-hook hook #'epithet-rename-buffer))
1725 (if (boundp 'eww-auto-rename-buffer) ; Emacs 29
1726 (:option eww-auto-rename-buffer 'title)
1727 (add-hook 'eww-after-render-hook #'epithet-rename-buffer)))
1728
1729(setup (:straight eros)
1730 (:option eros-eval-result-prefix "; "
1731 eros-overlays-use-font-lock nil)
1732 (:hook-into emacs-lisp-mode
1733 lisp-interaction-mode))
1734
1735(setup (:straight eshell-bookmark)
1736 (add-hook 'eshell-mode-hook #'eshell-bookmark-setup))
1737
1738(setup (:straight eshell-syntax-highlighting)
1739 (:hook-into eshell-mode))
1740
1741(setup (:straight eshell-vterm
1742 :quit)
1743 (:load-after eshell)
1744 (defalias 'eshell/v 'eshell-exec-visual)
1745 (eshell-vterm-mode +1))
1746
1747(setup (:straight exec-path-from-shell
1748 (eq system-type 'gnu/linux))
1749 (require 'exec-path-from-shell)
1750 (dolist (var '("SSH_AUTH_SOCK"
1751 "SSH_AGENT_PID"
1752 "GPG_AGENT_INFO"
1753 "LANG"
1754 "LC_CTYPE"
1755 "XDG_CONFIG_HOME"
1756 "XDG_CONFIG_DIRS"
1757 "XDG_DATA_HOME"
1758 "XDG_DATA_DIRS"
1759 "XDG_CACHE_HOME"))
1760 (add-to-list 'exec-path-from-shell-variables var))
1761 (exec-path-from-shell-initialize))
1762
1763(setup (:straight expand-region)
1764 (:require expand-region +expand-region)
1765 (:option expand-region-fast-keys-enabled nil)
1766 (:+key "C-=" #'er/expand-region
1767 "C--" #'+er/contract-or-negative-argument))
1768
1769(setup (:straight fennel-mode)
1770 (with-eval-after-load 'apheleia
1771 (when-let ((fnlfmt (executable-find "fnlfmt")))
1772 (setf (alist-get 'fnlfmt apheleia-formatters) (list fnlfmt 'filepath))
1773 (setf (alist-get 'fennel-mode apheleia-mode-alist) 'fnlfmt))))
1774
1775(setup (:straight (filldent :host nil
1776 :repo "https://codeberg.org/acdw/filldent.el"))
1777 (:+key "M-q" #'filldent-unfill-toggle))
1778
1779(setup (:straight (flymake-chicken
1780 :host github
1781 :repo "chicken-contrib/flymake-chicken"))
1782 (add-hook 'scheme-mode-hook (defun +flymake-chicken-init ()
1783 (add-hook 'flymake-diagnostic-functions
1784 #'flymake-chicken-backend
1785 nil t))))
1786
1787(setup (:straight (flymake-collection :host github
1788 :repo "mohkale/flymake-collection"))
1789 (+ensure-after-init #'flymake-collection-hook-setup))
1790
1791(setup (:straight (flyspell-correct
1792 :fork (:host github :repo "duckwork/flyspell-correct"
1793 :branch "metadata-category")))
1794 (:load-after flyspell)
1795 (:also-load +flyspell-correct)
1796 (:option flyspell-correct--cr-key ";")
1797 (:bind-into flyspell
1798 "C-;" #'flyspell-correct-wrapper
1799 "<f7>" #'+flyspell-correct-buffer))
1800
1801(setup (:straight focus)
1802 (:require)
1803 (add-hook 'modus-themes-after-load-theme-hook
1804 (defun focus-update@after-modus-load ()
1805 (modus-themes-with-colors
1806 (:face 'focus-unfocused `((t ( :foreground ,fg-inactive
1807 :background ,bg-inactive
1808 :weight normal
1809 :slant normal
1810 :extend t)))))))
1811 ;; XXX: This doesn't work, because notmuch overlays shit on the buffer
1812 (setf (alist-get 'notmuch-show-mode focus-mode-to-thing)
1813 'notmuch-message)
1814 (:hook-into notmuch-show-mode))
1815
1816(setup (:straight (forge :host github :repo "magit/forge")
1817 (eq system-type 'gnu/linux))
1818 (:quit) ; XXX: Somehow missing compat-26
1819 (add-to-list 'forge-alist
1820 '("tildegit.org" "tildegit.org/api/v1" "tildegit.org"
1821 forge-gitea-repository)))
1822
1823(setup (:straight form-feed)
1824 ;; See also `page-break-lines', further down.
1825 (:face 'form-feed-line '((t (:strike-through t))))
1826 (global-form-feed-mode +1))
1827
1828(setup (:straight (frowny :host nil
1829 :repo "https://codeberg.org/acdw/frowny.el"))
1830 (:option frowny-eyes (rx (any ":=") (opt "'") (? "-")))
1831 (add-to-list 'frowny-inhibit-modes 'vterm-mode)
1832 (global-frowny-mode +1))
1833
1834;; (setup (:straight (geiser
1835;; :type git
1836;; :flavor melpa
1837;; :files ("elisp/*.el" "doc/*" "geiser-pkg.el")
1838;; :pre-build ("make" "-Cdoc" "geiser.info")
1839;; :host gitlab
1840;; :repo "emacs-geiser/geiser"))
1841;; (dolist (pkg '( geiser-chicken geiser-guile
1842;; macrostep-geiser
1843;; scheme-complete))
1844;; (straight-use-package pkg))
1845;; (:require +chicken)
1846;; (+chicken-indentation-insinuate)
1847;; (:with-mode scheme-mode
1848;; (:file-match (rx ".scm" eos)))
1849;; (setf (alist-get "\\.scm\\'" auto-insert-alist nil nil #'equal)
1850;; '(insert "#!/bin/sh\n#| -*- scheme -*-\nexec csi -s $0 \"$@\"\n|#\n"))
1851;; ;; (when-let ((scmfmt-exe (executable-find "scmfmt")))
1852;; ;; (with-eval-after-load 'apheleia
1853;; ;; (setf (alist-get 'scmfmt apheleia-formatters) (list scmfmt-exe))
1854;; ;; (setf (alist-get 'scheme-mode apheleia-mode-alist) 'scmfmt)))
1855;; )
1856
1857(setup (:straight (ghelp :repo "https://github.com/casouri/ghelp"))
1858 ;;; XXX: set this up!
1859 (:require))
1860
1861(setup (:straight (git-modes :host github :repo "magit/git-modes"))
1862 (:require git-modes))
1863
1864(setup (:straight god-mode
1865 :quit "I could never get the hang of this.")
1866 (setq god-mode-enable-function-key-translation nil)
1867 (:require god-mode
1868 +god-mode)
1869 (:+key "C-M-g" #'god-mode-all)
1870 (:with-mode god-local-mode
1871 (:bind "i" #'+god-mode-insert
1872 "a" nil)))
1873
1874(setup (:straight helpful)
1875 (:+key "<f1> f" #'helpful-callable
1876 "<f1> v" #'helpful-variable
1877 "<f1> k" #'helpful-key
1878 "<f1> ." #'helpful-at-point)
1879 ;; Load faster on first invocation by pre-loading a slow function
1880 ;; (see https://github.com/Wilfred/helpful/issues/236)
1881 (run-with-idle-timer 1 nil (lambda ()
1882 (require 'info-look)
1883 (info-lookup-setup-mode 'symbol 'emacs-lisp-mode))))
1884
1885(setup (:straight (hippie-completing-read :host nil
1886 :repo "https://codeberg.org/acdw/hippie-completing-read.el"))
1887 (:+key "M-/" #'hippie-completing-read))
1888
1889(setup (:straight hungry-delete)
1890 (:option hungry-delete-chars-to-skip " \t"
1891 hungry-delete-join-reluctantly nil)
1892 (+with-ensure-after-init
1893 (dolist (m '(eshell-mode
1894 nim-mode
1895 python-mode))
1896 (add-to-list 'hungry-delete-except-modes m)))
1897 (:bind-into paredit
1898 ;; I define these functions here because they really require both packages
1899 ;; to make any sense. So, would I put them in `+hungry-delete' or
1900 ;; `+paredit' ? There's no satisfactory answer.
1901 [remap paredit-backward-delete]
1902 (defun acdw/paredit-hungry-delete-backward (arg)
1903 (interactive "P")
1904 (if (looking-back "[ \t]" 1)
1905 (hungry-delete-backward (or arg 1))
1906 (paredit-backward-delete arg)))
1907 [remap paredit-forward-delete]
1908 (defun acdw/paredit-hungry-delete-forward (arg)
1909 (interactive "P")
1910 (if (looking-at "[ \t]")
1911 (hungry-delete-forward (or arg 1))
1912 (paredit-forward-delete arg))))
1913 (global-hungry-delete-mode +1))
1914
1915(setup (:straight i3wm-config-mode
1916 (executable-find "i3")))
1917
1918(setup (:straight info+)
1919 (:load-after info)
1920 (:option Info-fontify-isolated-quote-flag nil
1921 Info-breadcrumbs-in-mode-line-mode nil
1922 Info-fontify-emphasis-flag nil
1923 Info-fontify-quotations nil
1924 Info-saved-history-file (.etc "info-history"))
1925 (add-hook 'Info-mode-hook #'Info-variable-pitch-text-mode))
1926
1927(setup (:straight isearch-mb)
1928 ;; This complicatedness is an attempt to make it easier to add and
1929 ;; subtract `isearch-mb' bindings using the suggestions in the
1930 ;; project's README.
1931 (:load-after consult anzu)
1932 (:when-loaded
1933 (dolist (spec '((isearch-mb--with-buffer
1934 ("M-e" . consult-isearch)
1935 ("C-o" . loccur-isearch))
1936 (isearch-mb--after-exit
1937 ("M-%" . anzu-isearch-query-replace)
1938 ("M-s l" . consult-line))))
1939 (let ((isearch-mb-list (car spec))
1940 (isearch-mb-binds (cdr spec)))
1941 (dolist (cell isearch-mb-binds)
1942 (let ((key (car cell))
1943 (command (cdr cell)))
1944 (when (fboundp command)
1945 (add-to-list isearch-mb-list command)
1946 (define-key isearch-mb-minibuffer-map (kbd key) command)))))))
1947 (isearch-mb-mode +1))
1948
1949(setup (:straight (jabber :host nil
1950 :repo "https://codeberg.org/emacs-jabber/emacs-jabber"
1951 :files ("*.el" "*.texi"
1952 ("jabber-fallback-lib"
1953 "jabber-fallback-lib/hexrgb.el"
1954 "jabber-fallback-lib/srv.el"
1955 "jabber-fallback-lib/fsm.el")
1956 "jabber-pkg.el")
1957 :fork ( :host nil
1958 :repo "https://codeberg.org/acdw/emacs-jabber")))
1959 (:require jabber +jabber)
1960 ;; (:option +jabber-pre-prompt "~ ~ ~\n")
1961 (add-to-list 'jabber-post-connect-hooks 'jabber-enable-carbons)
1962 (:option jabber-account-list '(("acdw@hmm.st"))
1963 jabber-groupchat-buffer-format "%n"
1964 jabber-chat-buffer-format "%n"
1965 jabber-muc-private-buffer-format "%n(%g)"
1966 jabber-muc-header-line-format '("" jabber-muc-topic)
1967 jabber-activity-show-p #'ignore
1968 jabber-muc-decorate-presence-patterns
1969 '(("\\( enters the room ([^)]+)\\| has left the chatroom\\)$")
1970 ("." . jabber-muc-presence-dim))
1971 jabber-muc-colorize-foreign nil ; doesn't match my color theme
1972 jabber-groupchat-prompt-format "[%t] %n> "
1973 jabber-chat-local-prompt-format "[%t] %n> "
1974 jabber-chat-foreign-prompt-format "[%t] %n> "
1975 ;; jabber-chat-foreign-prompt-format
1976 ;; (concat +jabber-pre-prompt
1977 ;; "%n\n"
1978 ;; (make-string +jabber-ws-prefix
1979 ;; ?\ ))
1980 ;; jabber-chat-local-prompt-format
1981 ;; (concat +jabber-pre-prompt
1982 ;; "%n\n"
1983 ;; (make-string +jabber-ws-prefix
1984 ;; ?\ ))
1985 ;; jabber-groupchat-prompt-format
1986 ;; (concat +jabber-pre-prompt
1987 ;; "%n\n"
1988 ;; (make-string +jabber-ws-prefix
1989 ;; ?\ ))
1990 jabber-auto-reconnect t)
1991 (add-hook 'modus-themes-after-load-theme-hook
1992 (defun jabber-chat@after-modus-themes-load ()
1993 (modus-themes-with-colors
1994 (:face 'jabber-chat-prompt-foreign `((t (:foreground ,red)))
1995 'jabber-chat-prompt-local `((t (:foreground ,blue)))
1996 'jabber-chat-prompt-system `((t (:foreground ,green)))))
1997 (setq jabber-muc-nick-value (pcase (frame--current-backround-mode (selected-frame))
1998 ('light 0.5)
1999 ('dark 1.0)))
2000 (+mapc-some-buffers #'+jabber-colors-update
2001 (lambda () (derived-mode-p 'jabber-chat-mode
2002 'jabber-roster-mode
2003 'jabber-activity-mode
2004 'jabber-browse-mode)))))
2005 (dolist (mode '(jabber-chat-mode
2006 jabber-browse-mode
2007 jabber-roster-mode
2008 jabber-console-mode))
2009 (let ((hook (intern (format "%s-hook" mode))))
2010 (add-hook hook #'visual-fill-column-mode)
2011 (add-hook hook (defun +electric-pair-disable-local-mode () (electric-pair-local-mode -1)))
2012 ;; (add-hook hook (lambda () (setq-local wrap-prefix " ")))
2013 ))
2014 (with-eval-after-load 'tracking
2015 (add-to-list 'tracking-ignored-buffers "discuss@conference.soprani.ca"))
2016 (:with-mode jabber-chat-mode
2017 (:local-set +modeline-position-function (lambda ()
2018 (cond
2019 ((string-match-p "hmm@" (buffer-name))
2020 "🤔 ")))
2021 file-percentage-mode nil
2022 ;; wrap-prefix (make-string +jabber-ws-prefix ?\ )
2023 comment-start nil)
2024 (:bind "C-c C-t" #'jabber-muc-set-topic))
2025 (:+leader "C-j" jabber-global-keymap)
2026 (advice-add 'jabber-activity-add :after #'+jabber-tracking-add)
2027 (advice-add 'jabber-activity-add-muc :after #'+jabber-tracking-add-muc)
2028 ;;; Alerting hooks --- remove echo messages
2029 (remove-hook 'jabber-alert-muc-hooks 'jabber-muc-echo)
2030 (remove-hook 'jabber-alert-presence-hooks 'jabber-presence-echo))
2031
2032(setup (:straight (keepassxc-shim :host nil
2033 :repo "https://codeberg.org/acdw/keepassxc-shim.el"))
2034 (keepassxc-shim-activate))
2035
2036(setup (:straight keychain-environment
2037 (executable-find "keychain"))
2038 (keychain-refresh-environment))
2039
2040(setup (:straight lacarte)
2041 (:+key "<f10>" #'lacarte-execute-menu-command))
2042
2043(setup (:straight (lin :host nil
2044 :repo "https://git.sr.ht/~protesilaos/lin"))
2045 (:require)
2046 (lin-global-mode +1))
2047
2048(setup (:straight link-hint)
2049 (:require +link-hint)
2050 (+link-hint-open-secondary-setup)
2051 (+link-hint-open-chrome-setup)
2052 (:option link-hint-avy-style 'at-full
2053 link-hint-avy-all-windows t)
2054 (:+key "M-l" +link-hint-map)
2055 (:with-map +link-hint-map
2056 (:bind "M-l" #'+link-hint-open-link "l" #'+link-hint-open-link
2057 "M-o" #'+link-hint-open-secondary "o" #'+link-hint-open-secondary
2058 "M-m" #'link-hint-open-multiple-links "m" #'link-hint-open-multiple-links
2059 "M-w" #'link-hint-copy-link "w" #'link-hint-copy-link
2060 "M-c" #'+link-hint-open-chrome "c" #'+link-hint-open-chrome)))
2061
2062(setup (:straight lua-mode)
2063 (:file-match (rx ".lua" eos)))
2064
2065(setup (:straight (machine
2066 :host nil
2067 :repo "https://codeberg.org/acdw/machine.el"))
2068 (+with-ensure-after-init ; So that they override anything here.
2069 ;; Emoji fonts
2070 (let ((ffl (font-family-list))
2071 (emoji-fonts '("Noto Color Emoji"
2072 "Noto Emoji"
2073 "Segoe UI Emoji"
2074 "Apple Color Emoji"
2075 "FreeSans"
2076 "FreeMono"
2077 "FreeSerif"
2078 "Unifont"
2079 "Symbola")))
2080 (dolist (font emoji-fonts)
2081 (when (member font ffl)
2082 (set-fontset-font t 'symbol (font-spec :family font) nil :append))))
2083 (machine-settings-load)))
2084
2085(setup (:straight macrostep)
2086 (:require macrostep)
2087 (dolist (m '(emacs-lisp-mode-map
2088 lisp-interaction-mode-map))
2089 (define-key (symbol-value m) (kbd "C-c e") #'macrostep-expand)))
2090
2091(setup (:straight (magit :host github :repo "magit/magit"
2092 :build (:not compile))
2093 (:straight (transient :host github :repo "magit/transient"
2094 :build (:not compile))))
2095 (autoload 'transient--with-suspended-override "transient"))
2096
2097(setup (:straight marginalia)
2098 (marginalia-mode +1))
2099
2100(setup (:straight markdown-mode)
2101 (:option markdown-hide-markup nil)
2102 (:file-match (rx (or ".md" ".markdown" ".mdown") eos))
2103 (with-eval-after-load 'visual-fill-column
2104 (:hook #'visual-fill-column-mode))
2105 (with-eval-after-load 'apheleia
2106 (when-let ((mdfmt-exe (executable-find "markdownfmt")))
2107 (setf (alist-get 'markdownfmt apheleia-formatters) (list mdfmt-exe))
2108 (setf (alist-get 'markdown-mode apheleia-mode-alist) 'markdownfmt)
2109 (setf (alist-get 'gfm-mode apheleia-mode-alist) 'markdownfmt))))
2110
2111(setup (:straight (mastodon
2112 :fork (:host nil :repo "https://codeberg.org/acdw/mastodon.el")))
2113 (:option mastodon-instance-url "https://tiny.tilde.website"
2114 mastodon-active-user "acdw"
2115 mastodon-client--token-file (.etc "mastodon.plstore")
2116 mastodon-auth-source-file (seq-some (lambda (i)
2117 (when (and (stringp i)
2118 (file-exists-p i))
2119 i))
2120 auth-sources)
2121 mastodon-tl--show-avatars t
2122 mastodon-tl--enable-proportional-fonts nil)
2123 (:hook #'mastodon-async-mode
2124 #'variable-pitch-mode
2125 #'hl-line-mode
2126 #'lin-mode))
2127
2128(setup (:straight minions)
2129 (minions-mode +1))
2130
2131(setup (:straight (mode-line-bell
2132 :host github :repo "purcell/mode-line-bell"
2133 :fork (:host github :repo "duckwork/mode-line-bell"
2134 :branch "remap-face")))
2135 ;; This is still, annoyingly, not quite working right.
2136 (:face 'mode-line-bell '((t (:inherit mode-line-highlight))))
2137 (:option mode-line-bell-flash-time 0.1)
2138 (mode-line-bell-mode +1))
2139
2140(setup (:straight (modus-themes
2141 :host nil
2142 :repo "https://git.sr.ht/~protesilaos/modus-themes"))
2143 (require 'modus-themes (.etc "straight/build/modus-themes/modus-themes"))
2144 (:option modus-themes-mixed-fonts t
2145 modus-themes-bold-constructs t
2146 modus-themes-italic-constructs t
2147 modus-themes-headings '((1 monochrome bold overline)
2148 (2 monochrome bold)
2149 (3 monochrome italic)
2150 (t monochrome)))
2151 (dotimes (facen-1 8)
2152 (let ((facen (1+ facen-1)))
2153 (custom-set-faces
2154 `(,(intern (format "org-level-%s" facen))
2155 ((t :inherit
2156 (,(intern (format "modus-themes-heading-%s" facen))
2157 fixed-pitch))
2158 :now)))))
2159 (:face 'modus-themes-tab-active '((t ( :bold nil)))
2160 'modus-themes-tab-inactive '((t ( :italic t))))
2161
2162 (define-advice modus-themes--current-theme (:around (fn &rest r))
2163 "Fix a \"nil is not a Modus theme\" error."
2164 (or (apply fn r)
2165 'modus-operandi))
2166
2167 ;; This needs to be after the themes are loaded, I think.
2168 (add-hook 'modus-themes-after-load-theme-hook
2169 (defun +modus-themes-mostly-monochrome ()
2170 "Set up mdous-themes to be mostly monochrome."
2171 ;; Major mode in the mode-line
2172 (modus-themes-with-colors
2173 (custom-set-faces
2174 `(font-lock-builtin-face
2175 ((,class :inherit modus-themes-bold
2176 :foreground unspecified)))
2177 `(font-lock-comment-face
2178 ((,class :inherit default
2179 :slant normal
2180 :height 1.0
2181 :foreground ,fg-comment-yellow)))
2182 `(font-lock-comment-delimiter-face
2183 ((,class :inherit fixed-pitch
2184 :foreground ,fg-comment-yellow)))
2185 `(font-lock-constant-face
2186 ((,class :inherit underline
2187 :foreground unspecified)))
2188 `(font-lock-doc-face
2189 ((,class :inherit modus-themes-slant
2190 :foreground ,fg-docstring)))
2191 `(font-lock-function-name-face
2192 ((,class :foreground unspecified
2193 :slant italic)))
2194 `(font-lock-keyword-face
2195 ((,class :inherit modus-themes-bold
2196 :foreground unspecified)))
2197 `(font-lock-negation-char-face
2198 ((,class :inherit modus-themes-bold
2199 :foreground unspecified)))
2200 `(font-lock-preprocessor-face
2201 ((,class :foreground unspecified)))
2202 `(font-lock-regexp-grouping-backslash
2203 ((,class :foreground ,fg-escape-char-backslash)))
2204 `(font-lock-regexp-grouping-construct
2205 ((,class :foreground ,fg-escape-char-construct)))
2206 `(font-lock-string-face
2207 ((,class :foreground ,fg-special-warm)))
2208 `(font-lock-type-face
2209 ((,class :inherit modus-themes-bold
2210 :foreground unspecified)))
2211 `(font-lock-variable-name-face
2212 ((,class :foreground unspecified)))
2213 `(font-lock-warning-face
2214 ((,class :inherit modus-themes-bold
2215 :foreground ,red-nuanced-fg)))
2216 `(font-lock-todo-face
2217 ((,class :inherit font-lock-comment-face
2218 :foreground ,fg-header
2219 :background ,yellow-intense-bg)))
2220 ;; `(mode-line
2221 ;; ((,class :height 100)))
2222 ;; `(mode-line-inactive
2223 ;; ((,class :height 100)))
2224 ;; `(tab-bar
2225 ;; ((,class :height 100)))
2226 ))))
2227
2228 (require 'dawn)
2229 (dawn-schedule #'modus-themes-load-operandi
2230 #'modus-themes-load-vivendi))
2231
2232(setup (:straight mwim)
2233 (:require +mwim)
2234 (:option +mwim-passthrough-modes '(comint-mode
2235 eshell-mode
2236 vterm-mode
2237 crossword-mode
2238 geiser-repl-mode))
2239 (:global "C-a" #'mwim-beginning
2240 "C-e" #'mwim-end))
2241
2242(setup (:straight native-complete)
2243 (with-eval-after-load 'shell
2244 (native-complete-setup-bash))
2245 (:with-hook shell-mode-hook
2246 (:local-set completion-at-point-functions
2247 (cons 'native-complete-at-point
2248 completion-at-point-functions))))
2249
2250(setup (:straight notmuch-bookmarks)
2251 (:load-after notmuch)
2252 (:when-loaded
2253 (notmuch-bookmarks-mode +1)))
2254
2255(setup (:straight notmuch-labeler
2256 :quit "Buggy")
2257 (:load-after notmuch))
2258
2259(setup (:straight (notmuch-tags
2260 :repo "https://git.madhouse-project.org/algernon/notmuch-tags.el"
2261 :fork (:repo "https://codeberg.org/acdw/notmuch-tags.el"))))
2262
2263(setup (:straight nov)
2264 (:hook #'visual-fill-column-mode)
2265 (:file-match (rx ".epub" eos)))
2266
2267(setup (:straight (nyan-mode
2268 :fork (:repo "duckwork/nyan-mode")))
2269 (:require nyan-mode +nyan-mode)
2270 (with-eval-after-load 'modus-themes
2271 (add-hook 'modus-themes-after-load-theme-hook
2272 (defun +nyan-modus-update-colors ()
2273 (modus-themes-with-colors
2274 (set-face-attribute '+nyan-mode-line nil
2275 :background bg-special-warm))))
2276 (+nyan-modus-update-colors))
2277 (+nyan-mode +1))
2278
2279(setup (:straight ol-notmuch))
2280
2281(setup (:straight orderless)
2282 (:require +orderless)
2283 (:option completion-styles '(substring orderless basic)
2284 completion-category-defaults nil
2285 completion-category-overrides
2286 '((file (styles basic partial-completion))
2287 (command (styles +orderless-with-initialism))
2288 (variable (styles +orderless-with-initialism))
2289 (symbol (styles +orderless-with-initialism)))
2290 orderless-component-separator #'orderless-escapable-split-on-space
2291 orderless-style-dispatchers '(+orderless-dispatch)))
2292
2293(setup (:straight org-appear)
2294 (:option org-appear-autoemphasis t
2295 org-appear-autoentities t
2296 org-appear-autokeywords t
2297 org-appear-autolinks nil
2298 org-appear-autosubmarkers t
2299 org-appear-delay 0)
2300 (:hook-into org-mode))
2301
2302(setup (:straight org-download)
2303 (:require)
2304 (:option org-download-method 'attach
2305 org-download-backend (cond ((executable-find "curl") 'curl)
2306 ((executable-find "wget") 'wget)
2307 (:else 'url-retrieve)))
2308 (add-hook 'dired-mode-hook 'org-download-enable))
2309
2310(setup (:straight (org-drawer-list
2311 :host github
2312 :repo "d12frosted/org-drawer-list"))
2313 (:load-after org)
2314 (:also-load +org-drawer-list))
2315
2316(setup (:straight org-mime)
2317 (:option org-mime-export-ascii 'utf-8)
2318 (add-hook 'message-mode-hook
2319 (defun org-mime-setup@message-mode ()
2320 (local-set-key (kbd "C-c M-o") 'org-mime-htmlize)))
2321 (add-hook 'org-mode-hook
2322 (defun org-mime-setup@org-mode ()
2323 (local-set-key (kbd "C-c M-o") 'org-mime-org-buffer-htmlize))))
2324
2325(setup (:straight (org-taskwise
2326 :host nil
2327 :repo "https://codeberg.org/acdw/org-taskwise.el.git"))
2328 (with-eval-after-load 'org
2329 (require 'org-taskwise)
2330 (define-key org-mode-map (kbd "C-x n t") #'org-taskwise-narrow-to-task)))
2331
2332(setup (:straight org-wc)
2333 (:load-after org simple-modeline)
2334 (:also-load +org-wc)
2335 (add-hook 'org-mode-hook #'+org-wc-mode))
2336
2337(setup (:straight orglink)
2338 (:option orglink-activate-in-modes '(text-mode prog-mode))
2339 (global-orglink-mode +1)
2340 (global-goto-address-mode -1))
2341
2342(setup (:straight package-lint))
2343
2344(setup (:straight package-lint-flymake)
2345 (add-hook 'emacs-mode-hook #'package-lint-flymake-setup)
2346 ;; Remove it from init.el files
2347 (add-hook '+init-mode-hook #'flymake-mode-off))
2348
2349(setup (:straight page-break-lines)
2350 (:option page-break-lines-char ?—)
2351 (:hook-into jabber-chat-mode))
2352
2353(setup (:straight paredit)
2354 (:also-load +paredit)
2355 (:bind "DEL" #'paredit-backward-delete
2356 "C-<backspace>" #'+paredit-backward-kill-word
2357 "C-w" (lambda (arg) (interactive "P")
2358 (+kill-word-backward-or-region arg #'paredit-backward-kill-word))
2359 "M-s" nil)
2360 (dolist (hook '(emacs-lisp-mode-hook
2361 eval-expression-minibuffer-setup-hook
2362 ielm-mode-hook
2363 lisp-interaction-mode-hook
2364 lisp-mode-hook
2365 scheme-mode-hook
2366 geiser-mode-hook
2367 geiser-repl-mode-hook
2368 fennel-mode-hook
2369 fennel-repl-mode-hook))
2370 (add-hook hook #'enable-paredit-mode))
2371 (:also-load eldoc)
2372 (eldoc-add-command #'paredit-backward-delete #'paredit-close-round))
2373
2374(setup (:straight paren-face)
2375 (:hook-into emacs-lisp-mode
2376 ielm-mode sly-repl-mode
2377 lisp-mode
2378 lisp-interaction-mode
2379 scheme-mode))
2380
2381(setup (:straight pdf-tools
2382 (or (executable-find "gcc")
2383 (executable-find "g++")))
2384 (:also-load +pdf-tools)
2385 (:with-mode pdf-view-mode
2386 (:local-set +modeline-position-function #'+pdf-view-position)
2387 (:file-match (rx ".pdf" eos)))
2388 (pdf-tools-install :no-query))
2389
2390(setup (:straight persistent-scratch)
2391 (:require)
2392 (:option persistent-scratch-save-file (sync/ "emacs/scratch")
2393 persistent-scratch-backup-directory (sync/ "emacs/scratch.d/" t)
2394 persistent-scratch-backup-file-name-format "%Y-%m-%dT%H:%M_%s")
2395 (persistent-scratch-autosave-mode +1)
2396 (+mapc-some-buffers (lambda () (persistent-scratch-mode +1))
2397 persistent-scratch-scratch-buffer-p-function))
2398
2399(setup (:straight (plancat
2400 :host nil
2401 :repo "https://codeberg.org/acdw/plancat.el"))
2402 (:option plancat-user "acdw"))
2403
2404(setup (:straight pocket-reader)
2405 (:option pocket-reader-open-url-default-function #'browse-url)
2406 (:+leader "p" #'pocket-reader
2407 "C-p" #'pocket-reader)
2408 (dolist (mode '((eww-mode-map . eww)
2409 (w3m-mode-map . w3m)
2410 (elfeed-search-mode-map . elfeed-search)
2411 (elfeed-show-mode-map . elfeed-show)))
2412 (with-eval-after-load (cdr mode)
2413 (define-key (symbol-value (car mode)) "\"" #'pocket-reader-add-link))
2414 (with-eval-after-load '+link-hint
2415 (+link-hint-pocket-add-setup)
2416 (define-key +link-hint-map "M-\"" #'+link-hint-pocket-add)
2417 (define-key +link-hint-map "\"" #'+link-hint-pocket-add))))
2418
2419(setup (:straight rainbow-mode)
2420 (:hook-into prog-mode))
2421
2422(setup (:straight (shell-command+
2423 :host nil
2424 :repo "https://git.sr.ht/~pkal/shell-command-plus"))
2425 (:option shell-command-prompt "$ ")
2426 (:bind-into dired
2427 "M-!" 'shell-command+)
2428 (:+key "M-!" #'shell-command+))
2429
2430(setup (:straight sicp))
2431
2432(setup (:straight (simple-modeline
2433 :host github :repo "gexplorer/simple-modeline"
2434 :fork (:host github :repo "duckwork/simple-modeline")))
2435 (:require +modeline)
2436 (:option +modeline-modified-icon-alist '((ephemeral . "~")
2437 (special . "*")
2438 (readonly . "=")
2439 (modified . "+")
2440 (t . "-"))
2441 +modeline-minions-icon "&"
2442 +modeline-buffer-name-max-length 0.35)
2443 ;; Segments
2444 (:option simple-modeline-segments
2445 `(( ; left
2446 +modeline-ace-window-display
2447 +modeline-modified
2448 +modeline-buffer-name
2449 +modeline-major-mode
2450 (lambda () (+modeline-vc " : "))
2451 +modeline-nyan-on-focused
2452 +modeline-anzu
2453 )
2454 ( ; right
2455 simple-modeline-segment-process
2456 (lambda ()
2457 (unless +tab-bar-misc-info-mode
2458 (+modeline-concat
2459 '(+modeline-track
2460 simple-modeline-segment-misc-info))))
2461 (lambda () (when (featurep 'dired-rsync)
2462 dired-rsync-modeline-status))
2463 ,(+modeline-concat
2464 '(+modeline-god-mode
2465 +modeline-kmacro-indicator
2466 +modeline-reading-mode
2467 +modeline-narrowed
2468 +modeline-text-scale
2469 +modeline-input-method)
2470 " ")
2471 +modeline-position
2472 +modeline-spacer
2473 )))
2474 (simple-modeline-mode +1))
2475
2476(setup (:straight slack)
2477 (:also-load +slack)
2478 (:option slack-prefer-current-team t
2479 slack-buffer-emojify t
2480 slack-thread-also-send-to-room nil
2481 slack-typing-visibility 'buffer
2482 slack-buffer-create-on-notify t
2483 slack-enable-wysiwyg t
2484 slack-file-dir (xdg-user-dir "DOWNLOAD")
2485 slack-display-team-name nil)
2486 (with-eval-after-load '+slack
2487 (+slack-register-teams))
2488 (with-eval-after-load 'alert
2489 ;; Don't notify for Slack messages
2490 (alert-add-rule :category "slack"
2491 :style 'ignore)))
2492
2493;; (setup (:straight sly
2494;; (defvar +lisp-bin (executable-find "sbcl")))
2495;; (:also-load sly-autoloads
2496;; +sly)
2497;; (:option inferior-lisp-program +lisp-bin
2498;; sly-kill-without-query-p t
2499;; sly-command-switch-to-existing-lisp t)
2500;; (:with-mode lisp-mode
2501;; (:bind "C-c C-z" #'sly-mrepl))
2502;; (:with-feature sly-mrepl
2503;; (dolist (key '("RET" "<return>"))
2504;; (:bind key #'sly-mrepl-return-at-end))
2505;; (:bind "C-c C-c" #'sly-mrepl-return)))
2506
2507(setup (:straight slime))
2508
2509(setup (:straight smartscan)
2510 (:with-map smartscan-map
2511 (:bind "M-'" nil))
2512 (:hook-into prog-mode))
2513
2514(setup (:straight (sophomore
2515 :host nil
2516 :repo "https://codeberg.org/acdw/sophomore.el"))
2517 (sophomore-enable #'narrow-to-region)
2518 (sophomore-disable ; These are mostly annoying commands
2519 #'view-hello-file
2520 #'describe-gnu-project
2521 #'suspend-frame)
2522 (sophomore-disable-with 'confirm
2523 #'save-buffers-kill-terminal)
2524 (sophomore-disable-with 'confirm-y
2525 #'+save-buffers-quit)
2526 (sophomore-mode +1))
2527
2528(setup (:straight (spongebob-case
2529 :host nil
2530 :repo "https://codeberg.org/acdw/spongebob-case.el")))
2531
2532(setup (:straight ssh-config-mode)
2533 (:file-match (rx "/.ssh/config" eos)
2534 (rx "/ssh" (? "d") "_config" eos))
2535 (:with-mode ssh-known-hosts-mode
2536 (:file-match (rx "/knownhosts" eos)))
2537 (:with-mode ssh-authorized-keys-mode
2538 (:file-match (rx "/authorized_keys" (? "2") eos))))
2539
2540;; (setup (:straight super-save)
2541;; (:option auto-save-default nil
2542;; super-save-auto-save-when-idle t
2543;; super-save-idle-duration 30
2544;; super-save-exclude '(".gpg")
2545;; super-save-remote-files nil)
2546;; (auto-save-visited-mode -1)
2547;; (super-save-mode +1))
2548
2549(setup (:straight systemd
2550 (executable-find "systemd"))
2551 (:option systemd-man-function 'woman))
2552
2553(setup (:straight (titlecase
2554 :host nil
2555 :repo "https://codeberg.org/acdw/titlecase.el"
2556 :files ("*")))
2557 (:require titlecase +titlecase)
2558 (add-to-list 'titlecase-skip-words-regexps (rx word-boundary
2559 (+ (any upper digit))
2560 word-boundary))
2561 (:with-map +casing-map
2562 (:bind "t" #'titlecase-dwim
2563 "M-t" #'titlecase-dwim
2564 "s" #'+titlecase-sentence-style-dwim
2565 "M-s" #'+titlecase-sentence-style-dwim)))
2566
2567(setup (:straight topsy)
2568 (:hook-into ;;prog-mode
2569 circe-chat-mode)
2570 (:when-loaded
2571 (:option
2572 topsy-header-line-format
2573 '(:eval
2574 (list
2575 (propertize " "
2576 'display
2577 `((space
2578 :align-to
2579 ,(unless (bound-and-true-p visual-fill-column-mode)
2580 0))))
2581 (funcall topsy-fn))))))
2582
2583(setup (:straight transpose-frame)
2584 (defvar +transpose-frame-map
2585 (let ((map (make-sparse-keymap)))
2586 (dolist (bind '(("t" . transpose-frame)
2587 ("v" . flip-frame)
2588 ("h" . flop-frame)
2589 ("r" . rotate-frame-clockwise)
2590 ("R" . rotate-frame-anticlockwise)))
2591 (define-key map (car bind) (cdr bind)))
2592 map)
2593 "Map for transposing frames.")
2594 (define-key +key-mode-map (kbd "C-x 5 t") +transpose-frame-map))
2595
2596(setup (:straight trashed)
2597 (:+leader "t" #'trashed)
2598 (:option trashed-action-confirmer #'y-or-n-p
2599 trashed-use-header-line t
2600 trashed-size-format 'human-readable))
2601
2602(setup (:straight undo-fu) (:quit "Trying native undo functionality")
2603 (:option undo-fu-allow-undo-in-region t)
2604 (:global "C-/" #'undo-fu-only-undo
2605 "C-?" #'undo-fu-only-redo))
2606
2607(setup (:straight undo-fu-session)
2608 (:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'"
2609 "/git-rebase-todo\\'")
2610 undo-fu-session-directory (.etc "undo/" t)
2611 undo-fu-session-compression (cond
2612 ((executable-find "gzip") 'gz)
2613 ((executable-find "bzip2") 'bz2)
2614 ((executable-find "xz") 'xz)
2615 (t nil)))
2616 (global-undo-fu-session-mode +1))
2617
2618(setup (:straight (undo-hl
2619 :host github
2620 :repo "casouri/undo-hl"))
2621 (:require)
2622 (:face 'undo-hl-delete '((t :strikethrough t))
2623 'undo-hl-insert '((t :underline t)))
2624 (:hook-into text-mode prog-mode))
2625
2626(setup (:straight valign
2627 :quit "Doesn't work with narrowed tables.")
2628 (:option valign-fancy-bar t)
2629 (:hook-into org-mode
2630 markdown-mode))
2631
2632(setup (:straight (vertico
2633 :host github
2634 :repo "minad/vertico"
2635 :files ("*" "extensions/*"
2636 (:exclude ".git"))))
2637 (:require vertico +vertico)
2638 (:option resize-mini-windows 'grow-only
2639 vertico-count-format nil
2640 vertico-cycle t)
2641 (advice-add #'vertico-next :around #'+vertico-ding-wrap)
2642 (when (boundp 'native-comp-deferred-compilation-deny-list)
2643 (add-to-list 'native-comp-deferred-compilation-deny-list "vertico"))
2644 (vertico-mode +1)
2645 ;; Extensions
2646 (:also-load vertico-directory
2647 vertico-mouse
2648 vertico-quick)
2649 (vertico-mouse-mode +1)
2650 (:with-map vertico-map
2651 (:bind "RET" #'vertico-directory-enter
2652 "DEL" #'vertico-directory-delete-char
2653 "M-DEL" #'vertico-directory-delete-word
2654 "TAB" #'+vertico-widen-or-complete
2655 "M-j" #'vertico-quick-insert))
2656 (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy))
2657
2658(setup (:straight visual-fill-column)
2659 (:option visual-fill-column-center-text t
2660 (append reading-modes) '(visual-fill-column-mode . +1))
2661 (:hook #'visual-line-mode)
2662 (:hook-into org-mode)
2663 (advice-add #'text-scale-adjust :after #'visual-fill-column-adjust)
2664 (:global [f12] #'visual-fill-column-mode))
2665
2666(setup (:straight vlf)
2667 (:require vlf-setup))
2668
2669(setup (:straight vterm
2670 (and module-file-suffix
2671 (executable-find "cmake")))
2672 (:also-load +vterm)
2673 (:option vterm-always-compile-module t
2674 vterm-buffer-name-string "vterm: %s"
2675 vterm-max-scrollback 100000 ; max allowed by vterm-module.h
2676 )
2677 (advice-add 'counsel-yank-pop-action :around
2678 #'+vterm-counsel-yank-pop-action))
2679
2680(setup (:straight (vundo
2681 :host github
2682 :repo "casouri/vundo")))
2683
2684(setup (:straight web-mode)
2685 (:file-match (rx "." (or "htm" "html" "phtml" "tpl.php"
2686 "asp" "gsp" "jsp" "ascx" "aspx"
2687 "erb" "mustache" "djhtml")
2688 eos))
2689 (with-eval-after-load 'apheleia
2690 (setf (alist-get 'web-mode apheleia-mode-alist)
2691 'prettier)))
2692
2693(setup (:straight whitespace-cleanup-mode)
2694 (:option whitespace-cleanup-mode-preserve-point t
2695 whitespace-cleanup-mode-only-if-initially-clean nil)
2696 (global-whitespace-cleanup-mode +1))
2697
2698(setup (:straight wrap-region)
2699 (:require wrap-region)
2700 (wrap-region-add-wrappers
2701 '(("*" "*" nil org-mode)
2702 ("~" "~" nil org-mode)
2703 ("/" "/" nil org-mode)
2704 ("=" "=" nil org-mode)
2705 ("+" "+" nil org-mode)
2706 ("_" "_" nil org-mode)
2707 ("$" "$" nil (org-mode latex-mode))))
2708 (:hook-into org-mode
2709 latex-mode))
2710
2711(setup (:straight xkcd)
2712 (:also-load +xkcd)
2713 (:hook #'visual-fill-column-mode))
2714
2715(setup (:straight xr))
2716
2717(setup (:straight yaml-mode)
2718 (:file-match (rx "." (or "yml" "yaml") eos)))
2719
2720(setup (:straight yaoddmuse))
2721
2722(setup (:straight yasnippet)
2723 (:option yas-snippet-dirs (list
2724 (expand-file-name "snippets" user-emacs-directory)
2725 (sync/ "emacs/snippets" t)))
2726 (yas-global-mode +1))
2727
2728(setup (:straight (ytdious
2729 :host github :repo "spiderbit/ytdious"
2730 :fork (:host github :repo "duckwork/ytdious")))
2731 (:also-load +ytdious)
2732 (:option ytdious-invidious-api-url (if +invidious-host
2733 (concat "https://" +invidious-host)
2734 "https://invidious.snopyta.org"))
2735 (:bind "y" #'+ytdious-watch))
2736
2737(setup (:straight zoom-frm)
2738 (:+key "M-+" #'zoom-frm-in
2739 "M-_" #'zoom-frm-out))
2740
2741(setup (:straight zzz-to-char)
2742 (:require +zzz-to-char)
2743 (:option zzz-to-char-reach (+bytes 1 :kib))
2744 (:global "M-z" #'+zzz-to-char))