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