diff options
-rw-r--r-- | init.el | 1782 | ||||
-rw-r--r-- | lisp/acdw.el | 21 |
2 files changed, 915 insertions, 888 deletions
diff --git a/init.el b/init.el index 4a4c57c..7c40722 100644 --- a/init.el +++ b/init.el | |||
@@ -20,10 +20,50 @@ | |||
20 | 20 | ||
21 | ;; NOTE that some of the names in `setup' forms are arbitrary. | 21 | ;; NOTE that some of the names in `setup' forms are arbitrary. |
22 | 22 | ||
23 | (setup (:straight (0x0 | 23 | (setup (:require auth-source) |
24 | :host gitlab | 24 | (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg"))) |
25 | :repo "willvaughn/emacs-0x0")) | 25 | |
26 | (:option 0x0-default-server 'ttm)) | 26 | (setup (:require gforth) |
27 | (:autoload forth-mode | ||
28 | forth-block-mode) | ||
29 | (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode)) | ||
30 | (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))) | ||
31 | |||
32 | (setup (:require goto-addr) | ||
33 | (if (fboundp #'global-goto-address-mode) | ||
34 | (global-goto-address-mode) | ||
35 | (add-hook 'after-change-major-mode-hook #'goto-address-mode))) | ||
36 | |||
37 | (setup (:require recentf) | ||
38 | (:option recentf-save-file (acdw/dir "recentf.el") | ||
39 | recentf-max-menu-items 100 | ||
40 | recentf-max-saved-items nil | ||
41 | recentf-auto-cleanup 'mode | ||
42 | (append recentf-exclude) (acdw/dir)) | ||
43 | |||
44 | (:advise dired-rename-file :after #'rjs/recentf-rename-notify) | ||
45 | |||
46 | (recentf-mode +1)) | ||
47 | |||
48 | (setup (:require savehist) | ||
49 | (:option history-length t | ||
50 | history-delete-duplicates t | ||
51 | savehist-autosave-interval 60 | ||
52 | savehist-file (acdw/dir "savehist.el")) | ||
53 | |||
54 | (dolist (var '(extended-command-history | ||
55 | global-mark-ring | ||
56 | kill-ring | ||
57 | regexp-search-ring | ||
58 | search-ring | ||
59 | mark-ring)) | ||
60 | (:option (append savehist-additional-variables) var)) | ||
61 | |||
62 | (savehist-mode +1)) | ||
63 | |||
64 | (setup (:require server) | ||
65 | (unless (server-running-p) | ||
66 | (server-start))) | ||
27 | 67 | ||
28 | (setup Info | 68 | (setup Info |
29 | (:hook #'variable-pitch-mode | 69 | (:hook #'variable-pitch-mode |
@@ -51,79 +91,45 @@ | |||
51 | (defun acdw/sort-setups () | 91 | (defun acdw/sort-setups () |
52 | "Sort `setup' forms in the current buffer. | 92 | "Sort `setup' forms in the current buffer. |
53 | Actually sorts all forms, but based on the logic of `setup'. | 93 | Actually sorts all forms, but based on the logic of `setup'. |
54 | AKA, DO NOT USE THIS FUNCTION!!!" | 94 | In short, DO NOT USE THIS FUNCTION!!!" |
55 | (save-excursion | 95 | (save-excursion |
56 | (sort-sexps (point-min) (point-max) | 96 | (sort-sexps |
57 | (lambda (sexp) | 97 | (point-min) (point-max) |
58 | (let ((name (cadr sexp))) | 98 | (lambda (sexp) |
59 | (symbol-name (if (listp name) ; this is /terrible/! | 99 | (format "%S" (cadr sexp))) |
60 | (if (keywordp (car name)) | 100 | (lambda (s1 s2) ; oh god, this is worse. |
61 | (let ((feature (cadr name))) | 101 | (let* ((s1 (cdr s1)) (s2 (cdr s2)) ; for the strings themselves |
62 | (if (listp feature) | 102 | (s1-require (string-match ":require" s1)) |
63 | (car feature) | 103 | (s2-require (string-match ":require" s2)) |
64 | feature)) | 104 | (s1-straight (string-match ":straight" s1)) |
65 | (car name)) | 105 | (s2-straight (string-match ":straight" s2)) |
66 | name)))))))) | 106 | (s1-bare (not (or s1-require s1-straight))) |
67 | 107 | (s2-bare (not (or s2-require s2-straight)))) | |
68 | (setup (:straight-if affe | 108 | (cond |
69 | (and (or (executable-find "fd") | 109 | ;; if both are the same, sort regular style |
70 | (executable-find "find")) | 110 | ((or (and s1-require s2-require) |
71 | (executable-find "rg"))) | 111 | (and s1-bare s2-bare)) |
72 | ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find' | 112 | (string< s1 s2)) |
73 | (:option affe-regexp-compiler | 113 | ((and s1-straight s2-straight) |
74 | (defun affe-orderless-regexp-compiler (input _type) | 114 | (let* ((r (rx ":straight" (? "-if") (* space) (? "("))) |
75 | (setq input (orderless-pattern-compiler input)) | 115 | (s1 (replace-regexp-in-string r "" s1)) |
76 | (cons input (lambda (str) (orderless--highlight input str)))))) | 116 | (s2 (replace-regexp-in-string r "" s2))) |
77 | 117 | (message "'%S' '%S'" s1 s2) | |
78 | (setup (:straight-if ahk-mode | 118 | (string< s1 s2))) |
79 | (acdw/system :work))) | 119 | ;; requires should go first |
80 | 120 | ((and s1-require (not s2-require)) t) | |
81 | (setup (:straight alert) | 121 | ((and (not s1-require) s2-require) nil) |
82 | (:option alert-default-style (acdw/system | 122 | ;; straights should go last |
83 | (:home 'libnotify) | 123 | ((and s1-straight (not s2-straight)) nil) |
84 | (_ 'message)))) | 124 | ((and (not s1-straight) s2-straight) t) |
85 | 125 | ;; else, just sort em. | |
86 | (setup (:straight (apheleia | 126 | (t (string< s1 s2))))))))) |
87 | :host github | ||
88 | :repo "raxod502/apheleia")) | ||
89 | |||
90 | (apheleia-global-mode +1) | ||
91 | |||
92 | ;; Use a dumb formatter on modes that `apheleia' doesn't work for. | ||
93 | (add-hook 'before-save-hook | ||
94 | (defun before-save@dumb-auto-format () | ||
95 | (setq stupid-modes '(makefile-mode | ||
96 | org-mode)) | ||
97 | ;; If there's no apheleia formatter for the mode, just indent the | ||
98 | ;; buffer. | ||
99 | (unless (or (apply #'derived-mode-p stupid-modes) | ||
100 | (and (fboundp 'apheleia--get-formatter-command) | ||
101 | (apheleia--get-formatter-command))) | ||
102 | (indent-region (point-min) (point-max)))))) | ||
103 | |||
104 | (setup (:straight async) | ||
105 | (dired-async-mode +1) | ||
106 | |||
107 | (:with-feature dired | ||
108 | (:hook (defun dired@disable-dired-async-mode-line () | ||
109 | (autoload 'dired-async--modeline-mode "dired-async" nil t) | ||
110 | (dired-async--modeline-mode -1))))) | ||
111 | |||
112 | (setup (:require auth-source) | ||
113 | (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg"))) | ||
114 | 127 | ||
115 | (setup autorevert | 128 | (setup autorevert |
116 | (:option global-auto-revert-non-file-buffers t | 129 | (:option global-auto-revert-non-file-buffers t |
117 | auto-revert-verbose nil) | 130 | auto-revert-verbose nil) |
118 | (global-auto-revert-mode +1)) | 131 | (global-auto-revert-mode +1)) |
119 | 132 | ||
120 | (setup (:straight avy) | ||
121 | (:global "C-'" #'avy-goto-char-timer | ||
122 | "C-c C-j" #'avy-resume) | ||
123 | |||
124 | (:with-feature isearch | ||
125 | (:bind "C-'" #'avy-isearch))) | ||
126 | |||
127 | (setup browse-url | 133 | (setup browse-url |
128 | (:require acdw-browse-url) | 134 | (:require acdw-browse-url) |
129 | 135 | ||
@@ -186,6 +192,829 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
186 | (setup calendar | 192 | (setup calendar |
187 | (:option calendar-week-start-day 1)) | 193 | (:option calendar-week-start-day 1)) |
188 | 194 | ||
195 | (setup completion | ||
196 | (:option completion-ignore-case t | ||
197 | read-buffer-completion-ignore-case t | ||
198 | completion-styles '(substring partial-completion) | ||
199 | completion-category-defaults nil | ||
200 | completion-category-overrides | ||
201 | '((file (styles . (partial-completion))))) | ||
202 | |||
203 | (:global "M-/" #'hippie-expand)) | ||
204 | |||
205 | (setup cursor | ||
206 | (:option cursor-type 'bar | ||
207 | cursor-in-non-selected-windows 'hollow | ||
208 | blink-cursor-blinks 1) | ||
209 | (blink-cursor-mode +1)) | ||
210 | |||
211 | (setup cus-edit | ||
212 | (:option custom-file null-device ; don't store customizations | ||
213 | custom-magic-show nil | ||
214 | custom-magic-show-button t | ||
215 | custom-raised-buttons nil | ||
216 | custom-unlispify-tag-names nil | ||
217 | custom-variable-default-form 'lisp) | ||
218 | |||
219 | ;; `Custom-mode-hook' fires /before/ the widgets are built, so I have to | ||
220 | ;; install advice after the widgets are made. | ||
221 | (:advise custom-buffer-create :after | ||
222 | (defun custom-buffer@expand-widgets (&rest _) | ||
223 | "Expand descriptions in `Custom-mode' buffers." | ||
224 | (interactive) | ||
225 | ;; "More/Hide" widgets (thanks alphapapa!) | ||
226 | (widget-map-buttons (lambda (widget _) | ||
227 | (pcase (widget-get widget :off) | ||
228 | ("More" (widget-apply-action widget))) | ||
229 | nil)) | ||
230 | ;; "Show Value" widgets (the little triangles) | ||
231 | (widget-map-buttons (lambda (widget _) | ||
232 | (pcase (widget-get widget :off) | ||
233 | ("Show Value" | ||
234 | (widget-apply-action widget))) | ||
235 | nil)))) | ||
236 | |||
237 | (:with-mode Custom-mode | ||
238 | (:local-set imenu-generic-expression ; thanks u/oantolin! | ||
239 | '(("Faces" (rx (seq bol | ||
240 | (or "Show" "Hide") " " | ||
241 | (group (zero-or-more nonl)) | ||
242 | " face: [sample]")) | ||
243 | 1) | ||
244 | ("Variables" (rx (seq bol | ||
245 | (or "Show Value" "Hide") " " | ||
246 | (group (zero-or-more | ||
247 | (not (any "\n:")))))) | ||
248 | 1))))) | ||
249 | |||
250 | (setup debugger | ||
251 | (:hook visual-line-mode)) | ||
252 | |||
253 | (setup dired | ||
254 | (:also-load dired-x) | ||
255 | (:straight dired-subtree | ||
256 | dired-collapse | ||
257 | dired-git-info) | ||
258 | |||
259 | (:option dired-recursive-copies 'always | ||
260 | dired-recursive-deletes 'always | ||
261 | delete-by-moving-to-trash t | ||
262 | dired-listing-switches "-Al" | ||
263 | ls-lisp-dirs-first t | ||
264 | dired-ls-F-marks-symlinks t | ||
265 | dired-no-confirm '(byte-compile | ||
266 | chgrp chmod chown copy | ||
267 | hardlink load move | ||
268 | shell touch symlink) | ||
269 | dired-dwim-target t) | ||
270 | |||
271 | (:bind "TAB" #'dired-subtree-cycle | ||
272 | "i" #'dired-subtree-toggle | ||
273 | ")" #'dired-git-info-mode) | ||
274 | |||
275 | (:hook dired-collapse-mode | ||
276 | dired-hide-details-mode | ||
277 | hl-line-mode) | ||
278 | |||
279 | (:global "C-x C-j" #'dired-jump) | ||
280 | |||
281 | (with-eval-after-load 'dired | ||
282 | (acdw/system | ||
283 | (:work (:straight w32-browser) | ||
284 | (autoload #'dired-w32-browser "w32-browser" nil t) | ||
285 | (:bind "RET" #'dired-w32-browser)) | ||
286 | (:home (:straight dired-open) | ||
287 | (autoload #'dired-find-alternate-file "dired-open" nil t) | ||
288 | (:bind "RET" #'dired-find-alternate-file))))) | ||
289 | |||
290 | (setup disabled | ||
291 | ;; While this stuff is defined in novice.el, I'm using 'disabled' as the name | ||
292 | ;; for easy finding. | ||
293 | |||
294 | ;; Enable all disabled commands. | ||
295 | ;; This is an option, but I'm going to try /enabling/ just the ones that I | ||
296 | ;; use instead. | ||
297 | ;; (mapatoms (lambda (symbol) | ||
298 | ;; (when (get symbol 'disabled) | ||
299 | ;; (put symbol 'disabled nil)))) | ||
300 | |||
301 | ;; Enable /some/ disabled commands | ||
302 | (dolist (enable-sym '(narrow-to-region | ||
303 | dired-find-alternate-file | ||
304 | narrow-to-page)) | ||
305 | (put enable-sym 'disabled nil)) | ||
306 | |||
307 | ;; Now, disable symbols as I wish. | ||
308 | (dolist (disable-sym '(view-hello-file | ||
309 | suspend-frame | ||
310 | scroll-left | ||
311 | scroll-right | ||
312 | comment-set-column | ||
313 | set-fill-column)) | ||
314 | (put disable-sym 'disabled t)) | ||
315 | |||
316 | ;; And set the disabled function to something better than the default. | ||
317 | ;; Now, I can run any disabled command, but I have to use M-x to do it. | ||
318 | (setq disabled-command-function | ||
319 | (defun acdw/disabled-command-function (&optional cmd keys) | ||
320 | (let ((cmd (or cmd this-command)) | ||
321 | (keys (or keys (this-command-keys)))) | ||
322 | ;; this logic stolen from original `disabled-command-function' | ||
323 | (if (or (eq (aref keys 0) (if (stringp keys) | ||
324 | (aref "\M-x" 0) | ||
325 | ?\M-x)) | ||
326 | (and (>= (length keys) 2) | ||
327 | (eq (aref keys 0) meta-prefix-char) | ||
328 | (eq (aref keys 1) ?x))) | ||
329 | ;; it's been run as an M-x command, we want to do it | ||
330 | (call-interactively cmd) | ||
331 | ;; else, tell the user it's disabled. | ||
332 | (message (substitute-command-keys | ||
333 | (concat "Command `%s' has been disabled. " | ||
334 | "Run with \\[execute-extended-command].")) | ||
335 | cmd)))))) | ||
336 | |||
337 | (setup ediff | ||
338 | (:option ediff-diff-options "-w" ; ignore whitespace | ||
339 | ediff-window-setup-function #'ediff-setup-windows-plain | ||
340 | ediff-split-window-function #'split-window-horizontally) | ||
341 | ;; https://oremacs.com/2015/01/17/setting-up-ediff/ | ||
342 | (add-hook 'ediff-after-quit-hook-internal #'winner-undo)) | ||
343 | |||
344 | (setup eldoc | ||
345 | (:option eldoc-idle-delay 0.1 | ||
346 | eldoc-echo-area-use-multiline-p nil)) | ||
347 | |||
348 | (setup elisp-mode | ||
349 | (:with-mode emacs-lisp-mode ;; -_- | ||
350 | (:option eval-expression-print-length nil | ||
351 | eval-expression-print-level nil | ||
352 | lisp-indent-function #'lisp-indent-function) | ||
353 | |||
354 | (:local-set (append imenu-generic-expression) | ||
355 | `("Setup" | ||
356 | ,(rx (seq | ||
357 | (group bol (* space) "(setup" (+ space)) | ||
358 | (? (group "(:" (+ graph) (* space) (? "("))) | ||
359 | (group (+ (any word ?-))))) | ||
360 | 3)) | ||
361 | |||
362 | (:hook #'checkdoc-minor-mode | ||
363 | #'turn-on-eldoc-mode) | ||
364 | |||
365 | ;; Emulate slime's eval binds | ||
366 | (:bind "C-c C-c" #'eval-defun | ||
367 | "C-c C-k" #'acdw/eval-region-or-buffer | ||
368 | "C-c C-z" #'ielm) | ||
369 | |||
370 | ;; Add advice to pulse evaluated regions | ||
371 | (:advise eval-region :around | ||
372 | (defun eval-region@pulse (fn beg end &rest args) | ||
373 | (pulse-momentary-highlight-region beg end) | ||
374 | (apply fn beg end args)))) | ||
375 | |||
376 | (:with-mode lisp-interaction-mode ;; -___- | ||
377 | (:bind "C-c C-c" #'eval-defun | ||
378 | "C-c C-k" #'acdw/eval-region-or-buffer | ||
379 | "C-c C-z" #'ielm))) | ||
380 | |||
381 | (setup emacs | ||
382 | ;; "Et cetera" settings | ||
383 | ;; This should stay as /minimal/ as possible. Anything that can go somewhere | ||
384 | ;; else /should/ go there. | ||
385 | (:option | ||
386 | attempt-orderly-shutdown-on-fatal-signal nil | ||
387 | attempt-stack-overflow-recovery nil | ||
388 | echo-keystrokes 0.01 | ||
389 | find-function-C-source-directory (acdw/find-emacs-source) | ||
390 | kill-read-only-ok t | ||
391 | load-prefer-newer t | ||
392 | native-comp-async-report-warnings-errors nil | ||
393 | password-cache t | ||
394 | password-cache-expiry 3600 ; 5 minutes | ||
395 | set-mark-command-repeat-pop t) | ||
396 | |||
397 | (when (fboundp 'command-completion-default-include-p) | ||
398 | (setq read-extended-command-predicate | ||
399 | #'command-completion-default-include-p)) | ||
400 | |||
401 | (defvar case-map (make-sparse-keymap) | ||
402 | "A keymap for setting case in various ways.") | ||
403 | (global-set-key (kbd "C-c c") case-map) | ||
404 | |||
405 | (defvar lookup-map (make-sparse-keymap) | ||
406 | "A keymap for looking up things.") | ||
407 | (global-set-key (kbd "C-c l") lookup-map) | ||
408 | |||
409 | (defvar toggle-map (make-sparse-keymap) | ||
410 | "A keymap for toggling!") | ||
411 | (global-set-key (kbd "C-c t") toggle-map) | ||
412 | |||
413 | (:global "M-=" #'count-words | ||
414 | "C-w" #'kill-region-or-backward-word | ||
415 | "C-c d" #'acdw/insert-iso-date | ||
416 | "M-`" nil | ||
417 | "C-x o" #'acdw/other-window-or-switch-buffer | ||
418 | "C-x O" #'acdw/other-window-or-switch-buffer-backward | ||
419 | "C-c _" #'add-file-local-variable | ||
420 | "C-x C-c" #'acdw/fat-finger-exit) | ||
421 | |||
422 | (:with-map toggle-map | ||
423 | (:bind "c" #'column-number-mode | ||
424 | "l" #'display-line-numbers-mode | ||
425 | "d" #'toggle-debug-on-error)) | ||
426 | |||
427 | (:with-map case-map | ||
428 | (require 'titlecase) | ||
429 | (:bind "c" #'capitalize-dwim | ||
430 | "t" #'titlecase-dwim | ||
431 | "u" #'upcase-dwim | ||
432 | "l" #'downcase-dwim | ||
433 | "s" (defun studlify-dwim (count) | ||
434 | "Studlify region if active, or COUNT words if not." | ||
435 | (interactive "*p") | ||
436 | (if (region-active-p) | ||
437 | (studlify-region (region-beginning) (region-end)) | ||
438 | (studlify-word count))))) | ||
439 | |||
440 | (add-hook 'after-make-frame-functions | ||
441 | (defun after-make-frame@maximize (frame) | ||
442 | (unless (bound-and-true-p edit-server-frame-p) | ||
443 | (toggle-frame-maximized frame))))) | ||
444 | |||
445 | (setup encoding | ||
446 | (:option locale-coding-system 'utf-8-unix | ||
447 | coding-system-for-read 'utf-8-unix | ||
448 | coding-system-for-write 'utf-8-unix | ||
449 | buffer-file-coding-system 'utf-8-unix | ||
450 | default-process-coding-system '(utf-8-unix . utf-8-unix) | ||
451 | x-select-request-type '(UTF8_STRING | ||
452 | COMPOUND_TEXT | ||
453 | TEXT | ||
454 | STRING)) | ||
455 | |||
456 | (set-charset-priority 'unicode) | ||
457 | (set-language-environment "UTF-8") | ||
458 | (prefer-coding-system 'utf-8-unix) | ||
459 | (set-default-coding-systems 'utf-8-unix) | ||
460 | (set-terminal-coding-system 'utf-8-unix) | ||
461 | (set-keyboard-coding-system 'utf-8-unix) | ||
462 | |||
463 | (acdw/system | ||
464 | (:work (set-clipboard-coding-system 'utf-16-le) | ||
465 | (set-selection-coding-system 'utf-16-le)) | ||
466 | (_ (set-selection-coding-system 'utf-8) | ||
467 | (set-clipboard-coding-system 'utf-8)))) | ||
468 | |||
469 | (setup eshell | ||
470 | (:also-load acdw-eshell | ||
471 | em-smart | ||
472 | em-tramp) | ||
473 | |||
474 | (:option eshell-aliases-file (acdw/dir "eshell/aliases" t) | ||
475 | eshell-destroy-buffer-when-process-dies t | ||
476 | eshell-directory-name (acdw/dir "eshell/" t) | ||
477 | eshell-error-if-no-glob t | ||
478 | eshell-hist-ignore-dups t | ||
479 | eshell-kill-on-exit nil | ||
480 | eshell-prefer-lisp-functions t ; I want to try using eshell | ||
481 | eshell-prefer-lisp-variables t ; as much as possible. | ||
482 | eshell-review-quick-commands nil | ||
483 | eshell-save-history-on-exit t | ||
484 | eshell-scroll-to-bottom-on-input 'all | ||
485 | eshell-smart-space-goes-to-end t | ||
486 | eshell-where-to-jump 'begin) | ||
487 | |||
488 | (:local-set outline-regexp eshell-prompt-regexp | ||
489 | page-delimiter eshell-prompt-regexp) | ||
490 | |||
491 | (:bind "C-d" #'eshell-quit-or-delete-char) | ||
492 | |||
493 | (:hook #'eshell-arg-hist-mode | ||
494 | (defun eshell-mode@setup () | ||
495 | (unless (bound-and-true-p eshell-customizations-loaded) | ||
496 | (load (expand-file-name "eshell" user-emacs-directory)))))) | ||
497 | |||
498 | (setup eww | ||
499 | (defvar-local eww-readable-p nil | ||
500 | "Whether current buffer is in readable-mode.") | ||
501 | (:option eww-search-prefix "https://duckduckgo.com/html?q=" | ||
502 | url-privacy-level '(email agent cookies lastloc)) | ||
503 | |||
504 | (defun eww@is-readable (&rest _) | ||
505 | (setq-local eww-readable-p t)) | ||
506 | (defun eww@is-not-readable (&rest _) | ||
507 | (setq-local eww-readable-p nil)) | ||
508 | |||
509 | (advice-add 'eww-readable :after #'eww@is-readable) | ||
510 | (advice-add 'eww-render :after #'eww@is-not-readable) | ||
511 | (advice-add 'eww-back-url :after #'eww@is-not-readable) | ||
512 | |||
513 | (:hook #'reading-mode)) | ||
514 | |||
515 | (setup files | ||
516 | (:option | ||
517 | auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t)) | ||
518 | auto-save-list-file-prefix (acdw/dir "auto-save-list/.saves-" t) | ||
519 | auto-save-interval 60 | ||
520 | auto-save-timeout 60 | ||
521 | auto-save-visited-interval auto-save-timeout | ||
522 | backup-by-copying t | ||
523 | backup-directory-alist `((".*" . ,(acdw/dir "backup/" t))) | ||
524 | delete-old-versions t | ||
525 | mode-require-final-newline 'visit-save | ||
526 | tramp-backup-directory-alist backup-directory-alist | ||
527 | vc-make-backup-files t | ||
528 | version-control t) | ||
529 | |||
530 | (auto-save-visited-mode +1)) | ||
531 | |||
532 | (setup find-func | ||
533 | (:global "C-c l f" #'find-function | ||
534 | "C-c l l" #'find-library | ||
535 | "C-c l v" #'find-variable)) | ||
536 | |||
537 | (setup flymake | ||
538 | |||
539 | (defvar-local flymake-inhibit nil | ||
540 | "Buffer-local variable to inhibit `flymake'.") | ||
541 | (add-to-list 'safe-local-variable-values '(flymake-inhibit . t)) | ||
542 | (add-to-list 'safe-local-variable-values '(flymake-inhibit . nil)) | ||
543 | |||
544 | (defvar flymake-inhibit-major-modes nil | ||
545 | "Which major-modes NOT to enable `flymake' in.") | ||
546 | |||
547 | (defvar flymake-inhibit-file-name-regexps '("init\\.el\\'" | ||
548 | "early-init\\.el\\'") | ||
549 | "List of file regexps NOT to enable `flymake' in.") | ||
550 | |||
551 | (defvar flymake-inhibit-buffer-name-regexps (list (rx "*scratch*")) | ||
552 | "List of buffer-name regexps NOT to enable `flymake' in.") | ||
553 | |||
554 | (defun list-string-match-p (string regexp-list) | ||
555 | "Return t if at least one regex in RETGEXP-LIST matches STRING, else nil." | ||
556 | (when string ; if STRING is nil, return nil. | ||
557 | (catch 'found | ||
558 | (dolist (regexp regexp-list) | ||
559 | (when (string-match regexp string) | ||
560 | (throw 'found t)))))) | ||
561 | |||
562 | (defun flymake-unless () | ||
563 | "Turn on `flymake-mode', UNLESS it's inhibited. | ||
564 | There are three methods to inhibit flymake in a file. From most | ||
565 | specific to most general, they are these: | ||
566 | |||
567 | - `flymake-inhibit': a file-local-variable | ||
568 | |||
569 | - `flymake-inhibit-buffer-name-regexps': a list of regexps to | ||
570 | match the buffer name against. If one of them matches, inhibit | ||
571 | `flymake-mode'. | ||
572 | |||
573 | - `flymake-inhibit-file-name-regexps': a list of regexps to match | ||
574 | the filename against. If one of them matches, inhibit | ||
575 | `flymake-mode'. | ||
576 | |||
577 | - `flymake-inhibit-major-modes': a list of major-modes in which | ||
578 | to inhibit `flymake-mode'. Really only useful if you want to | ||
579 | generally add `flymake-mode' to `prog-mode-hook'." | ||
580 | (unless (or (bound-and-true-p flymake-inhibit) ; file-local variable | ||
581 | (list-string-match-p (buffer-name) | ||
582 | flymake-inhibit-buffer-name-regexps) | ||
583 | (list-string-match-p (buffer-file-name) | ||
584 | flymake-inhibit-file-name-regexps) | ||
585 | (apply #'derived-mode-p flymake-inhibit-major-modes)) | ||
586 | (flymake-mode-on))) | ||
587 | |||
588 | (add-hook 'prog-mode-hook #'flymake-unless) | ||
589 | |||
590 | (:bind "M-n" #'flymake-goto-next-error | ||
591 | "M-p" #'flymake-goto-prev-error)) | ||
592 | |||
593 | (setup flyspell | ||
594 | (:hook-into text-mode)) | ||
595 | |||
596 | (setup frames | ||
597 | (:option frame-title-format '("%b@" | ||
598 | (:eval | ||
599 | (or (file-remote-p default-directory 'host) | ||
600 | system-name)) | ||
601 | " %+%* GNU Emacs" | ||
602 | (:eval (when (frame-parameter nil 'client) | ||
603 | " Client"))) | ||
604 | window-resize-pixelwise t)) | ||
605 | |||
606 | (setup ibuffer | ||
607 | (:also-load ibuf-ext) | ||
608 | (:option ibuffer-expert t | ||
609 | ibuffer-show-empty-filter-groups nil | ||
610 | ibuffer-saved-filter-groups | ||
611 | '(("default" | ||
612 | ("dired" (mode . dired-mode)) | ||
613 | ("customize" (mode . Custom-mode)) | ||
614 | ("emacs" (or (name . "^\\*scratch\\*$") | ||
615 | (name . "^\\*Messages\\*$") | ||
616 | (name . "^\\*Warnings\\*$") | ||
617 | (name . "^\\*straight-process\\*$") | ||
618 | (name . "^\\*Calendar\\*$"))) | ||
619 | ("git" (or (name . "^\*magit") | ||
620 | (name . "^\magit"))) | ||
621 | ("help" (or (mode . help-mode) | ||
622 | (mode . Info-mode) | ||
623 | (mode . helpful-mode))) | ||
624 | ("messaging" (or (mode . message-mode) | ||
625 | (mode . bbdb-mode) | ||
626 | (mode . mail-mode) | ||
627 | (mode . gnus-group-mode) | ||
628 | (mode . gnus-summary-mode) | ||
629 | (mode . gnus-article-mode) | ||
630 | (name . "^\\.bbdb$") | ||
631 | (name . "^\\.newsrc-dribble") | ||
632 | (mode . erc-mode) | ||
633 | (mode . circe-server-mode) | ||
634 | (mode . circe-channel-mode))) | ||
635 | ("shell" (or (mode . eshell-mode) | ||
636 | (mode . shell-mode) | ||
637 | (mode . vterm-mode))) | ||
638 | ("web" (or (mode . elpher-mode) | ||
639 | (mode . gemini-mode) | ||
640 | (mode . eww-mode)))))) | ||
641 | |||
642 | (:global "C-x C-b" #'ibuffer) | ||
643 | |||
644 | (:hook (defun ibuffer@filter-to-default () | ||
645 | (ibuffer-switch-to-saved-filter-groups "default")))) | ||
646 | |||
647 | (setup ielm | ||
648 | (:hook #'turn-on-eldoc-mode)) | ||
649 | |||
650 | (setup imenu | ||
651 | (:option imenu-auto-rescan t)) | ||
652 | |||
653 | (setup isearch | ||
654 | (:option search-default-mode t)) | ||
655 | |||
656 | (setup lines | ||
657 | (:option fill-column 79 | ||
658 | word-wrap t | ||
659 | truncate-lines nil) | ||
660 | |||
661 | (global-display-fill-column-indicator-mode +1) | ||
662 | (global-so-long-mode +1) | ||
663 | |||
664 | (add-hook 'visual-line-mode-hook | ||
665 | (defun acdw/disable-fill-column-indicator () | ||
666 | (display-fill-column-indicator-mode | ||
667 | (if visual-line-mode -1 +1)))) | ||
668 | |||
669 | ;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'. | ||
670 | ;; I can't simply advise `kill-line' with an override from crux because crux | ||
671 | ;; itself calls `kill-line', leading to a infinite nesting situation. | ||
672 | (advice-add 'kill-line :around | ||
673 | (defun kill-line@join (fn &rest args) | ||
674 | (if (and (eolp) | ||
675 | (not (bolp))) | ||
676 | (delete-indentation 1) | ||
677 | (apply fn args))))) | ||
678 | |||
679 | (setup minibuffer | ||
680 | (:option enable-recursive-minibuffers t | ||
681 | file-name-shadow-properties '(invisible t intangible t) | ||
682 | minibuffer-eldef-shorten-default t | ||
683 | minibuffer-prompt-properties | ||
684 | '(read-only t cursor-intangible t face minibuffer-prompt) | ||
685 | read-answer-short t | ||
686 | read-extended-command-predicate ; used on >28 | ||
687 | #'command-completion-default-include-p) | ||
688 | |||
689 | (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) | ||
690 | |||
691 | (add-hook 'minibuffer-setup-hook #'acdw/gc-disable) | ||
692 | (add-hook 'minibuffer-exit-hook #'acdw/gc-enable) | ||
693 | |||
694 | (minibuffer-depth-indicate-mode +1) | ||
695 | (file-name-shadow-mode +1) | ||
696 | (minibuffer-electric-default-mode +1) | ||
697 | |||
698 | (if (version< emacs-version "28") | ||
699 | (fset 'yes-or-no-p #'y-or-n-p) | ||
700 | (setq use-short-answers t))) | ||
701 | |||
702 | (setup mouse-avoidance | ||
703 | (mouse-avoidance-mode 'exile)) | ||
704 | |||
705 | (setup page | ||
706 | (:option page-delimiter | ||
707 | (rx bol (or "\f" ";;;") | ||
708 | (not (any "#")) (* not-newline) "\n" | ||
709 | (* (* blank) (opt ";" (* not-newline)) "\n"))) | ||
710 | |||
711 | (defun recenter-to-top (&rest _) | ||
712 | "Recenter the cursor to the top of the window." | ||
713 | (when (called-interactively-p 'any) | ||
714 | (recenter (if (or (null scroll-margin) | ||
715 | (zerop scroll-margin)) | ||
716 | 3 | ||
717 | scroll-margin)))) | ||
718 | |||
719 | (:advise forward-page :after #'recenter-to-top | ||
720 | backward-page :after #'recenter-to-top) | ||
721 | |||
722 | ;; I'm not sure where this is in /my/ version of Emacs | ||
723 | ;; (defvar page-navigation-repeat-map | ||
724 | ;; (let ((map (make-sparse-keymap))) | ||
725 | ;; (define-key map "]" #'forward-page) | ||
726 | ;; (define-key map "[" #'backward-page) | ||
727 | ;; map) | ||
728 | ;; "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.") | ||
729 | |||
730 | ;; (put 'forward-page 'repeat-map 'page-navigation-repeat-map) | ||
731 | ;; (put 'backward-page 'repeat-map 'page-navigation-repeat-map) | ||
732 | ) | ||
733 | |||
734 | (setup prog | ||
735 | (:option show-paren-delay 0 | ||
736 | show-paren-style 'mixed | ||
737 | show-paren-when-point-inside-paren t | ||
738 | show-paren-when-point-in-periphery t | ||
739 | smie-indent-basic tab-width) | ||
740 | |||
741 | (:hook show-paren-mode | ||
742 | electric-pair-local-mode | ||
743 | acdw/setup-fringes | ||
744 | |||
745 | (defun prog-mode@auto-fill () | ||
746 | (setq-local comment-auto-fill-only-comments t) | ||
747 | (turn-on-auto-fill))) | ||
748 | |||
749 | (add-hook 'after-save-hook | ||
750 | #'executable-make-buffer-file-executable-if-script-p)) | ||
751 | |||
752 | (setup repeat | ||
753 | ;; new for Emacs 28! | ||
754 | (:only-if (fboundp #'repeat-mode)) | ||
755 | |||
756 | (:option repeat-exit-key "g" | ||
757 | repeat-exit-timeout 5) | ||
758 | |||
759 | (repeat-mode +1)) | ||
760 | |||
761 | (setup saveplace | ||
762 | (:option save-place-file (acdw/dir "places.el") | ||
763 | save-place-forget-unreadable-files (acdw/system :home)) | ||
764 | |||
765 | (save-place-mode +1)) | ||
766 | |||
767 | (setup scratch | ||
768 | (:option inhibit-startup-screen t | ||
769 | initial-buffer-choice t | ||
770 | initial-scratch-message "" | ||
771 | ;; (concat ";; Howdy, " | ||
772 | ;; (nth 0 (split-string | ||
773 | ;; user-full-name)) | ||
774 | ;; "! " | ||
775 | ;; "Welcome to GNU Emacs.\n\n") | ||
776 | ) | ||
777 | |||
778 | (add-hook 'kill-buffer-query-functions | ||
779 | (defun kill-buffer-query@immortal-scratch () | ||
780 | (if (eq (current-buffer) (get-buffer "*scratch*")) | ||
781 | (progn (bury-buffer) | ||
782 | nil) | ||
783 | t)))) | ||
784 | |||
785 | (setup scrolling | ||
786 | (:option auto-window-vscroll nil | ||
787 | fast-but-imprecise-scrolling t | ||
788 | scroll-margin 3 | ||
789 | scroll-conservatively 101 | ||
790 | scroll-preserve-screen-position 1)) | ||
791 | |||
792 | (setup selection | ||
793 | (:option save-interprogram-paste-before-kill t | ||
794 | yank-pop-change-selection t | ||
795 | x-select-enable-clipboard t | ||
796 | x-select-enable-primary t | ||
797 | mouse-drag-copy-region t | ||
798 | kill-do-not-save-duplicates t) | ||
799 | |||
800 | (delete-selection-mode +1)) | ||
801 | |||
802 | (setup sh-mode | ||
803 | (:option sh-basic-offset tab-width | ||
804 | sh-indent-after-case 0 | ||
805 | sh-indent-for-case-alt '+ | ||
806 | sh-indent-for-case-label 0) | ||
807 | |||
808 | (:local-set indent-tabs-mode t) | ||
809 | |||
810 | (when (executable-find "shfmt") | ||
811 | (with-eval-after-load 'apheleia | ||
812 | (:option (append apheleia-formatters) '(shfmt . ("shfmt")) | ||
813 | (append apheleia-mode-alist) '(sh-mode . shfmt)))) | ||
814 | |||
815 | (when (executable-find "shellcheck") | ||
816 | (:straight flymake-shellcheck) | ||
817 | (:hook flymake-mode | ||
818 | flymake-shellcheck-load))) | ||
819 | |||
820 | (setup shell-command | ||
821 | (:option shell-command-switch (acdw/system | ||
822 | ;; I should be testing on some variable | ||
823 | (:home "-csi") | ||
824 | (:work "-c")) | ||
825 | shell-command-prompt-show-cwd t | ||
826 | shell-command-default-error-buffer "*shell-command-errors*")) | ||
827 | |||
828 | (setup shr | ||
829 | (:option shr-width fill-column | ||
830 | shr-max-width fill-column | ||
831 | shr-max-image-proportion 0.6 | ||
832 | shr-image-animate t | ||
833 | shr-discard-aria-hidden t | ||
834 | shr-folding-mode t)) | ||
835 | |||
836 | (setup text | ||
837 | (:hook turn-on-auto-fill | ||
838 | tildify-mode | ||
839 | acdw/setup-fringes)) | ||
840 | |||
841 | (setup uniquify | ||
842 | (:option uniquify-buffer-name-style 'forward | ||
843 | uniquify-separator path-separator | ||
844 | uniquify-after-kill-buffer-p t | ||
845 | uniquify-ignore-buffers-re "^\\*")) | ||
846 | |||
847 | (setup variable-pitch-mode | ||
848 | ;; I might want to change this to `buffer-face-mode-hook'... | ||
849 | (:advise variable-pitch-mode :after | ||
850 | (defun variable-pitch-mode@setup (&rest _) | ||
851 | "Set up `variable-pitch-mode' with my customizations." | ||
852 | (display-fill-column-indicator-mode | ||
853 | (if buffer-face-mode -1 +1))))) | ||
854 | |||
855 | (setup view | ||
856 | (:option view-read-only t) | ||
857 | |||
858 | (:hook (defun acdw/read-view-mode () | ||
859 | (reading-mode (if view-mode +1 -1))))) | ||
860 | |||
861 | (setup w32 | ||
862 | (:option w32-allow-system-shell t | ||
863 | w32-pass-lwindow-to-system nil | ||
864 | w32-lwindow-modifier 'super | ||
865 | w32-pass-rwindow-to-system nil | ||
866 | w32-rwindow-modifier 'super | ||
867 | w32-pass-apps-to-system nil | ||
868 | w32-apps-modifier 'hyper)) | ||
869 | |||
870 | (setup whitespace | ||
871 | (:option whitespace-style '(empty | ||
872 | indentation | ||
873 | space-before-tab | ||
874 | space-after-tab) | ||
875 | indent-tabs-mode nil | ||
876 | tab-width 4 | ||
877 | backward-delete-char-untabify-method 'hungry) | ||
878 | |||
879 | (:global "M-SPC" #'cycle-spacing)) | ||
880 | |||
881 | (setup windmove | ||
882 | (:option windmove-wrap-around t) | ||
883 | (:global | ||
884 | ;; moving | ||
885 | "C-x 4 <left>" #'windmove-left | ||
886 | "C-x 4 <right>" #'windmove-right | ||
887 | "C-x 4 <up>" #'windmove-up | ||
888 | "C-x 4 <down>" #'windmove-down | ||
889 | ;; swapping | ||
890 | "C-x 4 S-<left>" #'windmove-swap-states-left | ||
891 | "C-x 4 S-<right>" #'windmove-swap-states-right | ||
892 | "C-x 4 S-<up>" #'windmove-swap-states-up | ||
893 | "C-x 4 S-<down>" #'windmove-swap-states-down) | ||
894 | |||
895 | ;; (when (fboundp 'repeat-mode) | ||
896 | ;; (defvar windmove-repeat-map | ||
897 | ;; (let ((map (make-sparse-keymap))) | ||
898 | ;; ;; moving | ||
899 | ;; (define-key map [left] #'windmove-left) | ||
900 | ;; (define-key map [right] #'windmove-right) | ||
901 | ;; (define-key map [up] #'windmove-up) | ||
902 | ;; (define-key map [down] #'windmove-down) | ||
903 | ;; ;; swapping | ||
904 | ;; (define-key map [S-left] #'windmove-swap-states-left) | ||
905 | ;; (define-key map [S-right] #'windmove-swap-states-right) | ||
906 | ;; (define-key map [S-up] #'windmove-swap-states-up) | ||
907 | ;; (define-key map [S-down] #'windmove-swap-states-down) | ||
908 | ;; map) | ||
909 | ;; "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.") | ||
910 | |||
911 | ;; (dolist (sym '(windmove-left | ||
912 | ;; windmove-right | ||
913 | ;; windmove-up | ||
914 | ;; windmove-down | ||
915 | ;; windmove-swap-states-left | ||
916 | ;; windmove-swap-states-right | ||
917 | ;; windmove-swap-states-up | ||
918 | ;; windmove-swap-states-down)) | ||
919 | ;; (put sym 'repeat-map 'windmove-repeat-map))) | ||
920 | ) | ||
921 | |||
922 | (setup window | ||
923 | (require 'acdw-bell) | ||
924 | (:option | ||
925 | ;; Man-notify-method 'pushy | ||
926 | ;; display-buffer-alist ; from FrostyX | ||
927 | ;; '(("shell.*" (display-buffer-same-window) ()) | ||
928 | ;; (".*" (display-buffer-reuse-window | ||
929 | ;; display-buffer-same-window) | ||
930 | ;; (reusable-frames . t))) | ||
931 | recenter-positions '(top middle bottom) | ||
932 | ring-bell-function (lambda () | ||
933 | (acdw-bell/flash-mode-line | ||
934 | (acdw/system :home))) | ||
935 | use-dialog-box nil | ||
936 | use-file-dialog nil | ||
937 | visible-bell nil) | ||
938 | |||
939 | (tooltip-mode -1)) | ||
940 | |||
941 | (setup winner | ||
942 | ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html | ||
943 | (:global "C-x 4 C-/" #'winner-undo | ||
944 | "C-x 4 /" #'winner-undo | ||
945 | "C-x 4 C-?" #'winner-redo | ||
946 | "C-x 4 ?" #'winner-redo) | ||
947 | |||
948 | ;; add `winner-undo' and `winner-redo' to `repeat-mode' | ||
949 | ;; (when (fboundp 'repeat-mode) | ||
950 | ;; (defvar winner-mode-repeat-map | ||
951 | ;; (let ((map (make-sparse-keymap))) | ||
952 | ;; (define-key map "/" #'winner-undo) | ||
953 | ;; (define-key map "?" #'winner-redo) | ||
954 | ;; map) | ||
955 | ;; "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.") | ||
956 | |||
957 | ;; (put 'winner-undo 'repeat-map 'winner-mode-repeat-map) | ||
958 | ;; (put 'winner-redo 'repeat-map 'winner-mode-repeat-map)) | ||
959 | |||
960 | (winner-mode +1)) | ||
961 | |||
962 | (setup (:straight (0x0 | ||
963 | :host gitlab | ||
964 | :repo "willvaughn/emacs-0x0")) | ||
965 | (:option 0x0-default-server 'ttm)) | ||
966 | |||
967 | (setup (:straight-if affe | ||
968 | (and (or (executable-find "fd") | ||
969 | (executable-find "find")) | ||
970 | (executable-find "rg"))) | ||
971 | ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find' | ||
972 | (:option affe-regexp-compiler | ||
973 | (defun affe-orderless-regexp-compiler (input _type) | ||
974 | (setq input (orderless-pattern-compiler input)) | ||
975 | (cons input (lambda (str) (orderless--highlight input str)))))) | ||
976 | |||
977 | (setup (:straight-if ahk-mode | ||
978 | (acdw/system :work))) | ||
979 | |||
980 | (setup (:straight alert) | ||
981 | (:option alert-default-style (acdw/system | ||
982 | (:home 'libnotify) | ||
983 | (_ 'message)))) | ||
984 | |||
985 | (setup (:straight (apheleia | ||
986 | :host github | ||
987 | :repo "raxod502/apheleia")) | ||
988 | |||
989 | (apheleia-global-mode +1) | ||
990 | |||
991 | ;; Use a dumb formatter on modes that `apheleia' doesn't work for. | ||
992 | (add-hook 'before-save-hook | ||
993 | (defun before-save@dumb-auto-format () | ||
994 | (setq stupid-modes '(makefile-mode | ||
995 | org-mode)) | ||
996 | ;; If there's no apheleia formatter for the mode, just indent the | ||
997 | ;; buffer. | ||
998 | (unless (or (apply #'derived-mode-p stupid-modes) | ||
999 | (and (fboundp 'apheleia--get-formatter-command) | ||
1000 | (apheleia--get-formatter-command))) | ||
1001 | (indent-region (point-min) (point-max)))))) | ||
1002 | |||
1003 | (setup (:straight async) | ||
1004 | (dired-async-mode +1) | ||
1005 | |||
1006 | (:with-feature dired | ||
1007 | (:hook (defun dired@disable-dired-async-mode-line () | ||
1008 | (autoload 'dired-async--modeline-mode "dired-async" nil t) | ||
1009 | (dired-async--modeline-mode -1))))) | ||
1010 | |||
1011 | (setup (:straight avy) | ||
1012 | (:global "C-'" #'avy-goto-char-timer | ||
1013 | "C-c C-j" #'avy-resume) | ||
1014 | |||
1015 | (:with-feature isearch | ||
1016 | (:bind "C-'" #'avy-isearch))) | ||
1017 | |||
189 | (setup (:straight circe) | 1018 | (setup (:straight circe) |
190 | (require 'circe) | 1019 | (require 'circe) |
191 | (require 'acdw-irc) | 1020 | (require 'acdw-irc) |
@@ -326,16 +1155,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
326 | 1155 | ||
327 | (:hook #'enable-lui-track))) | 1156 | (:hook #'enable-lui-track))) |
328 | 1157 | ||
329 | (setup completion | ||
330 | (:option completion-ignore-case t | ||
331 | read-buffer-completion-ignore-case t | ||
332 | completion-styles '(substring partial-completion) | ||
333 | completion-category-defaults nil | ||
334 | completion-category-overrides | ||
335 | '((file (styles . (partial-completion))))) | ||
336 | |||
337 | (:global "M-/" #'hippie-expand)) | ||
338 | |||
339 | (setup (:straight (consult | 1158 | (setup (:straight (consult |
340 | :host github | 1159 | :host github |
341 | :repo "minad/consult")) | 1160 | :repo "minad/consult")) |
@@ -434,57 +1253,9 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
434 | 1253 | ||
435 | (crux-reopen-as-root-mode +1)) | 1254 | (crux-reopen-as-root-mode +1)) |
436 | 1255 | ||
437 | (setup cursor | ||
438 | (:option cursor-type 'bar | ||
439 | cursor-in-non-selected-windows 'hollow | ||
440 | blink-cursor-blinks 1) | ||
441 | (blink-cursor-mode +1)) | ||
442 | |||
443 | (setup cus-edit | ||
444 | (:option custom-file null-device ; don't store customizations | ||
445 | custom-magic-show nil | ||
446 | custom-magic-show-button t | ||
447 | custom-raised-buttons nil | ||
448 | custom-unlispify-tag-names nil | ||
449 | custom-variable-default-form 'lisp) | ||
450 | |||
451 | ;; `Custom-mode-hook' fires /before/ the widgets are built, so I have to | ||
452 | ;; install advice after the widgets are made. | ||
453 | (:advise custom-buffer-create :after | ||
454 | (defun custom-buffer@expand-widgets (&rest _) | ||
455 | "Expand descriptions in `Custom-mode' buffers." | ||
456 | (interactive) | ||
457 | ;; "More/Hide" widgets (thanks alphapapa!) | ||
458 | (widget-map-buttons (lambda (widget _) | ||
459 | (pcase (widget-get widget :off) | ||
460 | ("More" (widget-apply-action widget))) | ||
461 | nil)) | ||
462 | ;; "Show Value" widgets (the little triangles) | ||
463 | (widget-map-buttons (lambda (widget _) | ||
464 | (pcase (widget-get widget :off) | ||
465 | ("Show Value" | ||
466 | (widget-apply-action widget))) | ||
467 | nil)))) | ||
468 | |||
469 | (:with-mode Custom-mode | ||
470 | (:local-set imenu-generic-expression ; thanks u/oantolin! | ||
471 | '(("Faces" (rx (seq bol | ||
472 | (or "Show" "Hide") " " | ||
473 | (group (zero-or-more nonl)) | ||
474 | " face: [sample]")) | ||
475 | 1) | ||
476 | ("Variables" (rx (seq bol | ||
477 | (or "Show Value" "Hide") " " | ||
478 | (group (zero-or-more | ||
479 | (not (any "\n:")))))) | ||
480 | 1))))) | ||
481 | |||
482 | (setup debugger | ||
483 | (:hook visual-line-mode)) | ||
484 | |||
485 | (setup (:straight-if (define-repeat-map | 1256 | (setup (:straight-if (define-repeat-map |
486 | :host nil | 1257 | :host nil |
487 | :repo "https://tildegit.org/acdw/define-repeat-map.el") | 1258 | :repo "https://tildegit.org/acdw/define-repeat-map.el") |
488 | (acdw/system :home)) | 1259 | (acdw/system :home)) |
489 | 1260 | ||
490 | (defun acdw/other-window-or-switch-buffer-backward () | 1261 | (defun acdw/other-window-or-switch-buffer-backward () |
@@ -526,97 +1297,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
526 | ("/" winner-undo | 1297 | ("/" winner-undo |
527 | "?" winner-redo))) | 1298 | "?" winner-redo))) |
528 | 1299 | ||
529 | (setup dired | ||
530 | (:also-load dired-x) | ||
531 | (:straight dired-subtree | ||
532 | dired-collapse | ||
533 | dired-git-info) | ||
534 | |||
535 | (:option dired-recursive-copies 'always | ||
536 | dired-recursive-deletes 'always | ||
537 | delete-by-moving-to-trash t | ||
538 | dired-listing-switches "-Al" | ||
539 | ls-lisp-dirs-first t | ||
540 | dired-ls-F-marks-symlinks t | ||
541 | dired-no-confirm '(byte-compile | ||
542 | chgrp chmod chown copy | ||
543 | hardlink load move | ||
544 | shell touch symlink) | ||
545 | dired-dwim-target t) | ||
546 | |||
547 | (:bind "TAB" #'dired-subtree-cycle | ||
548 | "i" #'dired-subtree-toggle | ||
549 | ")" #'dired-git-info-mode) | ||
550 | |||
551 | (:hook dired-collapse-mode | ||
552 | dired-hide-details-mode | ||
553 | hl-line-mode) | ||
554 | |||
555 | (:global "C-x C-j" #'dired-jump) | ||
556 | |||
557 | (with-eval-after-load 'dired | ||
558 | (acdw/system | ||
559 | (:work (:straight w32-browser) | ||
560 | (autoload #'dired-w32-browser "w32-browser" nil t) | ||
561 | (:bind "RET" #'dired-w32-browser)) | ||
562 | (:home (:straight dired-open) | ||
563 | (autoload #'dired-find-alternate-file "dired-open" nil t) | ||
564 | (:bind "RET" #'dired-find-alternate-file))))) | ||
565 | |||
566 | (setup disabled | ||
567 | ;; While this stuff is defined in novice.el, I'm using 'disabled' as the name | ||
568 | ;; for easy finding. | ||
569 | |||
570 | ;; Enable all disabled commands. | ||
571 | ;; This is an option, but I'm going to try /enabling/ just the ones that I | ||
572 | ;; use instead. | ||
573 | ;; (mapatoms (lambda (symbol) | ||
574 | ;; (when (get symbol 'disabled) | ||
575 | ;; (put symbol 'disabled nil)))) | ||
576 | |||
577 | ;; Enable /some/ disabled commands | ||
578 | (dolist (enable-sym '(narrow-to-region | ||
579 | dired-find-alternate-file | ||
580 | narrow-to-page)) | ||
581 | (put enable-sym 'disabled nil)) | ||
582 | |||
583 | ;; Now, disable symbols as I wish. | ||
584 | (dolist (disable-sym '(view-hello-file | ||
585 | suspend-frame | ||
586 | scroll-left | ||
587 | scroll-right | ||
588 | comment-set-column | ||
589 | set-fill-column)) | ||
590 | (put disable-sym 'disabled t)) | ||
591 | |||
592 | ;; And set the disabled function to something better than the default. | ||
593 | ;; Now, I can run any disabled command, but I have to use M-x to do it. | ||
594 | (setq disabled-command-function | ||
595 | (defun acdw/disabled-command-function (&optional cmd keys) | ||
596 | (let ((cmd (or cmd this-command)) | ||
597 | (keys (or keys (this-command-keys)))) | ||
598 | ;; this logic stolen from original `disabled-command-function' | ||
599 | (if (or (eq (aref keys 0) (if (stringp keys) | ||
600 | (aref "\M-x" 0) | ||
601 | ?\M-x)) | ||
602 | (and (>= (length keys) 2) | ||
603 | (eq (aref keys 0) meta-prefix-char) | ||
604 | (eq (aref keys 1) ?x))) | ||
605 | ;; it's been run as an M-x command, we want to do it | ||
606 | (call-interactively cmd) | ||
607 | ;; else, tell the user it's disabled. | ||
608 | (message (substitute-command-keys | ||
609 | (concat "Command `%s' has been disabled. " | ||
610 | "Run with \\[execute-extended-command].")) | ||
611 | cmd)))))) | ||
612 | |||
613 | (setup ediff | ||
614 | (:option ediff-diff-options "-w" ; ignore whitespace | ||
615 | ediff-window-setup-function #'ediff-setup-windows-plain | ||
616 | ediff-split-window-function #'split-window-horizontally) | ||
617 | ;; https://oremacs.com/2015/01/17/setting-up-ediff/ | ||
618 | (add-hook 'ediff-after-quit-hook-internal #'winner-undo)) | ||
619 | |||
620 | (setup (:straight edit-indirect)) | 1300 | (setup (:straight edit-indirect)) |
621 | 1301 | ||
622 | ;; requires extension: | 1302 | ;; requires extension: |
@@ -637,10 +1317,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
637 | (defun edit-server@set-a-variable (&rest _) | 1317 | (defun edit-server@set-a-variable (&rest _) |
638 | (setq-local edit-server-frame-p t)))) | 1318 | (setq-local edit-server-frame-p t)))) |
639 | 1319 | ||
640 | (setup eldoc | ||
641 | (:option eldoc-idle-delay 0.1 | ||
642 | eldoc-echo-area-use-multiline-p nil)) | ||
643 | |||
644 | (setup (:straight (electric-cursor | 1320 | (setup (:straight (electric-cursor |
645 | :host github | 1321 | :host github |
646 | :repo "duckwork/electric-cursor")) | 1322 | :repo "duckwork/electric-cursor")) |
@@ -681,39 +1357,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
681 | (scroll-down-command arg) | 1357 | (scroll-down-command arg) |
682 | (error (elfeed-show-prev)))))))) | 1358 | (error (elfeed-show-prev)))))))) |
683 | 1359 | ||
684 | (setup elisp-mode | ||
685 | (:with-mode emacs-lisp-mode ;; -_- | ||
686 | (:option eval-expression-print-length nil | ||
687 | eval-expression-print-level nil | ||
688 | lisp-indent-function #'lisp-indent-function) | ||
689 | |||
690 | (:local-set (append imenu-generic-expression) | ||
691 | `("Setup" | ||
692 | ,(rx (seq | ||
693 | (group bol (* space) "(setup" (+ space)) | ||
694 | (? (group "(:" (+ graph) (* space) (? "("))) | ||
695 | (group (+ (any word ?-))))) | ||
696 | 3)) | ||
697 | |||
698 | (:hook #'checkdoc-minor-mode | ||
699 | #'turn-on-eldoc-mode) | ||
700 | |||
701 | ;; Emulate slime's eval binds | ||
702 | (:bind "C-c C-c" #'eval-defun | ||
703 | "C-c C-k" #'acdw/eval-region-or-buffer | ||
704 | "C-c C-z" #'ielm) | ||
705 | |||
706 | ;; Add advice to pulse evaluated regions | ||
707 | (:advise eval-region :around | ||
708 | (defun eval-region@pulse (fn beg end &rest args) | ||
709 | (pulse-momentary-highlight-region beg end) | ||
710 | (apply fn beg end args)))) | ||
711 | |||
712 | (:with-mode lisp-interaction-mode ;; -___- | ||
713 | (:bind "C-c C-c" #'eval-defun | ||
714 | "C-c C-k" #'acdw/eval-region-or-buffer | ||
715 | "C-c C-z" #'ielm))) | ||
716 | |||
717 | (setup (:straight elisp-slime-nav) | 1360 | (setup (:straight elisp-slime-nav) |
718 | (:hook-into emacs-lisp-mode | 1361 | (:hook-into emacs-lisp-mode |
719 | ielm-mode)) | 1362 | ielm-mode)) |
@@ -743,70 +1386,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
743 | ;; (t (apply fn url args)))) | 1386 | ;; (t (apply fn url args)))) |
744 | ) | 1387 | ) |
745 | 1388 | ||
746 | (setup emacs | ||
747 | ;; "Et cetera" settings | ||
748 | ;; This should stay as /minimal/ as possible. Anything that can go somewhere | ||
749 | ;; else /should/ go there. | ||
750 | (:option | ||
751 | attempt-orderly-shutdown-on-fatal-signal nil | ||
752 | attempt-stack-overflow-recovery nil | ||
753 | echo-keystrokes 0.01 | ||
754 | find-function-C-source-directory (acdw/find-emacs-source) | ||
755 | kill-read-only-ok t | ||
756 | load-prefer-newer t | ||
757 | native-comp-async-report-warnings-errors nil | ||
758 | password-cache t | ||
759 | password-cache-expiry 3600 ; 5 minutes | ||
760 | set-mark-command-repeat-pop t) | ||
761 | |||
762 | (when (fboundp 'command-completion-default-include-p) | ||
763 | (setq read-extended-command-predicate | ||
764 | #'command-completion-default-include-p)) | ||
765 | |||
766 | (defvar case-map (make-sparse-keymap) | ||
767 | "A keymap for setting case in various ways.") | ||
768 | (global-set-key (kbd "C-c c") case-map) | ||
769 | |||
770 | (defvar lookup-map (make-sparse-keymap) | ||
771 | "A keymap for looking up things.") | ||
772 | (global-set-key (kbd "C-c l") lookup-map) | ||
773 | |||
774 | (defvar toggle-map (make-sparse-keymap) | ||
775 | "A keymap for toggling!") | ||
776 | (global-set-key (kbd "C-c t") toggle-map) | ||
777 | |||
778 | (:global "M-=" #'count-words | ||
779 | "C-w" #'kill-region-or-backward-word | ||
780 | "C-c d" #'acdw/insert-iso-date | ||
781 | "M-`" nil | ||
782 | "C-x o" #'acdw/other-window-or-switch-buffer | ||
783 | "C-x O" #'acdw/other-window-or-switch-buffer-backward | ||
784 | "C-c _" #'add-file-local-variable | ||
785 | "C-x C-c" #'acdw/fat-finger-exit) | ||
786 | |||
787 | (:with-map toggle-map | ||
788 | (:bind "c" #'column-number-mode | ||
789 | "l" #'display-line-numbers-mode | ||
790 | "d" #'toggle-debug-on-error)) | ||
791 | |||
792 | (:with-map case-map | ||
793 | (require 'titlecase) | ||
794 | (:bind "c" #'capitalize-dwim | ||
795 | "t" #'titlecase-dwim | ||
796 | "u" #'upcase-dwim | ||
797 | "l" #'downcase-dwim | ||
798 | "s" (defun studlify-dwim (count) | ||
799 | "Studlify region if active, or COUNT words if not." | ||
800 | (interactive "*p") | ||
801 | (if (region-active-p) | ||
802 | (studlify-region (region-beginning) (region-end)) | ||
803 | (studlify-word count))))) | ||
804 | |||
805 | (add-hook 'after-make-frame-functions | ||
806 | (defun after-make-frame@maximize (frame) | ||
807 | (unless (bound-and-true-p edit-server-frame-p) | ||
808 | (toggle-frame-maximized frame))))) | ||
809 | |||
810 | (setup (:straight embark) | 1389 | (setup (:straight embark) |
811 | (:global "C-." #'embark-act) | 1390 | (:global "C-." #'embark-act) |
812 | (:option prefix-help-command #'embark-prefix-help-command | 1391 | (:option prefix-help-command #'embark-prefix-help-command |
@@ -830,30 +1409,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
830 | (add-hook 'embark-collect-mode-hook | 1409 | (add-hook 'embark-collect-mode-hook |
831 | #'consult-preview-at-point-mode))) | 1410 | #'consult-preview-at-point-mode))) |
832 | 1411 | ||
833 | (setup encoding | ||
834 | (:option locale-coding-system 'utf-8-unix | ||
835 | coding-system-for-read 'utf-8-unix | ||
836 | coding-system-for-write 'utf-8-unix | ||
837 | buffer-file-coding-system 'utf-8-unix | ||
838 | default-process-coding-system '(utf-8-unix . utf-8-unix) | ||
839 | x-select-request-type '(UTF8_STRING | ||
840 | COMPOUND_TEXT | ||
841 | TEXT | ||
842 | STRING)) | ||
843 | |||
844 | (set-charset-priority 'unicode) | ||
845 | (set-language-environment "UTF-8") | ||
846 | (prefer-coding-system 'utf-8-unix) | ||
847 | (set-default-coding-systems 'utf-8-unix) | ||
848 | (set-terminal-coding-system 'utf-8-unix) | ||
849 | (set-keyboard-coding-system 'utf-8-unix) | ||
850 | |||
851 | (acdw/system | ||
852 | (:work (set-clipboard-coding-system 'utf-16-le) | ||
853 | (set-selection-coding-system 'utf-16-le)) | ||
854 | (_ (set-selection-coding-system 'utf-8) | ||
855 | (set-clipboard-coding-system 'utf-8)))) | ||
856 | |||
857 | (setup (:straight epithet) | 1412 | (setup (:straight epithet) |
858 | (dolist (hook '(Info-selection-hook | 1413 | (dolist (hook '(Info-selection-hook |
859 | eww-after-render-hook | 1414 | eww-after-render-hook |
@@ -905,52 +1460,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
905 | (:hook-into emacs-lisp-mode | 1460 | (:hook-into emacs-lisp-mode |
906 | lisp-interaction-mode)) | 1461 | lisp-interaction-mode)) |
907 | 1462 | ||
908 | (setup eshell | ||
909 | (:also-load acdw-eshell | ||
910 | em-smart | ||
911 | em-tramp) | ||
912 | |||
913 | (:option eshell-aliases-file (acdw/dir "eshell/aliases" t) | ||
914 | eshell-destroy-buffer-when-process-dies t | ||
915 | eshell-directory-name (acdw/dir "eshell/" t) | ||
916 | eshell-error-if-no-glob t | ||
917 | eshell-hist-ignore-dups t | ||
918 | eshell-kill-on-exit nil | ||
919 | eshell-prefer-lisp-functions t ; I want to try using eshell | ||
920 | eshell-prefer-lisp-variables t ; as much as possible. | ||
921 | eshell-review-quick-commands nil | ||
922 | eshell-save-history-on-exit t | ||
923 | eshell-scroll-to-bottom-on-input 'all | ||
924 | eshell-smart-space-goes-to-end t | ||
925 | eshell-where-to-jump 'begin) | ||
926 | |||
927 | (:local-set outline-regexp eshell-prompt-regexp | ||
928 | page-delimiter eshell-prompt-regexp) | ||
929 | |||
930 | (:bind "C-d" #'eshell-quit-or-delete-char) | ||
931 | |||
932 | (:hook #'eshell-arg-hist-mode | ||
933 | (defun eshell-mode@setup () | ||
934 | (unless (bound-and-true-p eshell-customizations-loaded) | ||
935 | (load (expand-file-name "eshell" user-emacs-directory)))))) | ||
936 | |||
937 | (setup eww | ||
938 | (defvar-local eww-readable-p nil | ||
939 | "Whether current buffer is in readable-mode.") | ||
940 | (:option eww-search-prefix "https://duckduckgo.com/html?q=" | ||
941 | url-privacy-level '(email agent cookies lastloc)) | ||
942 | |||
943 | (defun eww@is-readable (&rest _) | ||
944 | (setq-local eww-readable-p t)) | ||
945 | (defun eww@is-not-readable (&rest _) | ||
946 | (setq-local eww-readable-p nil)) | ||
947 | |||
948 | (advice-add 'eww-readable :after #'eww@is-readable) | ||
949 | (advice-add 'eww-render :after #'eww@is-not-readable) | ||
950 | (advice-add 'eww-back-url :after #'eww@is-not-readable) | ||
951 | |||
952 | (:hook #'reading-mode)) | ||
953 | |||
954 | (setup (:straight-if exec-path-from-shell | 1463 | (setup (:straight-if exec-path-from-shell |
955 | (acdw/system :home)) | 1464 | (acdw/system :home)) |
956 | (when (daemonp) | 1465 | (when (daemonp) |
@@ -964,87 +1473,6 @@ AKA, DO NOT USE THIS FUNCTION!!!" | |||
964 | (:autoload (fennel-repl :interactive t)) | 1473 | (:autoload (fennel-repl :interactive t)) |
965 | (:file-match (rx ".fnl" eos))) | 1474 | (:file-match (rx ".fnl" eos))) |
966 | 1475 | ||
967 | (setup files | ||
968 | (:option | ||
969 | auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t)) | ||
970 | auto-save-list-file-prefix (acdw/dir "auto-save-list/.saves-" t) | ||
971 | auto-save-interval 60 | ||
972 | auto-save-timeout 60 | ||
973 | auto-save-visited-interval auto-save-timeout | ||
974 | backup-by-copying t | ||
975 | backup-directory-alist `((".*" . ,(acdw/dir "backup/" t))) | ||
976 | delete-old-versions t | ||
977 | mode-require-final-newline 'visit-save | ||
978 | tramp-backup-directory-alist backup-directory-alist | ||
979 | vc-make-backup-files t | ||
980 | version-control t) | ||
981 | |||
982 | (auto-save-visited-mode +1)) | ||
983 | |||
984 | (setup find-func | ||
985 | (:global "C-c l f" #'find-function | ||
986 | "C-c l l" #'find-library | ||
987 | "C-c l v" #'find-variable)) | ||
988 | |||
989 | (setup flymake | ||
990 | |||
991 | (defvar-local flymake-inhibit nil | ||
992 | "Buffer-local variable to inhibit `flymake'.") | ||
993 | (add-to-list 'safe-local-variable-values '(flymake-inhibit . t)) | ||
994 | (add-to-list 'safe-local-variable-values '(flymake-inhibit . nil)) | ||
995 | |||
996 | (defvar flymake-inhibit-major-modes nil | ||
997 | "Which major-modes NOT to enable `flymake' in.") | ||
998 | |||
999 | (defvar flymake-inhibit-file-name-regexps '("init\\.el\\'" | ||
1000 | "early-init\\.el\\'") | ||
1001 | "List of file regexps NOT to enable `flymake' in.") | ||
1002 | |||
1003 | (defvar flymake-inhibit-buffer-name-regexps (list (rx "*scratch*")) | ||
1004 | "List of buffer-name regexps NOT to enable `flymake' in.") | ||
1005 | |||
1006 | (defun list-string-match-p (string regexp-list) | ||
1007 | "Return t if at least one regex in RETGEXP-LIST matches STRING, else nil." | ||
1008 | (when string ; if STRING is nil, return nil. | ||
1009 | (catch 'found | ||
1010 | (dolist (regexp regexp-list) | ||
1011 | (when (string-match regexp string) | ||
1012 | (throw 'found t)))))) | ||
1013 | |||
1014 | (defun flymake-unless () | ||
1015 | "Turn on `flymake-mode', UNLESS it's inhibited. | ||
1016 | There are three methods to inhibit flymake in a file. From most | ||
1017 | specific to most general, they are these: | ||
1018 | |||
1019 | - `flymake-inhibit': a file-local-variable | ||
1020 | |||
1021 | - `flymake-inhibit-buffer-name-regexps': a list of regexps to | ||
1022 | match the buffer name against. If one of them matches, inhibit | ||
1023 | `flymake-mode'. | ||
1024 | |||
1025 | - `flymake-inhibit-file-name-regexps': a list of regexps to match | ||
1026 | the filename against. If one of them matches, inhibit | ||
1027 | `flymake-mode'. | ||
1028 | |||
1029 | - `flymake-inhibit-major-modes': a list of major-modes in which | ||
1030 | to inhibit `flymake-mode'. Really only useful if you want to | ||
1031 | generally add `flymake-mode' to `prog-mode-hook'." | ||
1032 | (unless (or (bound-and-true-p flymake-inhibit) ; file-local variable | ||
1033 | (list-string-match-p (buffer-name) | ||
1034 | flymake-inhibit-buffer-name-regexps) | ||
1035 | (list-string-match-p (buffer-file-name) | ||
1036 | flymake-inhibit-file-name-regexps) | ||
1037 | (apply #'derived-mode-p flymake-inhibit-major-modes)) | ||
1038 | (flymake-mode-on))) | ||
1039 | |||
1040 | (add-hook 'prog-mode-hook #'flymake-unless) | ||
1041 | |||
1042 | (:bind "M-n" #'flymake-goto-next-error | ||
1043 | "M-p" #'flymake-goto-prev-error)) | ||
1044 | |||
1045 | (setup flyspell | ||
1046 | (:hook-into text-mode)) | ||
1047 | |||
1048 | (setup (:straight flyspell-correct) | 1476 | (setup (:straight flyspell-correct) |
1049 | (:option flyspell-correct-interface #'flyspell-correct-completing-read | 1477 | (:option flyspell-correct-interface #'flyspell-correct-completing-read |
1050 | flyspell-correct--cr-key ";") | 1478 | flyspell-correct--cr-key ";") |
@@ -1070,16 +1498,6 @@ specific to most general, they are these: | |||
1070 | '("tildegit.org" "tildegit.org/api/v1" "tildegit.org" | 1498 | '("tildegit.org" "tildegit.org/api/v1" "tildegit.org" |
1071 | forge-gitea-repository)))) | 1499 | forge-gitea-repository)))) |
1072 | 1500 | ||
1073 | (setup frames | ||
1074 | (:option frame-title-format '("%b@" | ||
1075 | (:eval | ||
1076 | (or (file-remote-p default-directory 'host) | ||
1077 | system-name)) | ||
1078 | " %+%* GNU Emacs" | ||
1079 | (:eval (when (frame-parameter nil 'client) | ||
1080 | " Client"))) | ||
1081 | window-resize-pixelwise t)) | ||
1082 | |||
1083 | (setup (:straight gcmh) | 1501 | (setup (:straight gcmh) |
1084 | (:option gcmh-idle-delay 'auto) | 1502 | (:option gcmh-idle-delay 'auto) |
1085 | (gcmh-mode +1)) | 1503 | (gcmh-mode +1)) |
@@ -1120,23 +1538,12 @@ specific to most general, they are these: | |||
1120 | (with-eval-after-load 'elpher | 1538 | (with-eval-after-load 'elpher |
1121 | (require 'gemini-write))) | 1539 | (require 'gemini-write))) |
1122 | 1540 | ||
1123 | (setup (:require gforth) | ||
1124 | (:autoload forth-mode | ||
1125 | forth-block-mode) | ||
1126 | (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode)) | ||
1127 | (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))) | ||
1128 | |||
1129 | (setup (:straight gitattributes-mode)) | 1541 | (setup (:straight gitattributes-mode)) |
1130 | 1542 | ||
1131 | (setup (:straight gitconfig-mode)) | 1543 | (setup (:straight gitconfig-mode)) |
1132 | 1544 | ||
1133 | (setup (:straight gitignore-mode)) | 1545 | (setup (:straight gitignore-mode)) |
1134 | 1546 | ||
1135 | (setup (:require goto-addr) | ||
1136 | (if (fboundp #'global-goto-address-mode) | ||
1137 | (global-goto-address-mode) | ||
1138 | (add-hook 'after-change-major-mode-hook #'goto-address-mode))) | ||
1139 | |||
1140 | (setup (:straight helpful) | 1547 | (setup (:straight helpful) |
1141 | (:require-after 3) | 1548 | (:require-after 3) |
1142 | 1549 | ||
@@ -1187,62 +1594,12 @@ specific to most general, they are these: | |||
1187 | (hungry-delete-forward (or arg 1)) | 1594 | (hungry-delete-forward (or arg 1)) |
1188 | (paredit-forward-delete arg)))))) | 1595 | (paredit-forward-delete arg)))))) |
1189 | 1596 | ||
1190 | (setup ibuffer | ||
1191 | (:also-load ibuf-ext) | ||
1192 | (:option ibuffer-expert t | ||
1193 | ibuffer-show-empty-filter-groups nil | ||
1194 | ibuffer-saved-filter-groups | ||
1195 | '(("default" | ||
1196 | ("dired" (mode . dired-mode)) | ||
1197 | ("customize" (mode . Custom-mode)) | ||
1198 | ("emacs" (or (name . "^\\*scratch\\*$") | ||
1199 | (name . "^\\*Messages\\*$") | ||
1200 | (name . "^\\*Warnings\\*$") | ||
1201 | (name . "^\\*straight-process\\*$") | ||
1202 | (name . "^\\*Calendar\\*$"))) | ||
1203 | ("git" (or (name . "^\*magit") | ||
1204 | (name . "^\magit"))) | ||
1205 | ("help" (or (mode . help-mode) | ||
1206 | (mode . Info-mode) | ||
1207 | (mode . helpful-mode))) | ||
1208 | ("messaging" (or (mode . message-mode) | ||
1209 | (mode . bbdb-mode) | ||
1210 | (mode . mail-mode) | ||
1211 | (mode . gnus-group-mode) | ||
1212 | (mode . gnus-summary-mode) | ||
1213 | (mode . gnus-article-mode) | ||
1214 | (name . "^\\.bbdb$") | ||
1215 | (name . "^\\.newsrc-dribble") | ||
1216 | (mode . erc-mode) | ||
1217 | (mode . circe-server-mode) | ||
1218 | (mode . circe-channel-mode))) | ||
1219 | ("shell" (or (mode . eshell-mode) | ||
1220 | (mode . shell-mode) | ||
1221 | (mode . vterm-mode))) | ||
1222 | ("web" (or (mode . elpher-mode) | ||
1223 | (mode . gemini-mode) | ||
1224 | (mode . eww-mode)))))) | ||
1225 | |||
1226 | (:global "C-x C-b" #'ibuffer) | ||
1227 | |||
1228 | (:hook (defun ibuffer@filter-to-default () | ||
1229 | (ibuffer-switch-to-saved-filter-groups "default")))) | ||
1230 | |||
1231 | (setup ielm | ||
1232 | (:hook #'turn-on-eldoc-mode)) | ||
1233 | |||
1234 | (setup imenu | ||
1235 | (:option imenu-auto-rescan t)) | ||
1236 | |||
1237 | (setup (:straight iscroll) | 1597 | (setup (:straight iscroll) |
1238 | (define-globalized-minor-mode global-iscroll-mode iscroll-mode | 1598 | (define-globalized-minor-mode global-iscroll-mode iscroll-mode |
1239 | (lambda () (iscroll-mode +1))) | 1599 | (lambda () (iscroll-mode +1))) |
1240 | 1600 | ||
1241 | (global-iscroll-mode +1)) | 1601 | (global-iscroll-mode +1)) |
1242 | 1602 | ||
1243 | (setup isearch | ||
1244 | (:option search-default-mode t)) | ||
1245 | |||
1246 | (setup (:straight (kaomoji-insert | 1603 | (setup (:straight (kaomoji-insert |
1247 | :host nil | 1604 | :host nil |
1248 | :repo "https://tildegit.org/acdw/kaomoji-insert")) | 1605 | :repo "https://tildegit.org/acdw/kaomoji-insert")) |
@@ -1262,29 +1619,6 @@ specific to most general, they are these: | |||
1262 | (setup (:straight-if ledger-mode | 1619 | (setup (:straight-if ledger-mode |
1263 | (executable-find "ledger"))) | 1620 | (executable-find "ledger"))) |
1264 | 1621 | ||
1265 | (setup lines | ||
1266 | (:option fill-column 79 | ||
1267 | word-wrap t | ||
1268 | truncate-lines nil) | ||
1269 | |||
1270 | (global-display-fill-column-indicator-mode +1) | ||
1271 | (global-so-long-mode +1) | ||
1272 | |||
1273 | (add-hook 'visual-line-mode-hook | ||
1274 | (defun acdw/disable-fill-column-indicator () | ||
1275 | (display-fill-column-indicator-mode | ||
1276 | (if visual-line-mode -1 +1)))) | ||
1277 | |||
1278 | ;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'. | ||
1279 | ;; I can't simply advise `kill-line' with an override from crux because crux | ||
1280 | ;; itself calls `kill-line', leading to a infinite nesting situation. | ||
1281 | (advice-add 'kill-line :around | ||
1282 | (defun kill-line@join (fn &rest args) | ||
1283 | (if (and (eolp) | ||
1284 | (not (bolp))) | ||
1285 | (delete-indentation 1) | ||
1286 | (apply fn args))))) | ||
1287 | |||
1288 | (setup (:straight link-hint) | 1622 | (setup (:straight link-hint) |
1289 | ;; Browse web URLs with a browser with a prefix argument. | 1623 | ;; Browse web URLs with a browser with a prefix argument. |
1290 | (dolist (type '(gnus-w3m-image-url | 1624 | (dolist (type '(gnus-w3m-image-url |
@@ -1369,29 +1703,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1369 | (:hook #'hl-line-mode | 1703 | (:hook #'hl-line-mode |
1370 | #'reading-mode)) | 1704 | #'reading-mode)) |
1371 | 1705 | ||
1372 | (setup minibuffer | ||
1373 | (:option enable-recursive-minibuffers t | ||
1374 | file-name-shadow-properties '(invisible t intangible t) | ||
1375 | minibuffer-eldef-shorten-default t | ||
1376 | minibuffer-prompt-properties | ||
1377 | '(read-only t cursor-intangible t face minibuffer-prompt) | ||
1378 | read-answer-short t | ||
1379 | read-extended-command-predicate ; used on >28 | ||
1380 | #'command-completion-default-include-p) | ||
1381 | |||
1382 | (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) | ||
1383 | |||
1384 | (add-hook 'minibuffer-setup-hook #'acdw/gc-disable) | ||
1385 | (add-hook 'minibuffer-exit-hook #'acdw/gc-enable) | ||
1386 | |||
1387 | (minibuffer-depth-indicate-mode +1) | ||
1388 | (file-name-shadow-mode +1) | ||
1389 | (minibuffer-electric-default-mode +1) | ||
1390 | |||
1391 | (if (version< emacs-version "28") | ||
1392 | (fset 'yes-or-no-p #'y-or-n-p) | ||
1393 | (setq use-short-answers t))) | ||
1394 | |||
1395 | (setup (:straight (modus-themes | 1706 | (setup (:straight (modus-themes |
1396 | :host gitlab | 1707 | :host gitlab |
1397 | :repo "protesilaos/modus-themes")) | 1708 | :repo "protesilaos/modus-themes")) |
@@ -1406,9 +1717,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1406 | (acdw/sunrise-sunset #'modus-themes-load-operandi | 1717 | (acdw/sunrise-sunset #'modus-themes-load-operandi |
1407 | #'modus-themes-load-vivendi)) | 1718 | #'modus-themes-load-vivendi)) |
1408 | 1719 | ||
1409 | (setup mouse-avoidance | ||
1410 | (mouse-avoidance-mode 'exile)) | ||
1411 | |||
1412 | (setup (:straight mwim) | 1720 | (setup (:straight mwim) |
1413 | (:global "C-a" #'mwim-beginning | 1721 | (:global "C-a" #'mwim-beginning |
1414 | "C-e" #'mwim-end)) | 1722 | "C-e" #'mwim-end)) |
@@ -1572,35 +1880,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1572 | 1880 | ||
1573 | (setup (:straight package-lint-flymake)) | 1881 | (setup (:straight package-lint-flymake)) |
1574 | 1882 | ||
1575 | (setup page | ||
1576 | (:option page-delimiter | ||
1577 | (rx bol (or "\f" ";;;") | ||
1578 | (not (any "#")) (* not-newline) "\n" | ||
1579 | (* (* blank) (opt ";" (* not-newline)) "\n"))) | ||
1580 | |||
1581 | (defun recenter-to-top (&rest _) | ||
1582 | "Recenter the cursor to the top of the window." | ||
1583 | (when (called-interactively-p 'any) | ||
1584 | (recenter (if (or (null scroll-margin) | ||
1585 | (zerop scroll-margin)) | ||
1586 | 3 | ||
1587 | scroll-margin)))) | ||
1588 | |||
1589 | (:advise forward-page :after #'recenter-to-top | ||
1590 | backward-page :after #'recenter-to-top) | ||
1591 | |||
1592 | ;; I'm not sure where this is in /my/ version of Emacs | ||
1593 | ;; (defvar page-navigation-repeat-map | ||
1594 | ;; (let ((map (make-sparse-keymap))) | ||
1595 | ;; (define-key map "]" #'forward-page) | ||
1596 | ;; (define-key map "[" #'backward-page) | ||
1597 | ;; map) | ||
1598 | ;; "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.") | ||
1599 | |||
1600 | ;; (put 'forward-page 'repeat-map 'page-navigation-repeat-map) | ||
1601 | ;; (put 'backward-page 'repeat-map 'page-navigation-repeat-map) | ||
1602 | ) | ||
1603 | |||
1604 | (setup (:straight page-break-lines) | 1883 | (setup (:straight page-break-lines) |
1605 | (global-page-break-lines-mode +1)) | 1884 | (global-page-break-lines-mode +1)) |
1606 | 1885 | ||
@@ -1658,44 +1937,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1658 | (dolist (mode lispy-modes) | 1937 | (dolist (mode lispy-modes) |
1659 | (add-hook (intern (format "%s-hook" mode)) #'prism-mode))) | 1938 | (add-hook (intern (format "%s-hook" mode)) #'prism-mode))) |
1660 | 1939 | ||
1661 | (setup prog | ||
1662 | (:option show-paren-delay 0 | ||
1663 | show-paren-style 'mixed | ||
1664 | show-paren-when-point-inside-paren t | ||
1665 | show-paren-when-point-in-periphery t | ||
1666 | smie-indent-basic tab-width) | ||
1667 | |||
1668 | (:hook show-paren-mode | ||
1669 | electric-pair-local-mode | ||
1670 | acdw/setup-fringes | ||
1671 | |||
1672 | (defun prog-mode@auto-fill () | ||
1673 | (setq-local comment-auto-fill-only-comments t) | ||
1674 | (turn-on-auto-fill))) | ||
1675 | |||
1676 | (add-hook 'after-save-hook | ||
1677 | #'executable-make-buffer-file-executable-if-script-p)) | ||
1678 | |||
1679 | (setup (:require recentf) | ||
1680 | (:option recentf-save-file (acdw/dir "recentf.el") | ||
1681 | recentf-max-menu-items 100 | ||
1682 | recentf-max-saved-items nil | ||
1683 | recentf-auto-cleanup 'mode | ||
1684 | (append recentf-exclude) (acdw/dir)) | ||
1685 | |||
1686 | (:advise dired-rename-file :after #'rjs/recentf-rename-notify) | ||
1687 | |||
1688 | (recentf-mode +1)) | ||
1689 | |||
1690 | (setup repeat | ||
1691 | ;; new for Emacs 28! | ||
1692 | (:only-if (fboundp #'repeat-mode)) | ||
1693 | |||
1694 | (:option repeat-exit-key "g" | ||
1695 | repeat-exit-timeout 5) | ||
1696 | |||
1697 | (repeat-mode +1)) | ||
1698 | |||
1699 | (setup (:straight restart-emacs) | 1940 | (setup (:straight restart-emacs) |
1700 | (defun emacs-upgrade (&optional update-packages) | 1941 | (defun emacs-upgrade (&optional update-packages) |
1701 | "Pull config, upgrade packages, restart Emacs." | 1942 | "Pull config, upgrade packages, restart Emacs." |
@@ -1706,93 +1947,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1706 | (straight-x-pull-all)) | 1947 | (straight-x-pull-all)) |
1707 | (restart-emacs))) | 1948 | (restart-emacs))) |
1708 | 1949 | ||
1709 | (setup (:require savehist) | ||
1710 | (:option history-length t | ||
1711 | history-delete-duplicates t | ||
1712 | savehist-autosave-interval 60 | ||
1713 | savehist-file (acdw/dir "savehist.el")) | ||
1714 | |||
1715 | (dolist (var '(extended-command-history | ||
1716 | global-mark-ring | ||
1717 | kill-ring | ||
1718 | regexp-search-ring | ||
1719 | search-ring | ||
1720 | mark-ring)) | ||
1721 | (:option (append savehist-additional-variables) var)) | ||
1722 | |||
1723 | (savehist-mode +1)) | ||
1724 | |||
1725 | (setup saveplace | ||
1726 | (:option save-place-file (acdw/dir "places.el") | ||
1727 | save-place-forget-unreadable-files (acdw/system :home)) | ||
1728 | |||
1729 | (save-place-mode +1)) | ||
1730 | |||
1731 | (setup scratch | ||
1732 | (:option inhibit-startup-screen t | ||
1733 | initial-buffer-choice t | ||
1734 | initial-scratch-message "" | ||
1735 | ;; (concat ";; Howdy, " | ||
1736 | ;; (nth 0 (split-string | ||
1737 | ;; user-full-name)) | ||
1738 | ;; "! " | ||
1739 | ;; "Welcome to GNU Emacs.\n\n") | ||
1740 | ) | ||
1741 | |||
1742 | (add-hook 'kill-buffer-query-functions | ||
1743 | (defun kill-buffer-query@immortal-scratch () | ||
1744 | (if (eq (current-buffer) (get-buffer "*scratch*")) | ||
1745 | (progn (bury-buffer) | ||
1746 | nil) | ||
1747 | t)))) | ||
1748 | |||
1749 | (setup scrolling | ||
1750 | (:option auto-window-vscroll nil | ||
1751 | fast-but-imprecise-scrolling t | ||
1752 | scroll-margin 3 | ||
1753 | scroll-conservatively 101 | ||
1754 | scroll-preserve-screen-position 1)) | ||
1755 | |||
1756 | (setup selection | ||
1757 | (:option save-interprogram-paste-before-kill t | ||
1758 | yank-pop-change-selection t | ||
1759 | x-select-enable-clipboard t | ||
1760 | x-select-enable-primary t | ||
1761 | mouse-drag-copy-region t | ||
1762 | kill-do-not-save-duplicates t) | ||
1763 | |||
1764 | (delete-selection-mode +1)) | ||
1765 | |||
1766 | (setup (:require server) | ||
1767 | (unless (server-running-p) | ||
1768 | (server-start))) | ||
1769 | |||
1770 | (setup sh-mode | ||
1771 | (:option sh-basic-offset tab-width | ||
1772 | sh-indent-after-case 0 | ||
1773 | sh-indent-for-case-alt '+ | ||
1774 | sh-indent-for-case-label 0) | ||
1775 | |||
1776 | (:local-set indent-tabs-mode t) | ||
1777 | |||
1778 | (when (executable-find "shfmt") | ||
1779 | (with-eval-after-load 'apheleia | ||
1780 | (:option (append apheleia-formatters) '(shfmt . ("shfmt")) | ||
1781 | (append apheleia-mode-alist) '(sh-mode . shfmt)))) | ||
1782 | |||
1783 | (when (executable-find "shellcheck") | ||
1784 | (:straight flymake-shellcheck) | ||
1785 | (:hook flymake-mode | ||
1786 | flymake-shellcheck-load))) | ||
1787 | |||
1788 | (setup shell-command | ||
1789 | (:option shell-command-switch (acdw/system | ||
1790 | ;; I should be testing on some variable | ||
1791 | (:home "-csi") | ||
1792 | (:work "-c")) | ||
1793 | shell-command-prompt-show-cwd t | ||
1794 | shell-command-default-error-buffer "*shell-command-errors*")) | ||
1795 | |||
1796 | (setup (:straight (shell-command+ | 1950 | (setup (:straight (shell-command+ |
1797 | :host nil | 1951 | :host nil |
1798 | :repo "https://git.sr.ht/~pkal/shell-command-plus")) | 1952 | :repo "https://git.sr.ht/~pkal/shell-command-plus")) |
@@ -1801,14 +1955,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1801 | (:bind "M-!" shell-command+)) | 1955 | (:bind "M-!" shell-command+)) |
1802 | (:global "M-!" shell-command+)) | 1956 | (:global "M-!" shell-command+)) |
1803 | 1957 | ||
1804 | (setup shr | ||
1805 | (:option shr-width fill-column | ||
1806 | shr-max-width fill-column | ||
1807 | shr-max-image-proportion 0.6 | ||
1808 | shr-image-animate t | ||
1809 | shr-discard-aria-hidden t | ||
1810 | shr-folding-mode t)) | ||
1811 | |||
1812 | (setup (:straight simple-modeline | 1958 | (setup (:straight simple-modeline |
1813 | minions) | 1959 | minions) |
1814 | (:also-load acdw-modeline) | 1960 | (:also-load acdw-modeline) |
@@ -1897,11 +2043,6 @@ browser defined in `browse-url-secondary-browser-function'." | |||
1897 | (setup (:straight-if systemd | 2043 | (setup (:straight-if systemd |
1898 | (executable-find "systemd"))) | 2044 | (executable-find "systemd"))) |
1899 | 2045 | ||
1900 | (setup text | ||
1901 | (:hook turn-on-auto-fill | ||
1902 | tildify-mode | ||
1903 | acdw/setup-fringes)) | ||
1904 | |||
1905 | (setup (:straight (topsy | 2046 | (setup (:straight (topsy |
1906 | :host github | 2047 | :host github |
1907 | :repo "alphapapa/topsy.el")) | 2048 | :repo "alphapapa/topsy.el")) |
@@ -1965,20 +2106,6 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
1965 | (save-some-buffers t)) | 2106 | (save-some-buffers t)) |
1966 | #'garbage-collect))) | 2107 | #'garbage-collect))) |
1967 | 2108 | ||
1968 | (setup uniquify | ||
1969 | (:option uniquify-buffer-name-style 'forward | ||
1970 | uniquify-separator path-separator | ||
1971 | uniquify-after-kill-buffer-p t | ||
1972 | uniquify-ignore-buffers-re "^\\*")) | ||
1973 | |||
1974 | (setup variable-pitch-mode | ||
1975 | ;; I might want to change this to `buffer-face-mode-hook'... | ||
1976 | (:advise variable-pitch-mode :after | ||
1977 | (defun variable-pitch-mode@setup (&rest _) | ||
1978 | "Set up `variable-pitch-mode' with my customizations." | ||
1979 | (display-fill-column-indicator-mode | ||
1980 | (if buffer-face-mode -1 +1))))) | ||
1981 | |||
1982 | (setup (:straight (vertico | 2109 | (setup (:straight (vertico |
1983 | :host github | 2110 | :host github |
1984 | :repo "minad/vertico" | 2111 | :repo "minad/vertico" |
@@ -2016,12 +2143,6 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
2016 | " ") | 2143 | " ") |
2017 | cand)))) | 2144 | cand)))) |
2018 | 2145 | ||
2019 | (setup view | ||
2020 | (:option view-read-only t) | ||
2021 | |||
2022 | (:hook (defun acdw/read-view-mode () | ||
2023 | (reading-mode (if view-mode +1 -1))))) | ||
2024 | |||
2025 | (setup (:straight visual-regexp) | 2146 | (setup (:straight visual-regexp) |
2026 | (:global "M-%" #'vr/query-replace)) | 2147 | (:global "M-%" #'vr/query-replace)) |
2027 | 2148 | ||
@@ -2033,15 +2154,6 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
2033 | (eshell-vterm-mode +1) | 2154 | (eshell-vterm-mode +1) |
2034 | (defalias 'eshell/v 'eshell-exec-visual)) | 2155 | (defalias 'eshell/v 'eshell-exec-visual)) |
2035 | 2156 | ||
2036 | (setup w32 | ||
2037 | (:option w32-allow-system-shell t | ||
2038 | w32-pass-lwindow-to-system nil | ||
2039 | w32-lwindow-modifier 'super | ||
2040 | w32-pass-rwindow-to-system nil | ||
2041 | w32-rwindow-modifier 'super | ||
2042 | w32-pass-apps-to-system nil | ||
2043 | w32-apps-modifier 'hyper)) | ||
2044 | |||
2045 | (setup (:straight wc-mode) | 2157 | (setup (:straight wc-mode) |
2046 | (:option wc-modeline-format "[%tww]" | 2158 | (:option wc-modeline-format "[%tww]" |
2047 | wc-idle-wait 2) | 2159 | wc-idle-wait 2) |
@@ -2072,101 +2184,9 @@ If used with a numeric prefix argument N, N backticks will be inserted." | |||
2072 | (which-key-setup-side-window-right-bottom) | 2184 | (which-key-setup-side-window-right-bottom) |
2073 | (which-key-mode +1)) | 2185 | (which-key-mode +1)) |
2074 | 2186 | ||
2075 | (setup whitespace | ||
2076 | (:option whitespace-style '(empty | ||
2077 | indentation | ||
2078 | space-before-tab | ||
2079 | space-after-tab) | ||
2080 | indent-tabs-mode nil | ||
2081 | tab-width 4 | ||
2082 | backward-delete-char-untabify-method 'hungry) | ||
2083 | |||
2084 | (:global "M-SPC" #'cycle-spacing)) | ||
2085 | |||
2086 | (setup (:straight whitespace-cleanup-mode) | 2187 | (setup (:straight whitespace-cleanup-mode) |
2087 | (global-whitespace-cleanup-mode +1)) | 2188 | (global-whitespace-cleanup-mode +1)) |
2088 | 2189 | ||
2089 | (setup windmove | ||
2090 | (:option windmove-wrap-around t) | ||
2091 | (:global | ||
2092 | ;; moving | ||
2093 | "C-x 4 <left>" #'windmove-left | ||
2094 | "C-x 4 <right>" #'windmove-right | ||
2095 | "C-x 4 <up>" #'windmove-up | ||
2096 | "C-x 4 <down>" #'windmove-down | ||
2097 | ;; swapping | ||
2098 | "C-x 4 S-<left>" #'windmove-swap-states-left | ||
2099 | "C-x 4 S-<right>" #'windmove-swap-states-right | ||
2100 | "C-x 4 S-<up>" #'windmove-swap-states-up | ||
2101 | "C-x 4 S-<down>" #'windmove-swap-states-down) | ||
2102 | |||
2103 | ;; (when (fboundp 'repeat-mode) | ||
2104 | ;; (defvar windmove-repeat-map | ||
2105 | ;; (let ((map (make-sparse-keymap))) | ||
2106 | ;; ;; moving | ||
2107 | ;; (define-key map [left] #'windmove-left) | ||
2108 | ;; (define-key map [right] #'windmove-right) | ||
2109 | ;; (define-key map [up] #'windmove-up) | ||
2110 | ;; (define-key map [down] #'windmove-down) | ||
2111 | ;; ;; swapping | ||
2112 | ;; (define-key map [S-left] #'windmove-swap-states-left) | ||
2113 | ;; (define-key map [S-right] #'windmove-swap-states-right) | ||
2114 | ;; (define-key map [S-up] #'windmove-swap-states-up) | ||
2115 | ;; (define-key map [S-down] #'windmove-swap-states-down) | ||
2116 | ;; map) | ||
2117 | ;; "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.") | ||
2118 | |||
2119 | ;; (dolist (sym '(windmove-left | ||
2120 | ;; windmove-right | ||
2121 | ;; windmove-up | ||
2122 | ;; windmove-down | ||
2123 | ;; windmove-swap-states-left | ||
2124 | ;; windmove-swap-states-right | ||
2125 | ;; windmove-swap-states-up | ||
2126 | ;; windmove-swap-states-down)) | ||
2127 | ;; (put sym 'repeat-map 'windmove-repeat-map))) | ||
2128 | ) | ||
2129 | |||
2130 | (setup window | ||
2131 | (require 'acdw-bell) | ||
2132 | (:option | ||
2133 | ;; Man-notify-method 'pushy | ||
2134 | ;; display-buffer-alist ; from FrostyX | ||
2135 | ;; '(("shell.*" (display-buffer-same-window) ()) | ||
2136 | ;; (".*" (display-buffer-reuse-window | ||
2137 | ;; display-buffer-same-window) | ||
2138 | ;; (reusable-frames . t))) | ||
2139 | recenter-positions '(top middle bottom) | ||
2140 | ring-bell-function (lambda () | ||
2141 | (acdw-bell/flash-mode-line | ||
2142 | (acdw/system :home))) | ||
2143 | use-dialog-box nil | ||
2144 | use-file-dialog nil | ||
2145 | visible-bell nil) | ||
2146 | |||
2147 | (tooltip-mode -1)) | ||
2148 | |||
2149 | (setup winner | ||
2150 | ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html | ||
2151 | (:global "C-x 4 C-/" #'winner-undo | ||
2152 | "C-x 4 /" #'winner-undo | ||
2153 | "C-x 4 C-?" #'winner-redo | ||
2154 | "C-x 4 ?" #'winner-redo) | ||
2155 | |||
2156 | ;; add `winner-undo' and `winner-redo' to `repeat-mode' | ||
2157 | ;; (when (fboundp 'repeat-mode) | ||
2158 | ;; (defvar winner-mode-repeat-map | ||
2159 | ;; (let ((map (make-sparse-keymap))) | ||
2160 | ;; (define-key map "/" #'winner-undo) | ||
2161 | ;; (define-key map "?" #'winner-redo) | ||
2162 | ;; map) | ||
2163 | ;; "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.") | ||
2164 | |||
2165 | ;; (put 'winner-undo 'repeat-map 'winner-mode-repeat-map) | ||
2166 | ;; (put 'winner-redo 'repeat-map 'winner-mode-repeat-map)) | ||
2167 | |||
2168 | (winner-mode +1)) | ||
2169 | |||
2170 | (setup (:straight winum) | 2190 | (setup (:straight winum) |
2171 | (:option winum-scope 'frame-local | 2191 | (:option winum-scope 'frame-local |
2172 | winum-auto-setup-mode-line nil | 2192 | winum-auto-setup-mode-line nil |
diff --git a/lisp/acdw.el b/lisp/acdw.el index 0790f2e..472b4ab 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el | |||
@@ -265,10 +265,16 @@ With a prefix argument N, (un)comment that many sexps." | |||
265 | ;; from https://github.com/alphapapa/unpackaged.el#sort-sexps | 265 | ;; from https://github.com/alphapapa/unpackaged.el#sort-sexps |
266 | ;; and https://github.com/alphapapa/unpackaged.el/issues/20 | 266 | ;; and https://github.com/alphapapa/unpackaged.el/issues/20 |
267 | 267 | ||
268 | (defun sort-sexps (beg end &optional key) | 268 | (defun sort-sexps (beg end &optional key-fn sort-fn) |
269 | "Sort sexps between BEG and END. | 269 | "Sort sexps between BEG and END. |
270 | Comments stay with the code below. KEY is a function to sort by, | 270 | Comments stay with the code below. |
271 | e.g. (lambda (sexp) (symbol-name (car sexp)))" | 271 | |
272 | Optional argument KEY-FN will determine where in each sexp to | ||
273 | start sorting. e.g. (lambda (sexp) (symbol-name (car sexp))) | ||
274 | |||
275 | Optional argument SORT-FN will determine how to sort two sexps' | ||
276 | strings. It's passed to `sort'. By default, it sorts the sexps | ||
277 | with `string<' starting with the key determined by KEY-FN." | ||
272 | (interactive "r") | 278 | (interactive "r") |
273 | (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n")))) | 279 | (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n")))) |
274 | (goto-char (match-end 0)))) | 280 | (goto-char (match-end 0)))) |
@@ -298,8 +304,8 @@ e.g. (lambda (sexp) (symbol-name (car sexp)))" | |||
298 | (save-excursion | 304 | (save-excursion |
299 | (goto-char (marker-position start)) | 305 | (goto-char (marker-position start)) |
300 | (skip-both) | 306 | (skip-both) |
301 | (if key | 307 | (if key-fn |
302 | (funcall key sexp) | 308 | (funcall key-fn sexp) |
303 | (buffer-substring | 309 | (buffer-substring |
304 | (point) | 310 | (point) |
305 | (marker-position end))))) | 311 | (marker-position end))))) |
@@ -307,8 +313,9 @@ e.g. (lambda (sexp) (symbol-name (car sexp)))" | |||
307 | collect (cons start end) | 313 | collect (cons start end) |
308 | into markers | 314 | into markers |
309 | finally return (list sexps markers)) | 315 | finally return (list sexps markers)) |
310 | (setq sexps (sort sexps (lambda (a b) | 316 | (setq sexps (sort sexps (if sort-fn sort-fn |
311 | (string< (cdr a) (cdr b))))) | 317 | (lambda (a b) |
318 | (string< (cdr a) (cdr b)))))) | ||
312 | (cl-loop for (real . sort) in sexps | 319 | (cl-loop for (real . sort) in sexps |
313 | for (start . end) in markers | 320 | for (start . end) in markers |
314 | do (progn | 321 | do (progn |