diff options
Diffstat (limited to 'init.el')
-rw-r--r-- | init.el | 2900 |
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)) | ||