about summary refs log tree commit diff stats
path: root/init.el
diff options
context:
space:
mode:
authorCase Duckworth2021-09-16 08:41:56 -0500
committerCase Duckworth2021-09-16 08:41:56 -0500
commitea9749918dc13799b2ddef42c86c95ce2d0cb4ad (patch)
treed0de90be2c8fbbdf431ca9275ecc37c0a4d26b95 /init.el
parentIndentation (diff)
parentRemove gforth setup (diff)
downloademacs-ea9749918dc13799b2ddef42c86c95ce2d0cb4ad.tar.gz
emacs-ea9749918dc13799b2ddef42c86c95ce2d0cb4ad.zip
Merge branch 'main' of tildegit.org:acdw/emacs
Diffstat (limited to 'init.el')
-rw-r--r--init.el1737
1 files changed, 972 insertions, 765 deletions
diff --git a/init.el b/init.el index 771f73c..b0d9d77 100644 --- a/init.el +++ b/init.el
@@ -20,10 +20,44 @@
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 goto-addr)
27 (if (fboundp #'global-goto-address-mode)
28 (global-goto-address-mode)
29 (add-hook 'after-change-major-mode-hook #'goto-address-mode)))
30
31(setup (:require recentf)
32 (:option recentf-save-file (acdw/dir "recentf.el")
33 recentf-max-menu-items 100
34 recentf-max-saved-items nil
35 recentf-auto-cleanup 'mode
36 (append recentf-exclude) (acdw/dir))
37
38 (:advise dired-rename-file :after #'rjs/recentf-rename-notify)
39
40 (recentf-mode +1))
41
42(setup (:require savehist)
43 (:option history-length t
44 history-delete-duplicates t
45 savehist-autosave-interval 60
46 savehist-file (acdw/dir "savehist.el"))
47
48 (dolist (var '(extended-command-history
49 global-mark-ring
50 kill-ring
51 regexp-search-ring
52 search-ring
53 mark-ring))
54 (:option (append savehist-additional-variables) var))
55
56 (savehist-mode +1))
57
58(setup (:require server)
59 (unless (server-running-p)
60 (server-start)))
27 61
28(setup Info 62(setup Info
29 (:hook #'variable-pitch-mode 63 (:hook #'variable-pitch-mode
@@ -51,79 +85,45 @@
51 (defun acdw/sort-setups () 85 (defun acdw/sort-setups ()
52 "Sort `setup' forms in the current buffer. 86 "Sort `setup' forms in the current buffer.
53Actually sorts all forms, but based on the logic of `setup'. 87Actually sorts all forms, but based on the logic of `setup'.
54AKA, DO NOT USE THIS FUNCTION!!!" 88In short, DO NOT USE THIS FUNCTION!!!"
55 (save-excursion 89 (save-excursion
56 (sort-sexps (point-min) (point-max) 90 (sort-sexps
57 (lambda (sexp) 91 (point-min) (point-max)
58 (let ((name (cadr sexp))) 92 (lambda (sexp)
59 (symbol-name (if (listp name) ; this is /terrible/! 93 (format "%S" (cadr sexp)))
60 (if (keywordp (car name)) 94 (lambda (s1 s2) ; oh god, this is worse.
61 (let ((feature (cadr name))) 95 (let* ((s1 (cdr s1)) (s2 (cdr s2)) ; for the strings themselves
62 (if (listp feature) 96 (s1-require (string-match ":require" s1))
63 (car feature) 97 (s2-require (string-match ":require" s2))
64 feature)) 98 (s1-straight (string-match ":straight" s1))
65 (car name)) 99 (s2-straight (string-match ":straight" s2))
66 name)))))))) 100 (s1-bare (not (or s1-require s1-straight)))
67 101 (s2-bare (not (or s2-require s2-straight))))
68(setup (:straight-if affe 102 (cond
69 (and (or (executable-find "fd") 103 ;; if both are the same, sort regular style
70 (executable-find "find")) 104 ((or (and s1-require s2-require)
71 (executable-find "rg"))) 105 (and s1-bare s2-bare))
72 ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find' 106 (string< s1 s2))
73 (:option affe-regexp-compiler 107 ((and s1-straight s2-straight)
74 (defun affe-orderless-regexp-compiler (input _type) 108 (let* ((r (rx ":straight" (? "-if") (* space) (? "(")))
75 (setq input (orderless-pattern-compiler input)) 109 (s1 (replace-regexp-in-string r "" s1))
76 (cons input (lambda (str) (orderless--highlight input str)))))) 110 (s2 (replace-regexp-in-string r "" s2)))
77 111 (message "'%S' '%S'" s1 s2)
78(setup (:straight-if ahk-mode 112 (string< s1 s2)))
79 (acdw/system :work))) 113 ;; requires should go first
80 114 ((and s1-require (not s2-require)) t)
81(setup (:straight alert) 115 ((and (not s1-require) s2-require) nil)
82 (:option alert-default-style (acdw/system 116 ;; straights should go last
83 (:home 'libnotify) 117 ((and s1-straight (not s2-straight)) nil)
84 (_ 'message)))) 118 ((and (not s1-straight) s2-straight) t)
85 119 ;; else, just sort em.
86(setup (:straight (apheleia 120 (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 121
115(setup autorevert 122(setup autorevert
116 (:option global-auto-revert-non-file-buffers t 123 (:option global-auto-revert-non-file-buffers t
117 auto-revert-verbose nil) 124 auto-revert-verbose nil)
118 (global-auto-revert-mode +1)) 125 (global-auto-revert-mode +1))
119 126
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 127(setup browse-url
128 (:require acdw-browse-url) 128 (:require acdw-browse-url)
129 129
@@ -338,104 +338,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
338 338
339 (:global "M-/" #'hippie-expand)) 339 (:global "M-/" #'hippie-expand))
340 340
341(setup (:straight (consult
342 :host github
343 :repo "minad/consult"))
344
345 (:require acdw-consult)
346 (:autoload consult-register-preview)
347
348 ;; Bindings
349 (:global
350 ;; C-c bindings (`mode-specific-map')
351 ;; I don't use any of these right now.
352 ;; "C-c h" #'consult-history
353 ;; "C-c m" #'consult-mode-command
354 ;; "C-c b" #'consult-bookmark
355 ;; "C-c k" #'consult-kmacro
356 ;; C-x bindings (`ctl-x-map')
357 "C-x M-:" #'consult-complex-command
358 "C-x b" #'consult-buffer
359 "C-x 4 b" #'consult-buffer-other-window
360 "C-x 5 b" #'consult-buffer-other-frame
361 ;; Custom M-# bindings for fast register access
362 "M-#" #'consult-register-load
363 "M-'" #'consult-register-store
364 "C-M-#" #'consult-register
365 ;; M-g bindings (`goto-map')
366 "M-g e" #'consult-compile-error
367 "M-g g" #'consult-goto-line
368 "M-g M-g" #'consult-goto-line
369 "M-g o" #'consult-outline
370 "M-g m" #'consult-mark
371 "M-g k" #'consult-global-mark
372 "M-g i" #'consult-imenu
373 "M-g I" #'consult-project-imenu
374 ;; M-s bindings (`search-map')
375 "M-s g" #'acdw-consult/sensible-grep
376 "M-s f" #'acdw-consult/sensible-find
377 "M-s l" #'consult-line
378 "M-s m" #'consult-multi-occur
379 "M-s k" #'consult-keep-lines
380 "M-s u" #'consult-focus-lines
381 ;; Other bindings
382 "M-y" #'consult-yank-pop
383 "<help> a" #'consult-apropos
384 ;; Isearch integration
385 "M-s e" #'consult-isearch)
386
387 (:with-map isearch-mode-map
388 (:bind "M-e" #'consult-isearch
389 "M-s e" #'consult-isearch
390 "M-s l" #'consult-line))
391
392 (consult-history-to-modes ((minibuffer-local-map . nil)
393 (shell-mode-map . shell-mode-hook)
394 (term-mode-map . term-mode-hook)
395 (term-raw-map . term-mode-hook)
396 (comint-mode-map . comint-mode-hook)
397 (sly-mrepl-mode-map . sly-mrepl-hook)))
398
399 (:option register-preview-delay 0
400 register-preview-function #'consult-register-format
401 xref-show-xrefs-function #'consult-xref
402 xref-show-definitions-function #'consult-xref
403 consult-project-root-function #'vc-root-dir
404 completion-in-region-function #'acdw-consult/complete-in-region
405 completion-cycle-threshold 3
406 consult-preview-key (kbd "M-.")
407 tab-always-indent 'complete)
408
409 (:advise register-preview :override #'consult-register-window)
410
411 ;; Completing-read-multple
412 (if (fboundp #'consult-completing-read-multiple)
413 (:advise completing-read-multple :override
414 #'consult-completing-read-multiple)
415 (:advise completing-read-multiple :filter-args
416 (defun crm-indicator (args)
417 (cons (concat "[CRM] " (car args)) (cdr args)))))
418
419 (with-eval-after-load 'orderless
420 (:option consult--regexp-compiler
421 #'consult--orderless-regexp-compiler))
422
423 (with-eval-after-loads (vertico consult)
424 (:with-map consult-crm-map
425 (:bind "RET" (defun +vertico-crm-exit ()
426 (interactive)
427 (run-at-time 0 nil #'vertico-exit)
428 (funcall #'vertico-exit))
429 "TAB" #'vertico-exit))))
430
431(setup (:straight crux)
432 (:global "C-o" #'crux-smart-open-line
433 "M-o" #'crux-smart-open-line-above
434 "C-M-\\" #'crux-cleanup-buffer-or-region
435 "C-x 4 t" #'crux-transpose-windows)
436
437 (crux-reopen-as-root-mode +1))
438
439(setup cursor 341(setup cursor
440 (:option cursor-type 'bar 342 (:option cursor-type 'bar
441 cursor-in-non-selected-windows 'hollow 343 cursor-in-non-selected-windows 'hollow
@@ -489,50 +391,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
489(setup debugger 391(setup debugger
490 (:hook visual-line-mode)) 392 (:hook visual-line-mode))
491 393
492(setup (:straight-if (define-repeat-map
493 :host nil
494 :repo "https://tildegit.org/acdw/define-repeat-map.el")
495 (acdw/system :home))
496
497 (defun acdw/other-window-or-switch-buffer-backward ()
498 (interactive)
499 (setq repeat-map 'other-window-repeat-map)
500 (acdw/other-window-or-switch-buffer -1))
501
502 (define-repeat-map other-window
503 ("o" acdw/other-window-or-switch-buffer
504 "O" acdw/other-window-or-switch-buffer-backward))
505
506 (define-repeat-map case
507 ("c" capitalize-word
508 "u" upcase-dwim
509 "l" downcase-dwim)
510 (:continue "f" forward-word
511 "b" backward-word)
512 (:enter capitalize-dwim
513 upcase-dwim
514 downcase-dwim))
515
516 (define-repeat-map page-navigation
517 ("]" forward-page
518 "[" backward-page))
519
520 (define-repeat-map windmove
521 (;; moving
522 "<left>" windmove-left
523 "<right>" windmove-right
524 "<up>" windmove-up
525 "<down>" windmove-down
526 ;; swapping
527 "<S-left>" windmove-swap-states-left
528 "<S-right>" windmove-swap-states-right
529 "<S-up>" windmove-swap-states-up
530 "<S-down>" windmove-swap-states-down))
531
532 (define-repeat-map winner-mode
533 ("/" winner-undo
534 "?" winner-redo)))
535
536(setup dired 394(setup dired
537 (:also-load dired-x) 395 (:also-load dired-x)
538 (:straight dired-subtree 396 (:straight dired-subtree
@@ -648,46 +506,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
648 (:option eldoc-idle-delay 0.1 506 (:option eldoc-idle-delay 0.1
649 eldoc-echo-area-use-multiline-p nil)) 507 eldoc-echo-area-use-multiline-p nil))
650 508
651(setup (:straight (electric-cursor
652 :host github
653 :repo "duckwork/electric-cursor"))
654 (electric-cursor-mode +1))
655
656(setup (:straight elfeed
657 elfeed-protocol)
658 (:option elfeed-use-curl t
659 elfeed-feeds `(("fever+https://acdw@mf.acdw.net"
660 :api-url "https://mf.acdw.net/fever/"
661 :password ,(acdw/make-password-fetcher
662 :host "mf.acdw.net"))))
663
664 (elfeed-protocol-enable)
665 (:advise elfeed :after
666 (defun elfeed@protocol-update (&rest _)
667 (elfeed-search-fetch nil)))
668
669 (:face message-header-subject
670 ((t (:height 1.5))))
671
672 (:with-mode elfeed-show-mode
673 (:hook #'reading-mode)
674
675 ;; see https://irreal.org/blog/?p=8885
676 (:bind "SPC" (defun elfeed-scroll-up-command (&optional arg)
677 "Scroll up or go to next feed item in Elfeed"
678 (interactive "^P")
679 (let ((scroll-error-top-bottom nil))
680 (condition-case-unless-debug nil
681 (scroll-up-command arg)
682 (error (elfeed-show-next)))))
683 "S-SPC" (defun elfeed-scroll-down-command (&optional arg)
684 "Scroll up or go to next feed item in Elfeed"
685 (interactive "^P")
686 (let ((scroll-error-top-bottom nil))
687 (condition-case-unless-debug nil
688 (scroll-down-command arg)
689 (error (elfeed-show-prev))))))))
690
691(setup elisp-mode 509(setup elisp-mode
692 (:with-mode emacs-lisp-mode ;; -_- 510 (:with-mode emacs-lisp-mode ;; -_-
693 (:option eval-expression-print-length nil 511 (:option eval-expression-print-length nil
@@ -721,35 +539,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
721 "C-c C-k" #'acdw/eval-region-or-buffer 539 "C-c C-k" #'acdw/eval-region-or-buffer
722 "C-c C-z" #'ielm))) 540 "C-c C-z" #'ielm)))
723 541
724(setup (:straight elisp-slime-nav)
725 (:hook-into emacs-lisp-mode
726 ielm-mode))
727
728(setup (:straight (elpher
729 :host nil
730 :repo "git://thelambdalab.xyz/elpher.git"))
731 (:option elpher-ipv4-always t
732 elpher-certificate-directory (acdw/dir "elpher/")
733 elpher-gemini-max-fill-width fill-column)
734
735 (:bind "n" #'elpher-next-link
736 "p" #'elpher-prev-link
737 "o" #'elpher-follow-current-link
738 "G" #'elpher-go-current)
739
740 (:hook #'reading-mode)
741
742 (:autoload (elpher-bookmarks :interactive t)
743 (elpher-go :interactive t))
744
745 ;; Make `eww' gemini/gopher aware. From Emacswiki.
746 ;; (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher)
747 ;; (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
748 ;; (require 'elpher)
749 ;; (elpher-go url))
750 ;; (t (apply fn url args))))
751 )
752
753(setup emacs 542(setup emacs
754 ;; "Et cetera" settings 543 ;; "Et cetera" settings
755 ;; This should stay as /minimal/ as possible. Anything that can go somewhere 544 ;; This should stay as /minimal/ as possible. Anything that can go somewhere
@@ -814,29 +603,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
814 (unless (bound-and-true-p edit-server-frame-p) 603 (unless (bound-and-true-p edit-server-frame-p)
815 (toggle-frame-maximized frame))))) 604 (toggle-frame-maximized frame)))))
816 605
817(setup (:straight embark)
818 (:global "C-." #'embark-act)
819 (:option prefix-help-command #'embark-prefix-help-command
820 (append display-buffer-alist)
821 `(,(rx (seq bos "*Embark Collect "
822 (group (| "Live" "Completions"))
823 "*"))
824 nil
825 (window-parameters (mode-line-format . none)))
826 embark-prompter #'embark-keymap-prompter
827 embark-verbose-indicator-display-action
828 '(display-buffer-at-bottom (window-height . fit-window-to-buffer))
829 embark-action-indicator
830 (lambda (map _target)
831 (which-key--show-keymap "Embark" map nil nil 'no-paging)
832 #'which-key--hide--ignore-command)
833 embark-become-indicator embark-action-indicator)
834
835 (with-eval-after-loads (embark consult)
836 (:straight embark-consult)
837 (add-hook 'embark-collect-mode-hook
838 #'consult-preview-at-point-mode)))
839
840(setup encoding 606(setup encoding
841 (:option locale-coding-system 'utf-8-unix 607 (:option locale-coding-system 'utf-8-unix
842 coding-system-for-read 'utf-8-unix 608 coding-system-for-read 'utf-8-unix
@@ -861,57 +627,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
861 (_ (set-selection-coding-system 'utf-8) 627 (_ (set-selection-coding-system 'utf-8)
862 (set-clipboard-coding-system 'utf-8)))) 628 (set-clipboard-coding-system 'utf-8))))
863 629
864(setup (:straight epithet)
865 (dolist (hook '(Info-selection-hook
866 eww-after-render-hook
867 help-mode-hook
868 occur-mode-hook))
869 (add-hook hook #'epithet-rename-buffer)))
870
871;; TODO: look into emms or something related for this
872(setup (:straight-if eradio
873 (executable-find "mpv"))
874 (:option
875 eradio-player '("mpv" "--no-video" "--no-terminal")
876 eradio-channels `(("KLSU" .
877 "http://130.39.238.143:8010/stream.mp3")
878 ("Soma FM Synphaera" .
879 "https://somafm.com/synphaera256.pls")
880 ("SomaFM BAGel Radio" .
881 "https://somafm.com/bagel.pls")
882 ("SomaFM Boot Liquor" .
883 "https://somafm.com/bootliquor320.pls")
884 ("SomaFM Deep Space One" .
885 "https://somafm.com/deepspaceone.pls")
886 ("SomaFM Fluid" .
887 "https://somafm.com/fluid.pls")
888 ("SomaFM Underground 80s" .
889 "https://somafm.com/u80s256.pls")
890 ("WBRH: Jazz & More" .
891 "http://wbrh.streamguys1.com/wbrh-mp3")
892 ("KBRH Blues & Rhythm Hits" .
893 "http://wbrh.streamguys1.com/kbrh-mp3")
894 ("WRKF HD-2" .
895 ,(concat "https://playerservices.streamtheworld.com/"
896 "api/livestream-redirect/WRKFHD2.mp3"))
897 ("WRKF: NPR for the Capital Region" .
898 ,(concat "https://playerservices.streamtheworld.com/"
899 "api/livestream-redirect/WRKFFM.mp3"))
900 ("BadRadio: 24/7 PHONK" .
901 "https://s2.radio.co/s2b2b68744/listen")
902 ("tilderadio" .
903 "https://azuracast.tilderadio.org/radio/8000/radio.ogg")
904 ("vantaradio" .
905 "https://vantaa.black/radio")))
906 (:global "C-c r r" #'eradio-play ; mnemonic: radio
907 "C-c r s" #'eradio-stop ; mnemonic: stop
908 "C-c r p" #'eradio-toggle ; mnemonic: play/pause
909 ))
910
911(setup (:straight eros)
912 (:hook-into emacs-lisp-mode
913 lisp-interaction-mode))
914
915(setup eshell 630(setup eshell
916 (:also-load acdw-eshell 631 (:also-load acdw-eshell
917 em-smart 632 em-smart
@@ -958,19 +673,6 @@ AKA, DO NOT USE THIS FUNCTION!!!"
958 673
959 (:hook #'reading-mode)) 674 (:hook #'reading-mode))
960 675
961(setup (:straight-if exec-path-from-shell
962 (acdw/system :home))
963 (when (daemonp)
964 (exec-path-from-shell-initialize)))
965
966(setup (:straight expand-region)
967 (:global "C-=" #'er/expand-region))
968
969(setup (:straight-if fennel-mode
970 (executable-find "fennel"))
971 (:autoload (fennel-repl :interactive t))
972 (:file-match (rx ".fnl" eos)))
973
974(setup files 676(setup files
975 (:option 677 (:option
976 auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t)) 678 auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t))
@@ -1052,6 +754,886 @@ specific to most general, they are these:
1052(setup flyspell 754(setup flyspell
1053 (:hook-into text-mode)) 755 (:hook-into text-mode))
1054 756
757(setup frames
758 (:option frame-title-format '("%b@"
759 (:eval
760 (or (file-remote-p default-directory 'host)
761 system-name))
762 " %+%* GNU Emacs"
763 (:eval (when (frame-parameter nil 'client)
764 " Client")))
765 window-resize-pixelwise t))
766
767(setup ibuffer
768 (:also-load ibuf-ext)
769 (:option ibuffer-expert t
770 ibuffer-show-empty-filter-groups nil
771 ibuffer-saved-filter-groups
772 '(("default"
773 ("dired" (mode . dired-mode))
774 ("customize" (mode . Custom-mode))
775 ("emacs" (or (name . "^\\*scratch\\*$")
776 (name . "^\\*Messages\\*$")
777 (name . "^\\*Warnings\\*$")
778 (name . "^\\*straight-process\\*$")
779 (name . "^\\*Calendar\\*$")))
780 ("git" (or (name . "^\*magit")
781 (name . "^\magit")))
782 ("help" (or (mode . help-mode)
783 (mode . Info-mode)
784 (mode . helpful-mode)))
785 ("messaging" (or (mode . message-mode)
786 (mode . bbdb-mode)
787 (mode . mail-mode)
788 (mode . gnus-group-mode)
789 (mode . gnus-summary-mode)
790 (mode . gnus-article-mode)
791 (name . "^\\.bbdb$")
792 (name . "^\\.newsrc-dribble")
793 (mode . erc-mode)
794 (mode . circe-server-mode)
795 (mode . circe-channel-mode)))
796 ("shell" (or (mode . eshell-mode)
797 (mode . shell-mode)
798 (mode . vterm-mode)))
799 ("web" (or (mode . elpher-mode)
800 (mode . gemini-mode)
801 (mode . eww-mode))))))
802
803 (:global "C-x C-b" #'ibuffer)
804
805 (:hook (defun ibuffer@filter-to-default ()
806 (ibuffer-switch-to-saved-filter-groups "default"))))
807
808(setup ielm
809 (:hook #'turn-on-eldoc-mode))
810
811(setup imenu
812 (:option imenu-auto-rescan t))
813
814(setup isearch
815 (:option search-default-mode t))
816
817(setup lines
818 (:option fill-column 79
819 word-wrap t
820 truncate-lines nil)
821
822 (global-display-fill-column-indicator-mode +1)
823 (global-so-long-mode +1)
824
825 (add-hook 'visual-line-mode-hook
826 (defun acdw/disable-fill-column-indicator ()
827 (display-fill-column-indicator-mode
828 (if visual-line-mode -1 +1))))
829
830 ;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'.
831 ;; I can't simply advise `kill-line' with an override from crux because crux
832 ;; itself calls `kill-line', leading to a infinite nesting situation.
833 (advice-add 'kill-line :around
834 (defun kill-line@join (fn &rest args)
835 (if (and (eolp)
836 (not (bolp)))
837 (delete-indentation 1)
838 (apply fn args)))))
839
840(setup minibuffer
841 (:option enable-recursive-minibuffers t
842 file-name-shadow-properties '(invisible t intangible t)
843 minibuffer-eldef-shorten-default t
844 minibuffer-prompt-properties
845 '(read-only t cursor-intangible t face minibuffer-prompt)
846 read-answer-short t
847 read-extended-command-predicate ; used on >28
848 #'command-completion-default-include-p)
849
850 (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
851
852 (add-hook 'minibuffer-setup-hook #'acdw/gc-disable)
853 (add-hook 'minibuffer-exit-hook #'acdw/gc-enable)
854
855 (minibuffer-depth-indicate-mode +1)
856 (file-name-shadow-mode +1)
857 (minibuffer-electric-default-mode +1)
858
859 (if (version< emacs-version "28")
860 (fset 'yes-or-no-p #'y-or-n-p)
861 (setq use-short-answers t)))
862
863(setup mouse-avoidance
864 (mouse-avoidance-mode 'exile))
865
866(setup page
867 (:option page-delimiter
868 (rx bol (or "\f" ";;;")
869 (not (any "#")) (* not-newline) "\n"
870 (* (* blank) (opt ";" (* not-newline)) "\n")))
871
872 (defun recenter-to-top (&rest _)
873 "Recenter the cursor to the top of the window."
874 (when (called-interactively-p 'any)
875 (recenter (if (or (null scroll-margin)
876 (zerop scroll-margin))
877 3
878 scroll-margin))))
879
880 (:advise forward-page :after #'recenter-to-top
881 backward-page :after #'recenter-to-top)
882
883 ;; I'm not sure where this is in /my/ version of Emacs
884 ;; (defvar page-navigation-repeat-map
885 ;; (let ((map (make-sparse-keymap)))
886 ;; (define-key map "]" #'forward-page)
887 ;; (define-key map "[" #'backward-page)
888 ;; map)
889 ;; "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.")
890
891 ;; (put 'forward-page 'repeat-map 'page-navigation-repeat-map)
892 ;; (put 'backward-page 'repeat-map 'page-navigation-repeat-map)
893 )
894
895(setup prog
896 (:option show-paren-delay 0
897 show-paren-style 'mixed
898 show-paren-when-point-inside-paren t
899 show-paren-when-point-in-periphery t
900 smie-indent-basic tab-width)
901
902 (:hook show-paren-mode
903 electric-pair-local-mode
904 acdw/setup-fringes
905
906 (defun prog-mode@auto-fill ()
907 (setq-local comment-auto-fill-only-comments t)
908 (turn-on-auto-fill)))
909
910 (add-hook 'after-save-hook
911 #'executable-make-buffer-file-executable-if-script-p))
912
913(setup repeat
914 ;; new for Emacs 28!
915 (:only-if (fboundp #'repeat-mode))
916
917 (:option repeat-exit-key "g"
918 repeat-exit-timeout 5)
919
920 (repeat-mode +1))
921
922(setup saveplace
923 (:option save-place-file (acdw/dir "places.el")
924 save-place-forget-unreadable-files (acdw/system :home))
925
926 (save-place-mode +1))
927
928(setup scratch
929 (:option inhibit-startup-screen t
930 initial-buffer-choice t
931 initial-scratch-message ""
932 ;; (concat ";; Howdy, "
933 ;; (nth 0 (split-string
934 ;; user-full-name))
935 ;; "! "
936 ;; "Welcome to GNU Emacs.\n\n")
937 )
938
939 (add-hook 'kill-buffer-query-functions
940 (defun kill-buffer-query@immortal-scratch ()
941 (if (eq (current-buffer) (get-buffer "*scratch*"))
942 (progn (bury-buffer)
943 nil)
944 t))))
945
946(setup scrolling
947 (:option auto-window-vscroll nil
948 fast-but-imprecise-scrolling t
949 scroll-margin 3
950 scroll-conservatively 101
951 scroll-preserve-screen-position 1))
952
953(setup selection
954 (:option save-interprogram-paste-before-kill t
955 yank-pop-change-selection t
956 x-select-enable-clipboard t
957 x-select-enable-primary t
958 mouse-drag-copy-region t
959 kill-do-not-save-duplicates t)
960
961 (delete-selection-mode +1))
962
963(setup sh-mode
964 (:option sh-basic-offset tab-width
965 sh-indent-after-case 0
966 sh-indent-for-case-alt '+
967 sh-indent-for-case-label 0)
968
969 (:local-set indent-tabs-mode t)
970
971 (when (executable-find "shfmt")
972 (with-eval-after-load 'apheleia
973 (:option (append apheleia-formatters) '(shfmt . ("shfmt"))
974 (append apheleia-mode-alist) '(sh-mode . shfmt))))
975
976 (when (executable-find "shellcheck")
977 (:straight flymake-shellcheck)
978 (:hook flymake-mode
979 flymake-shellcheck-load)))
980
981(setup shell-command
982 (:option shell-command-switch (acdw/system
983 ;; I should be testing on some variable
984 (:home "-csi")
985 (:work "-c"))
986 shell-command-prompt-show-cwd t
987 shell-command-default-error-buffer "*shell-command-errors*"))
988
989(setup shr
990 (:option shr-width fill-column
991 shr-max-width fill-column
992 shr-max-image-proportion 0.6
993 shr-image-animate t
994 shr-discard-aria-hidden t
995 shr-folding-mode t))
996
997(setup text
998 (:hook turn-on-auto-fill
999 tildify-mode
1000 acdw/setup-fringes))
1001
1002(setup uniquify
1003 (:option uniquify-buffer-name-style 'forward
1004 uniquify-separator path-separator
1005 uniquify-after-kill-buffer-p t
1006 uniquify-ignore-buffers-re "^\\*"))
1007
1008(setup variable-pitch-mode
1009 ;; I might want to change this to `buffer-face-mode-hook'...
1010 (:advise variable-pitch-mode :after
1011 (defun variable-pitch-mode@setup (&rest _)
1012 "Set up `variable-pitch-mode' with my customizations."
1013 (display-fill-column-indicator-mode
1014 (if buffer-face-mode -1 +1)))))
1015
1016(setup view
1017 (:option view-read-only t)
1018
1019 (:hook (defun acdw/read-view-mode ()
1020 (reading-mode (if view-mode +1 -1)))))
1021
1022(setup w32
1023 (:option w32-allow-system-shell t
1024 w32-pass-lwindow-to-system nil
1025 w32-lwindow-modifier 'super
1026 w32-pass-rwindow-to-system nil
1027 w32-rwindow-modifier 'super
1028 w32-pass-apps-to-system nil
1029 w32-apps-modifier 'hyper))
1030
1031(setup whitespace
1032 (:option whitespace-style '(empty
1033 indentation
1034 space-before-tab
1035 space-after-tab)
1036 indent-tabs-mode nil
1037 tab-width 4
1038 backward-delete-char-untabify-method 'hungry)
1039
1040 (:global "M-SPC" #'cycle-spacing))
1041
1042(setup windmove
1043 (:option windmove-wrap-around t)
1044 (:global
1045 ;; moving
1046 "C-x 4 <left>" #'windmove-left
1047 "C-x 4 <right>" #'windmove-right
1048 "C-x 4 <up>" #'windmove-up
1049 "C-x 4 <down>" #'windmove-down
1050 ;; swapping
1051 "C-x 4 S-<left>" #'windmove-swap-states-left
1052 "C-x 4 S-<right>" #'windmove-swap-states-right
1053 "C-x 4 S-<up>" #'windmove-swap-states-up
1054 "C-x 4 S-<down>" #'windmove-swap-states-down)
1055
1056 ;; (when (fboundp 'repeat-mode)
1057 ;; (defvar windmove-repeat-map
1058 ;; (let ((map (make-sparse-keymap)))
1059 ;; ;; moving
1060 ;; (define-key map [left] #'windmove-left)
1061 ;; (define-key map [right] #'windmove-right)
1062 ;; (define-key map [up] #'windmove-up)
1063 ;; (define-key map [down] #'windmove-down)
1064 ;; ;; swapping
1065 ;; (define-key map [S-left] #'windmove-swap-states-left)
1066 ;; (define-key map [S-right] #'windmove-swap-states-right)
1067 ;; (define-key map [S-up] #'windmove-swap-states-up)
1068 ;; (define-key map [S-down] #'windmove-swap-states-down)
1069 ;; map)
1070 ;; "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.")
1071
1072 ;; (dolist (sym '(windmove-left
1073 ;; windmove-right
1074 ;; windmove-up
1075 ;; windmove-down
1076 ;; windmove-swap-states-left
1077 ;; windmove-swap-states-right
1078 ;; windmove-swap-states-up
1079 ;; windmove-swap-states-down))
1080 ;; (put sym 'repeat-map 'windmove-repeat-map)))
1081 )
1082
1083(setup window
1084 (require 'acdw-bell)
1085 (:option
1086 ;; Man-notify-method 'pushy
1087 ;; display-buffer-alist ; from FrostyX
1088 ;; '(("shell.*" (display-buffer-same-window) ())
1089 ;; (".*" (display-buffer-reuse-window
1090 ;; display-buffer-same-window)
1091 ;; (reusable-frames . t)))
1092 recenter-positions '(top middle bottom)
1093 ring-bell-function (lambda ()
1094 (acdw-bell/flash-mode-line
1095 (acdw/system :home)))
1096 use-dialog-box nil
1097 use-file-dialog nil
1098 visible-bell nil)
1099
1100 (tooltip-mode -1))
1101
1102(setup winner
1103 ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html
1104 (:global "C-x 4 C-/" #'winner-undo
1105 "C-x 4 /" #'winner-undo
1106 "C-x 4 C-?" #'winner-redo
1107 "C-x 4 ?" #'winner-redo)
1108
1109 ;; add `winner-undo' and `winner-redo' to `repeat-mode'
1110 ;; (when (fboundp 'repeat-mode)
1111 ;; (defvar winner-mode-repeat-map
1112 ;; (let ((map (make-sparse-keymap)))
1113 ;; (define-key map "/" #'winner-undo)
1114 ;; (define-key map "?" #'winner-redo)
1115 ;; map)
1116 ;; "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.")
1117
1118 ;; (put 'winner-undo 'repeat-map 'winner-mode-repeat-map)
1119 ;; (put 'winner-redo 'repeat-map 'winner-mode-repeat-map))
1120
1121 (winner-mode +1))
1122
1123(setup (:straight (0x0
1124 :host gitlab
1125 :repo "willvaughn/emacs-0x0"))
1126 (:option 0x0-default-server 'ttm))
1127
1128(setup (:straight-if affe
1129 (and (or (executable-find "fd")
1130 (executable-find "find"))
1131 (executable-find "rg")))
1132 ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find'
1133 (:option affe-regexp-compiler
1134 (defun affe-orderless-regexp-compiler (input _type)
1135 (setq input (orderless-pattern-compiler input))
1136 (cons input (lambda (str) (orderless--highlight input str))))))
1137
1138(setup (:straight-if ahk-mode
1139 (acdw/system :work)))
1140
1141(setup (:straight alert)
1142 (:option alert-default-style (acdw/system
1143 (:home 'libnotify)
1144 (_ 'message))))
1145
1146(setup (:straight (apheleia
1147 :host github
1148 :repo "raxod502/apheleia"))
1149
1150 (apheleia-global-mode +1)
1151
1152 ;; Use a dumb formatter on modes that `apheleia' doesn't work for.
1153 (add-hook 'before-save-hook
1154 (defun before-save@dumb-auto-format ()
1155 (setq stupid-modes '(makefile-mode
1156 org-mode))
1157 ;; If there's no apheleia formatter for the mode, just indent the
1158 ;; buffer.
1159 (unless (or (apply #'derived-mode-p stupid-modes)
1160 (and (fboundp 'apheleia--get-formatter-command)
1161 (apheleia--get-formatter-command)))
1162 (indent-region (point-min) (point-max))))))
1163
1164(setup (:straight async)
1165 (dired-async-mode +1)
1166
1167 (:with-feature dired
1168 (:hook (defun dired@disable-dired-async-mode-line ()
1169 (autoload 'dired-async--modeline-mode "dired-async" nil t)
1170 (dired-async--modeline-mode -1)))))
1171
1172(setup (:straight avy)
1173 (:global "C-'" #'avy-goto-char-timer
1174 "C-c C-j" #'avy-resume)
1175
1176 (:with-feature isearch
1177 (:bind "C-'" #'avy-isearch)))
1178
1179(setup (:straight circe)
1180 (require 'circe)
1181 (require 'acdw-irc)
1182
1183 (:option acdw-irc/left-margin 12
1184 acdw-irc/post-my-nick "-> "
1185 circe-channel-killed-confirmation nil
1186 circe-color-nicks-everywhere t
1187 circe-default-nick "acdw"
1188 circe-default-part-message "See You, Space Cowpokes . . ."
1189 circe-default-user "acdw"
1190 circe-format-action
1191 (lambda (&rest plist)
1192 (concat
1193 (acdw-irc/margin-format "" "*" "*" t)
1194 " " (plist-get plist :nick) " " (plist-get plist :body)))
1195 circe-format-say
1196 (lambda (&rest plist)
1197 (concat
1198 (acdw-irc/margin-format (plist-get plist :nick) "" " |" t)
1199 " " (plist-get plist :body)))
1200 circe-format-self-action
1201 (lambda (&rest plist)
1202 (concat
1203 (acdw-irc/margin-format "" "-*" " *" t)
1204 " " (plist-get plist :nick) " " (plist-get plist :body)))
1205 circe-format-self-say
1206 (lambda (&rest plist)
1207 (concat
1208 (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t)
1209 " " (plist-get plist :body)))
1210 ;; circe-highlight-nick-type 'message
1211 circe-network-options
1212 `(("Libera Chat"
1213 :channels ("#emacs" "#systemcrafters" "##webpals")
1214 :sasl-username ,circe-default-nick
1215 :sasl-password ,(acdw/make-password-fetcher
1216 :host "libera.chat"))
1217 ("Tilde Chat" :host "irc.tilde.chat" :port 6697 :use-tls t
1218 :channels ("#meta" "#bread" "#dadjokes" "#team"
1219 "#emacs")
1220 :sasl-username ,circe-default-nick
1221 :sasl-password ,(acdw/make-password-fetcher
1222 :host "tilde.chat"))
1223 ("Casa" :host "m455.casa" :port 6697 :use-tls t
1224 :channels ("#basement")
1225 :sasl-username ,circe-default-nick
1226 :sasl-password ,(acdw/make-password-fetcher
1227 :host "m455.casa"))
1228 ("Pissnet" :host "piss.hmm.st" :port 6697 :use-tls t
1229 :channels ("#i-just-peed")
1230 :sasl-username ,circe-default-nick
1231 :sasl-password ,(acdw/make-password-fetcher
1232 :host "piss.hmm.st"))
1233 ;; TODO: irc.chat.twitch.tv
1234 )
1235 circe-reduce-lurker-spam t
1236 circe-server-auto-join-default-type :after-auth)
1237
1238 ;; (:face circe-nick-highlight-face
1239 ;; ((t (:inherit (modus-themes-hl-line)))))
1240
1241 (:bind "C-c C-p" #'circe-command-PART
1242 "C-l" #'lui-track-jump-to-indicator)
1243
1244 (:advise circe-command-PART :after
1245 (defun circe-part@kill-buffer (&rest _)
1246 (let ((circe-channel-killed-confirmation nil))
1247 (kill-buffer)))
1248
1249 circe-command-QUIT :after
1250 (defun circe-quit@kill-buffer (&rest _)
1251 ;; `circe-server-killed-confirmation' set to nil, and manually
1252 ;; deleting all chat buffers, pending Github issue #402
1253 ;; (https://github.com/emacs-circe/circe/issues/402)
1254 (let ((circe-server-killed-confirmation nil))
1255 (with-circe-server-buffer
1256 (dolist (buf (circe-server-chat-buffers))
1257 (let ((circe-channel-killed-confirmation nil))
1258 (kill-buffer buf)))
1259 (kill-buffer))))
1260
1261 circe-command-GQUIT :after
1262 (defun circe-gquit@kill-buffer (&rest _)
1263 ;; `circe-server-killed-confirmation' set to nil, and manually
1264 ;; deleting all chat buffers, pending Github issue #402
1265 ;; (https://github.com/emacs-circe/circe/issues/402)
1266 (let ((circe-server-killed-confirmation nil))
1267 (dolist (buf (circe-server-buffers))
1268 (with-current-buffer buf
1269 (dolist (buf (circe-server-chat-buffers))
1270 (let ((circe-channel-killed-confirmation nil))
1271 (kill-buffer buf)))
1272 (message "%s: %s" buf circe-server-killed-confirmation)
1273 (kill-buffer))))))
1274
1275 (defun circe-command-SHORTEN (url)
1276 "Shorten URL using `0x0-shorten-uri'."
1277 (interactive "sURL to shorten: ")
1278 ;; TODO: enable /shorten URL comment syntax
1279 (let ((short-url (0x0-shorten-uri (0x0--choose-server) url)))
1280 (circe-command-SAY short-url)))
1281
1282 (:with-mode circe-chat-mode
1283 (:hook #'acdw/stop-paren-annoyances
1284 #'enable-circe-color-nicks
1285 #'enable-circe-display-images
1286 #'enable-circe-new-day-notifier
1287 (defun circe-chat@set-prompt ()
1288 (lui-set-prompt
1289 (concat
1290 (propertize
1291 (acdw-irc/margin-format (buffer-name) "" ">")
1292 'face 'circe-prompt-face
1293 'read-only t
1294 'intangible t
1295 'cursor-intangible t)
1296 " ")))))
1297
1298 (autoload 'circe-nick-color-reset "circe-color-nicks")
1299 (add-hook 'modus-themes-after-load-theme-hook
1300 #'circe-nick-color-reset)
1301
1302 (:with-mode lui-mode
1303 (:option lui-fill-column fill-column
1304 lui-fill-type (repeat-string acdw-irc/left-margin " ")
1305 lui-time-stamp-position 'right-margin
1306 lui-time-stamp-format "%H:%M"
1307 lui-track-behavior 'before-switch-to-buffer
1308 lui-track-indicator 'fringe)
1309
1310 (:local-set fringes-outside-margins t
1311 right-margin-width 5
1312 scroll-margin 0
1313 word-wrap t
1314 wrap-prefix (repeat-string acdw-irc/left-margin " ")
1315 line-number-mode nil)
1316
1317 (:hook #'enable-lui-track)))
1318
1319(setup (:straight (consult
1320 :host github
1321 :repo "minad/consult"))
1322
1323 (:require acdw-consult)
1324 (:autoload consult-register-preview)
1325
1326 ;; Bindings
1327 (:global
1328 ;; C-c bindings (`mode-specific-map')
1329 ;; I don't use any of these right now.
1330 ;; "C-c h" #'consult-history
1331 ;; "C-c m" #'consult-mode-command
1332 ;; "C-c b" #'consult-bookmark
1333 ;; "C-c k" #'consult-kmacro
1334 ;; C-x bindings (`ctl-x-map')
1335 "C-x M-:" #'consult-complex-command
1336 "C-x b" #'consult-buffer
1337 "C-x 4 b" #'consult-buffer-other-window
1338 "C-x 5 b" #'consult-buffer-other-frame
1339 ;; Custom M-# bindings for fast register access
1340 "M-#" #'consult-register-load
1341 "M-'" #'consult-register-store
1342 "C-M-#" #'consult-register
1343 ;; M-g bindings (`goto-map')
1344 "M-g e" #'consult-compile-error
1345 "M-g g" #'consult-goto-line
1346 "M-g M-g" #'consult-goto-line
1347 "M-g o" #'consult-outline
1348 "M-g m" #'consult-mark
1349 "M-g k" #'consult-global-mark
1350 "M-g i" #'consult-imenu
1351 "M-g I" #'consult-project-imenu
1352 ;; M-s bindings (`search-map')
1353 "M-s g" #'acdw-consult/sensible-grep
1354 "M-s f" #'acdw-consult/sensible-find
1355 "M-s l" #'consult-line
1356 "M-s m" #'consult-multi-occur
1357 "M-s k" #'consult-keep-lines
1358 "M-s u" #'consult-focus-lines
1359 ;; Other bindings
1360 "M-y" #'consult-yank-pop
1361 "<help> a" #'consult-apropos
1362 ;; Isearch integration
1363 "M-s e" #'consult-isearch)
1364
1365 (:with-map isearch-mode-map
1366 (:bind "M-e" #'consult-isearch
1367 "M-s e" #'consult-isearch
1368 "M-s l" #'consult-line))
1369
1370 (consult-history-to-modes ((minibuffer-local-map . nil)
1371 (shell-mode-map . shell-mode-hook)
1372 (term-mode-map . term-mode-hook)
1373 (term-raw-map . term-mode-hook)
1374 (comint-mode-map . comint-mode-hook)
1375 (sly-mrepl-mode-map . sly-mrepl-hook)))
1376
1377 (:option register-preview-delay 0
1378 register-preview-function #'consult-register-format
1379 xref-show-xrefs-function #'consult-xref
1380 xref-show-definitions-function #'consult-xref
1381 consult-project-root-function #'vc-root-dir
1382 completion-in-region-function #'acdw-consult/complete-in-region
1383 completion-cycle-threshold 3
1384 consult-preview-key (kbd "M-.")
1385 tab-always-indent 'complete)
1386
1387 (:advise register-preview :override #'consult-register-window)
1388
1389 ;; Completing-read-multple
1390 (if (fboundp #'consult-completing-read-multiple)
1391 (:advise completing-read-multple :override
1392 #'consult-completing-read-multiple)
1393 (:advise completing-read-multiple :filter-args
1394 (defun crm-indicator (args)
1395 (cons (concat "[CRM] " (car args)) (cdr args)))))
1396
1397 (with-eval-after-load 'orderless
1398 (:option consult--regexp-compiler
1399 #'consult--orderless-regexp-compiler))
1400
1401 (with-eval-after-loads (vertico consult)
1402 (:with-map consult-crm-map
1403 (:bind "RET" (defun +vertico-crm-exit ()
1404 (interactive)
1405 (run-at-time 0 nil #'vertico-exit)
1406 (funcall #'vertico-exit))
1407 "TAB" #'vertico-exit))))
1408
1409(setup (:straight crux)
1410 (:global "C-o" #'crux-smart-open-line
1411 "M-o" #'crux-smart-open-line-above
1412 "C-M-\\" #'crux-cleanup-buffer-or-region
1413 "C-x 4 t" #'crux-transpose-windows)
1414
1415 (crux-reopen-as-root-mode +1))
1416
1417(setup (:straight-if (define-repeat-map
1418 :host nil
1419 :repo "https://tildegit.org/acdw/define-repeat-map.el")
1420 (acdw/system :home))
1421
1422 (defun acdw/other-window-or-switch-buffer-backward ()
1423 (interactive)
1424 (setq repeat-map 'other-window-repeat-map)
1425 (acdw/other-window-or-switch-buffer -1))
1426
1427 (define-repeat-map other-window
1428 ("o" acdw/other-window-or-switch-buffer
1429 "O" acdw/other-window-or-switch-buffer-backward))
1430
1431 (define-repeat-map case
1432 ("c" capitalize-word
1433 "u" upcase-dwim
1434 "l" downcase-dwim)
1435 (:continue "f" forward-word
1436 "b" backward-word)
1437 (:enter capitalize-dwim
1438 upcase-dwim
1439 downcase-dwim))
1440
1441 (define-repeat-map page-navigation
1442 ("]" forward-page
1443 "[" backward-page))
1444
1445 (define-repeat-map windmove
1446 (;; moving
1447 "<left>" windmove-left
1448 "<right>" windmove-right
1449 "<up>" windmove-up
1450 "<down>" windmove-down
1451 ;; swapping
1452 "<S-left>" windmove-swap-states-left
1453 "<S-right>" windmove-swap-states-right
1454 "<S-up>" windmove-swap-states-up
1455 "<S-down>" windmove-swap-states-down))
1456
1457 (define-repeat-map winner-mode
1458 ("/" winner-undo
1459 "?" winner-redo)))
1460
1461(setup (:straight edit-indirect))
1462
1463;; requires extension:
1464;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/
1465(setup (:straight edit-server)
1466 (:require edit-server)
1467 (edit-server-start)
1468
1469 (:option edit-server-default-major-mode 'text-mode
1470 edit-server-url-major-mode-alist
1471 (list (cons (rx (| "reddit.com"
1472 "tildes.net"))
1473 'markdown-mode)
1474 (cons (rx "github.com")
1475 'gfm-mode)))
1476
1477 (:advise edit-server-make-frame :before
1478 (defun edit-server@set-a-variable (&rest _)
1479 (setq-local edit-server-frame-p t))))
1480
1481(setup (:straight (electric-cursor
1482 :host github
1483 :repo "duckwork/electric-cursor"))
1484 (electric-cursor-mode +1))
1485
1486(setup (:straight elfeed
1487 elfeed-protocol)
1488 (:option elfeed-use-curl t
1489 elfeed-feeds `(("fever+https://acdw@mf.acdw.net"
1490 :api-url "https://mf.acdw.net/fever/"
1491 :password ,(acdw/make-password-fetcher
1492 :host "mf.acdw.net"))))
1493
1494 (elfeed-protocol-enable)
1495 (:advise elfeed :after
1496 (defun elfeed@protocol-update (&rest _)
1497 (elfeed-search-fetch nil)))
1498
1499 (:face message-header-subject
1500 ((t (:height 1.5))))
1501
1502 (:with-mode elfeed-show-mode
1503 (:hook #'reading-mode)
1504
1505 ;; see https://irreal.org/blog/?p=8885
1506 (:bind "SPC" (defun elfeed-scroll-up-command (&optional arg)
1507 "Scroll up or go to next feed item in Elfeed"
1508 (interactive "^P")
1509 (let ((scroll-error-top-bottom nil))
1510 (condition-case-unless-debug nil
1511 (scroll-up-command arg)
1512 (error (elfeed-show-next)))))
1513 "S-SPC" (defun elfeed-scroll-down-command (&optional arg)
1514 "Scroll up or go to next feed item in Elfeed"
1515 (interactive "^P")
1516 (let ((scroll-error-top-bottom nil))
1517 (condition-case-unless-debug nil
1518 (scroll-down-command arg)
1519 (error (elfeed-show-prev))))))))
1520
1521(setup (:straight elisp-slime-nav)
1522 (:hook-into emacs-lisp-mode
1523 ielm-mode))
1524
1525(setup (:straight (elpher
1526 :host nil
1527 :repo "git://thelambdalab.xyz/elpher.git"))
1528 (:option elpher-ipv4-always t
1529 elpher-certificate-directory (acdw/dir "elpher/")
1530 elpher-gemini-max-fill-width fill-column)
1531
1532 (:bind "n" #'elpher-next-link
1533 "p" #'elpher-prev-link
1534 "o" #'elpher-follow-current-link
1535 "G" #'elpher-go-current)
1536
1537 (:hook #'reading-mode)
1538
1539 (:autoload (elpher-bookmarks :interactive t)
1540 (elpher-go :interactive t))
1541
1542 ;; Make `eww' gemini/gopher aware. From Emacswiki.
1543 ;; (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher)
1544 ;; (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
1545 ;; (require 'elpher)
1546 ;; (elpher-go url))
1547 ;; (t (apply fn url args))))
1548 )
1549
1550(setup (:straight embark)
1551 (:global "C-." #'embark-act)
1552 (:option prefix-help-command #'embark-prefix-help-command
1553 (append display-buffer-alist)
1554 `(,(rx (seq bos "*Embark Collect "
1555 (group (| "Live" "Completions"))
1556 "*"))
1557 nil
1558 (window-parameters (mode-line-format . none)))
1559 embark-prompter #'embark-keymap-prompter
1560 embark-verbose-indicator-display-action
1561 '(display-buffer-at-bottom (window-height . fit-window-to-buffer))
1562 embark-action-indicator
1563 (lambda (map _target)
1564 (which-key--show-keymap "Embark" map nil nil 'no-paging)
1565 #'which-key--hide--ignore-command)
1566 embark-become-indicator embark-action-indicator)
1567
1568 (with-eval-after-loads (embark consult)
1569 (:straight embark-consult)
1570 (add-hook 'embark-collect-mode-hook
1571 #'consult-preview-at-point-mode)))
1572
1573(setup (:straight epithet)
1574 (dolist (hook '(Info-selection-hook
1575 eww-after-render-hook
1576 help-mode-hook
1577 occur-mode-hook))
1578 (add-hook hook #'epithet-rename-buffer)))
1579
1580;; TODO: look into emms or something related for this
1581(setup (:straight-if eradio
1582 (executable-find "mpv"))
1583 (:option
1584 eradio-player '("mpv" "--no-video" "--no-terminal")
1585 eradio-channels `(("KLSU" .
1586 "http://130.39.238.143:8010/stream.mp3")
1587 ("Soma FM Synphaera" .
1588 "https://somafm.com/synphaera256.pls")
1589 ("SomaFM BAGel Radio" .
1590 "https://somafm.com/bagel.pls")
1591 ("SomaFM Boot Liquor" .
1592 "https://somafm.com/bootliquor320.pls")
1593 ("SomaFM Deep Space One" .
1594 "https://somafm.com/deepspaceone.pls")
1595 ("SomaFM Fluid" .
1596 "https://somafm.com/fluid.pls")
1597 ("SomaFM Underground 80s" .
1598 "https://somafm.com/u80s256.pls")
1599 ("WBRH: Jazz & More" .
1600 "http://wbrh.streamguys1.com/wbrh-mp3")
1601 ("KBRH Blues & Rhythm Hits" .
1602 "http://wbrh.streamguys1.com/kbrh-mp3")
1603 ("WRKF HD-2" .
1604 ,(concat "https://playerservices.streamtheworld.com/"
1605 "api/livestream-redirect/WRKFHD2.mp3"))
1606 ("WRKF: NPR for the Capital Region" .
1607 ,(concat "https://playerservices.streamtheworld.com/"
1608 "api/livestream-redirect/WRKFFM.mp3"))
1609 ("BadRadio: 24/7 PHONK" .
1610 "https://s2.radio.co/s2b2b68744/listen")
1611 ("tilderadio" .
1612 "https://azuracast.tilderadio.org/radio/8000/radio.ogg")
1613 ("vantaradio" .
1614 "https://vantaa.black/radio")))
1615 (:global "C-c r r" #'eradio-play ; mnemonic: radio
1616 "C-c r s" #'eradio-stop ; mnemonic: stop
1617 "C-c r p" #'eradio-toggle ; mnemonic: play/pause
1618 ))
1619
1620(setup (:straight eros)
1621 (:hook-into emacs-lisp-mode
1622 lisp-interaction-mode))
1623
1624(setup (:straight-if exec-path-from-shell
1625 (acdw/system :home))
1626 (when (daemonp)
1627 (exec-path-from-shell-initialize)))
1628
1629(setup (:straight expand-region)
1630 (:global "C-=" #'er/expand-region))
1631
1632(setup (:straight-if fennel-mode
1633 (executable-find "fennel"))
1634 (:autoload (fennel-repl :interactive t))
1635 (:file-match (rx ".fnl" eos)))
1636
1055(setup (:straight flyspell-correct) 1637(setup (:straight flyspell-correct)
1056 (:option flyspell-correct-interface #'flyspell-correct-completing-read 1638 (:option flyspell-correct-interface #'flyspell-correct-completing-read
1057 flyspell-correct--cr-key ";") 1639 flyspell-correct--cr-key ";")
@@ -1077,16 +1659,6 @@ specific to most general, they are these:
1077 '("tildegit.org" "tildegit.org/api/v1" "tildegit.org" 1659 '("tildegit.org" "tildegit.org/api/v1" "tildegit.org"
1078 forge-gitea-repository)))) 1660 forge-gitea-repository))))
1079 1661
1080(setup frames
1081 (:option frame-title-format '("%b@"
1082 (:eval
1083 (or (file-remote-p default-directory 'host)
1084 system-name))
1085 " %+%* GNU Emacs"
1086 (:eval (when (frame-parameter nil 'client)
1087 " Client")))
1088 window-resize-pixelwise t))
1089
1090(setup (:straight gcmh) 1662(setup (:straight gcmh)
1091 (:option gcmh-idle-delay 'auto) 1663 (:option gcmh-idle-delay 'auto)
1092 (gcmh-mode +1)) 1664 (gcmh-mode +1))
@@ -1127,23 +1699,12 @@ specific to most general, they are these:
1127 (with-eval-after-load 'elpher 1699 (with-eval-after-load 'elpher
1128 (require 'gemini-write))) 1700 (require 'gemini-write)))
1129 1701
1130(setup (:require gforth)
1131 (:autoload forth-mode
1132 forth-block-mode)
1133 (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode))
1134 (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode)))
1135
1136(setup (:straight gitattributes-mode)) 1702(setup (:straight gitattributes-mode))
1137 1703
1138(setup (:straight gitconfig-mode)) 1704(setup (:straight gitconfig-mode))
1139 1705
1140(setup (:straight gitignore-mode)) 1706(setup (:straight gitignore-mode))
1141 1707
1142(setup (:require goto-addr)
1143 (if (fboundp #'global-goto-address-mode)
1144 (global-goto-address-mode)
1145 (add-hook 'after-change-major-mode-hook #'goto-address-mode)))
1146
1147(setup (:straight helpful) 1708(setup (:straight helpful)
1148 (:require-after 3) 1709 (:require-after 3)
1149 1710
@@ -1194,72 +1755,22 @@ specific to most general, they are these:
1194 (hungry-delete-forward (or arg 1)) 1755 (hungry-delete-forward (or arg 1))
1195 (paredit-forward-delete arg)))))) 1756 (paredit-forward-delete arg))))))
1196 1757
1197(setup ibuffer
1198 (:also-load ibuf-ext)
1199 (:option ibuffer-expert t
1200 ibuffer-show-empty-filter-groups nil
1201 ibuffer-saved-filter-groups
1202 '(("default"
1203 ("dired" (mode . dired-mode))
1204 ("customize" (mode . Custom-mode))
1205 ("emacs" (or (name . "^\\*scratch\\*$")
1206 (name . "^\\*Messages\\*$")
1207 (name . "^\\*Warnings\\*$")
1208 (name . "^\\*straight-process\\*$")
1209 (name . "^\\*Calendar\\*$")))
1210 ("git" (or (name . "^\*magit")
1211 (name . "^\magit")))
1212 ("help" (or (mode . help-mode)
1213 (mode . Info-mode)
1214 (mode . helpful-mode)))
1215 ("messaging" (or (mode . message-mode)
1216 (mode . bbdb-mode)
1217 (mode . mail-mode)
1218 (mode . gnus-group-mode)
1219 (mode . gnus-summary-mode)
1220 (mode . gnus-article-mode)
1221 (name . "^\\.bbdb$")
1222 (name . "^\\.newsrc-dribble")
1223 (mode . erc-mode)
1224 (mode . circe-server-mode)
1225 (mode . circe-channel-mode)))
1226 ("shell" (or (mode . eshell-mode)
1227 (mode . shell-mode)
1228 (mode . vterm-mode)))
1229 ("web" (or (mode . elpher-mode)
1230 (mode . gemini-mode)
1231 (mode . eww-mode))))))
1232
1233 (:global "C-x C-b" #'ibuffer)
1234
1235 (:hook (defun ibuffer@filter-to-default ()
1236 (ibuffer-switch-to-saved-filter-groups "default"))))
1237
1238(setup ielm
1239 (:hook #'turn-on-eldoc-mode))
1240
1241(setup imenu
1242 (:option imenu-auto-rescan t))
1243
1244(setup (:straight iscroll) 1758(setup (:straight iscroll)
1245 (define-globalized-minor-mode global-iscroll-mode iscroll-mode 1759 (define-globalized-minor-mode global-iscroll-mode iscroll-mode
1246 (lambda () (iscroll-mode +1))) 1760 (lambda () (iscroll-mode +1)))
1247 1761
1248 (global-iscroll-mode +1)) 1762 (global-iscroll-mode +1))
1249 1763
1250(setup isearch
1251 (:option search-default-mode t))
1252
1253(setup (:straight (kaomoji-insert 1764(setup (:straight (kaomoji-insert
1254 :host nil 1765 :host nil
1255 :repo "https://tildegit.org/acdw/kaomoji-insert")) 1766 :repo "https://tildegit.org/acdw/kaomoji-insert"))
1256 (require 'kaomoji-insert) 1767 (require 'kaomoji-insert)
1257 (dolist (km '(("(Ծ‸ Ծ)" "suspicious") 1768 (dolist (km '(("(Ծ‸ Ծ)" "suspicious")
1258 ("(¬‿¬)═ɜ ɛ═(⌐‿⌐ )" "pound it" "fist bump") 1769 ("(¬‿¬)═ɜ ɛ═(⌐‿⌐ )" "pound it" "fist bump")
1259 ("▬▬▬▬▬▬▬▋ Ò╭╮Ó" "hammer") 1770 ("▬▬▬▬▬▬▬▋ Ò╭╮Ó" "hammer")
1260 ("👁👄👁" "lewk") 1771 ("👁👄👁" "lewk")
1261 ("( ͡~ ͜ʖ ͡°)" "wink") 1772 ("( ͡~ ͜ʖ ͡°)" "wink")
1262 ("⊙﹏⊙" "uhhh" "unsure"))) 1773 ("⊙﹏⊙" "uhhh" "unsure")))
1263 (add-to-list 'kaomoji-insert-alist km)) 1774 (add-to-list 'kaomoji-insert-alist km))
1264 (:global "C-x 8 k" #'kaomoji-insert)) 1775 (:global "C-x 8 k" #'kaomoji-insert))
1265 1776
@@ -1269,29 +1780,6 @@ specific to most general, they are these:
1269(setup (:straight-if ledger-mode 1780(setup (:straight-if ledger-mode
1270 (executable-find "ledger"))) 1781 (executable-find "ledger")))
1271 1782
1272(setup lines
1273 (:option fill-column 79
1274 word-wrap t
1275 truncate-lines nil)
1276
1277 (global-display-fill-column-indicator-mode +1)
1278 (global-so-long-mode +1)
1279
1280 (add-hook 'visual-line-mode-hook
1281 (defun acdw/disable-fill-column-indicator ()
1282 (display-fill-column-indicator-mode
1283 (if visual-line-mode -1 +1))))
1284
1285 ;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'.
1286 ;; I can't simply advise `kill-line' with an override from crux because crux
1287 ;; itself calls `kill-line', leading to a infinite nesting situation.
1288 (advice-add 'kill-line :around
1289 (defun kill-line@join (fn &rest args)
1290 (if (and (eolp)
1291 (not (bolp)))
1292 (delete-indentation 1)
1293 (apply fn args)))))
1294
1295(setup (:straight link-hint) 1783(setup (:straight link-hint)
1296 ;; Browse web URLs with a browser with a prefix argument. 1784 ;; Browse web URLs with a browser with a prefix argument.
1297 (dolist (type '(gnus-w3m-image-url 1785 (dolist (type '(gnus-w3m-image-url
@@ -1307,8 +1795,8 @@ specific to most general, they are these:
1307 w3m-link 1795 w3m-link
1308 w3m-message-link)) 1796 w3m-message-link))
1309 (link-hint-define-type type 1797 (link-hint-define-type type
1310 :open-secondary browse-url-secondary-browser-function 1798 :open-secondary browse-url-secondary-browser-function
1311 :open-secondary-multiple t)) 1799 :open-secondary-multiple t))
1312 1800
1313 (defun acdw/link-hint-open-all-links (prefix) 1801 (defun acdw/link-hint-open-all-links (prefix)
1314 "Open all visible links. 1802 "Open all visible links.
@@ -1316,7 +1804,7 @@ When PREFIX is non-nil, open links with
1316`browse-url-secondary-browser-function'." 1804`browse-url-secondary-browser-function'."
1317 (interactive "P") 1805 (interactive "P")
1318 (avy-with link-hint-open-all-links 1806 (avy-with link-hint-open-all-links
1319 (link-hint--all (if prefix :open-secondary :open)))) 1807 (link-hint--all (if prefix :open-secondary :open))))
1320 1808
1321 (defun acdw/link-hint-open-multiple-links (prefix) 1809 (defun acdw/link-hint-open-multiple-links (prefix)
1322 "Use `avy' to open multiple visible links at once. 1810 "Use `avy' to open multiple visible links at once.
@@ -1324,7 +1812,7 @@ When PREFIX is non-nil, open links with
1324`browse-url-secondary-browser-function'." 1812`browse-url-secondary-browser-function'."
1325 (interactive "P") 1813 (interactive "P")
1326 (avy-with link-hint-open-multiple-links 1814 (avy-with link-hint-open-multiple-links
1327 (link-hint--multiple (if prefix :open-secondary :open)))) 1815 (link-hint--multiple (if prefix :open-secondary :open))))
1328 1816
1329 (:option link-hint-avy-style 'post) 1817 (:option link-hint-avy-style 'post)
1330 (:global "C-;" 1818 (:global "C-;"
@@ -1393,29 +1881,6 @@ browser defined in `browse-url-secondary-browser-function'."
1393 (:hook #'hl-line-mode 1881 (:hook #'hl-line-mode
1394 #'reading-mode)) 1882 #'reading-mode))
1395 1883
1396(setup minibuffer
1397 (:option enable-recursive-minibuffers t
1398 file-name-shadow-properties '(invisible t intangible t)
1399 minibuffer-eldef-shorten-default t
1400 minibuffer-prompt-properties
1401 '(read-only t cursor-intangible t face minibuffer-prompt)
1402 read-answer-short t
1403 read-extended-command-predicate ; used on >28
1404 #'command-completion-default-include-p)
1405
1406 (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
1407
1408 (add-hook 'minibuffer-setup-hook #'acdw/gc-disable)
1409 (add-hook 'minibuffer-exit-hook #'acdw/gc-enable)
1410
1411 (minibuffer-depth-indicate-mode +1)
1412 (file-name-shadow-mode +1)
1413 (minibuffer-electric-default-mode +1)
1414
1415 (if (version< emacs-version "28")
1416 (fset 'yes-or-no-p #'y-or-n-p)
1417 (setq use-short-answers t)))
1418
1419(setup (:straight (modus-themes 1884(setup (:straight (modus-themes
1420 :host gitlab 1885 :host gitlab
1421 :repo "protesilaos/modus-themes")) 1886 :repo "protesilaos/modus-themes"))
@@ -1430,9 +1895,6 @@ browser defined in `browse-url-secondary-browser-function'."
1430 (acdw/sunrise-sunset #'modus-themes-load-operandi 1895 (acdw/sunrise-sunset #'modus-themes-load-operandi
1431 #'modus-themes-load-vivendi)) 1896 #'modus-themes-load-vivendi))
1432 1897
1433(setup mouse-avoidance
1434 (mouse-avoidance-mode 'exile))
1435
1436(setup (:straight mwim) 1898(setup (:straight mwim)
1437 (:global "C-a" #'mwim-beginning 1899 (:global "C-a" #'mwim-beginning
1438 "C-e" #'mwim-end)) 1900 "C-e" #'mwim-end))
@@ -1596,35 +2058,6 @@ browser defined in `browse-url-secondary-browser-function'."
1596 2058
1597(setup (:straight package-lint-flymake)) 2059(setup (:straight package-lint-flymake))
1598 2060
1599(setup page
1600 (:option page-delimiter
1601 (rx bol (or "\f" ";;;")
1602 (not (any "#")) (* not-newline) "\n"
1603 (* (* blank) (opt ";" (* not-newline)) "\n")))
1604
1605 (defun recenter-to-top (&rest _)
1606 "Recenter the cursor to the top of the window."
1607 (when (called-interactively-p 'any)
1608 (recenter (if (or (null scroll-margin)
1609 (zerop scroll-margin))
1610 3
1611 scroll-margin))))
1612
1613 (:advise forward-page :after #'recenter-to-top
1614 backward-page :after #'recenter-to-top)
1615
1616 ;; I'm not sure where this is in /my/ version of Emacs
1617 ;; (defvar page-navigation-repeat-map
1618 ;; (let ((map (make-sparse-keymap)))
1619 ;; (define-key map "]" #'forward-page)
1620 ;; (define-key map "[" #'backward-page)
1621 ;; map)
1622 ;; "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.")
1623
1624 ;; (put 'forward-page 'repeat-map 'page-navigation-repeat-map)
1625 ;; (put 'backward-page 'repeat-map 'page-navigation-repeat-map)
1626 )
1627
1628(setup (:straight page-break-lines) 2061(setup (:straight page-break-lines)
1629 (global-page-break-lines-mode +1)) 2062 (global-page-break-lines-mode +1))
1630 2063
@@ -1697,28 +2130,23 @@ browser defined in `browse-url-secondary-browser-function'."
1697 (setq-local comment-auto-fill-only-comments t) 2130 (setq-local comment-auto-fill-only-comments t)
1698 (turn-on-auto-fill))) 2131 (turn-on-auto-fill)))
1699 2132
1700 (add-hook 'after-save-hook 2133 (mapc (lambda (buf)
1701 #'executable-make-buffer-file-executable-if-script-p)) 2134 (with-current-buffer buf
2135 (when (funcall persistent-scratch-scratch-buffer-p-function)
2136 (persistent-scratch-mode +1))))
1702 2137
1703(setup (:require recentf) 2138 (buffer-list)))
1704 (:option recentf-save-file (acdw/dir "recentf.el")
1705 recentf-max-menu-items 100
1706 recentf-max-saved-items nil
1707 recentf-auto-cleanup 'mode
1708 (append recentf-exclude) (acdw/dir))
1709 2139
1710 (:advise dired-rename-file :after #'rjs/recentf-rename-notify) 2140(setup (:straight-if pkgbuild-mode
1711 2141 (executable-find "makepkg"))
1712 (recentf-mode +1)) 2142 (:file-match "PKGBUILD"))
1713 2143
1714(setup repeat 2144(setup (:straight powerthesaurus)
1715 ;; new for Emacs 28! 2145 (:global "C-c l t" #'powerthesaurus-lookup-word-dwim))
1716 (:only-if (fboundp #'repeat-mode))
1717 2146
1718 (:option repeat-exit-key "g" 2147(setup (:straight prism)
1719 repeat-exit-timeout 5) 2148 (dolist (mode lispy-modes)
1720 2149 (add-hook (intern (format "%s-hook" mode)) #'prism-mode)))
1721 (repeat-mode +1))
1722 2150
1723(setup (:straight restart-emacs) 2151(setup (:straight restart-emacs)
1724 (defun emacs-upgrade (&optional update-packages) 2152 (defun emacs-upgrade (&optional update-packages)
@@ -1730,93 +2158,6 @@ browser defined in `browse-url-secondary-browser-function'."
1730 (straight-x-pull-all)) 2158 (straight-x-pull-all))
1731 (restart-emacs))) 2159 (restart-emacs)))
1732 2160
1733(setup (:require savehist)
1734 (:option history-length t
1735 history-delete-duplicates t
1736 savehist-autosave-interval 60
1737 savehist-file (acdw/dir "savehist.el"))
1738
1739 (dolist (var '(extended-command-history
1740 global-mark-ring
1741 kill-ring
1742 regexp-search-ring
1743 search-ring
1744 mark-ring))
1745 (:option (append savehist-additional-variables) var))
1746
1747 (savehist-mode +1))
1748
1749(setup saveplace
1750 (:option save-place-file (acdw/dir "places.el")
1751 save-place-forget-unreadable-files (acdw/system :home))
1752
1753 (save-place-mode +1))
1754
1755(setup scratch
1756 (:option inhibit-startup-screen t
1757 initial-buffer-choice t
1758 initial-scratch-message ""
1759 ;; (concat ";; Howdy, "
1760 ;; (nth 0 (split-string
1761 ;; user-full-name))
1762 ;; "! "
1763 ;; "Welcome to GNU Emacs.\n\n")
1764 )
1765
1766 (add-hook 'kill-buffer-query-functions
1767 (defun kill-buffer-query@immortal-scratch ()
1768 (if (eq (current-buffer) (get-buffer "*scratch*"))
1769 (progn (bury-buffer)
1770 nil)
1771 t))))
1772
1773(setup scrolling
1774 (:option auto-window-vscroll nil
1775 fast-but-imprecise-scrolling t
1776 scroll-margin 3
1777 scroll-conservatively 101
1778 scroll-preserve-screen-position 1))
1779
1780(setup selection
1781 (:option save-interprogram-paste-before-kill t
1782 yank-pop-change-selection t
1783 x-select-enable-clipboard t
1784 x-select-enable-primary t
1785 mouse-drag-copy-region t
1786 kill-do-not-save-duplicates t)
1787
1788 (delete-selection-mode +1))
1789
1790(setup (:require server)
1791 (unless (server-running-p)
1792 (server-start)))
1793
1794(setup sh-mode
1795 (:option sh-basic-offset tab-width
1796 sh-indent-after-case 0
1797 sh-indent-for-case-alt '+
1798 sh-indent-for-case-label 0)
1799
1800 (:local-set indent-tabs-mode t)
1801
1802 (when (executable-find "shfmt")
1803 (with-eval-after-load 'apheleia
1804 (:option (append apheleia-formatters) '(shfmt . ("shfmt"))
1805 (append apheleia-mode-alist) '(sh-mode . shfmt))))
1806
1807 (when (executable-find "shellcheck")
1808 (:straight flymake-shellcheck)
1809 (:hook flymake-mode
1810 flymake-shellcheck-load)))
1811
1812(setup shell-command
1813 (:option shell-command-switch (acdw/system
1814 ;; I should be testing on some variable
1815 (:home "-csi")
1816 (:work "-c"))
1817 shell-command-prompt-show-cwd t
1818 shell-command-default-error-buffer "*shell-command-errors*"))
1819
1820(setup (:straight (shell-command+ 2161(setup (:straight (shell-command+
1821 :host nil 2162 :host nil
1822 :repo "https://git.sr.ht/~pkal/shell-command-plus")) 2163 :repo "https://git.sr.ht/~pkal/shell-command-plus"))
@@ -1825,14 +2166,6 @@ browser defined in `browse-url-secondary-browser-function'."
1825 (:bind "M-!" shell-command+)) 2166 (:bind "M-!" shell-command+))
1826 (:global "M-!" shell-command+)) 2167 (:global "M-!" shell-command+))
1827 2168
1828(setup shr
1829 (:option shr-width fill-column
1830 shr-max-width fill-column
1831 shr-max-image-proportion 0.6
1832 shr-image-animate t
1833 shr-discard-aria-hidden t
1834 shr-folding-mode t))
1835
1836(setup (:straight simple-modeline 2169(setup (:straight simple-modeline
1837 minions) 2170 minions)
1838 (:also-load acdw-modeline) 2171 (:also-load acdw-modeline)
@@ -1921,11 +2254,6 @@ browser defined in `browse-url-secondary-browser-function'."
1921(setup (:straight-if systemd 2254(setup (:straight-if systemd
1922 (executable-find "systemd"))) 2255 (executable-find "systemd")))
1923 2256
1924(setup text
1925 (:hook turn-on-auto-fill
1926 tildify-mode
1927 acdw/setup-fringes))
1928
1929(setup (:straight (topsy 2257(setup (:straight (topsy
1930 :host github 2258 :host github
1931 :repo "alphapapa/topsy.el")) 2259 :repo "alphapapa/topsy.el"))
@@ -1989,20 +2317,6 @@ If used with a numeric prefix argument N, N backticks will be inserted."
1989 (save-some-buffers t)) 2317 (save-some-buffers t))
1990 #'garbage-collect))) 2318 #'garbage-collect)))
1991 2319
1992(setup uniquify
1993 (:option uniquify-buffer-name-style 'forward
1994 uniquify-separator path-separator
1995 uniquify-after-kill-buffer-p t
1996 uniquify-ignore-buffers-re "^\\*"))
1997
1998(setup variable-pitch-mode
1999 ;; I might want to change this to `buffer-face-mode-hook'...
2000 (:advise variable-pitch-mode :after
2001 (defun variable-pitch-mode@setup (&rest _)
2002 "Set up `variable-pitch-mode' with my customizations."
2003 (display-fill-column-indicator-mode
2004 (if buffer-face-mode -1 +1)))))
2005
2006(setup (:straight (vertico 2320(setup (:straight (vertico
2007 :host github 2321 :host github
2008 :repo "minad/vertico" 2322 :repo "minad/vertico"
@@ -2040,12 +2354,6 @@ If used with a numeric prefix argument N, N backticks will be inserted."
2040 " ") 2354 " ")
2041 cand)))) 2355 cand))))
2042 2356
2043(setup view
2044 (:option view-read-only t)
2045
2046 (:hook (defun acdw/read-view-mode ()
2047 (reading-mode (if view-mode +1 -1)))))
2048
2049(setup (:straight visual-regexp) 2357(setup (:straight visual-regexp)
2050 (:global "M-%" #'vr/query-replace)) 2358 (:global "M-%" #'vr/query-replace))
2051 2359
@@ -2057,15 +2365,6 @@ If used with a numeric prefix argument N, N backticks will be inserted."
2057 (eshell-vterm-mode +1) 2365 (eshell-vterm-mode +1)
2058 (defalias 'eshell/v 'eshell-exec-visual)) 2366 (defalias 'eshell/v 'eshell-exec-visual))
2059 2367
2060(setup w32
2061 (:option w32-allow-system-shell t
2062 w32-pass-lwindow-to-system nil
2063 w32-lwindow-modifier 'super
2064 w32-pass-rwindow-to-system nil
2065 w32-rwindow-modifier 'super
2066 w32-pass-apps-to-system nil
2067 w32-apps-modifier 'hyper))
2068
2069(setup (:straight wc-mode) 2368(setup (:straight wc-mode)
2070 (:option wc-modeline-format "[%tww]" 2369 (:option wc-modeline-format "[%tww]"
2071 wc-idle-wait 2) 2370 wc-idle-wait 2)
@@ -2096,101 +2395,9 @@ If used with a numeric prefix argument N, N backticks will be inserted."
2096 (which-key-setup-side-window-right-bottom) 2395 (which-key-setup-side-window-right-bottom)
2097 (which-key-mode +1)) 2396 (which-key-mode +1))
2098 2397
2099(setup whitespace
2100 (:option whitespace-style '(empty
2101 indentation
2102 space-before-tab
2103 space-after-tab)
2104 indent-tabs-mode nil
2105 tab-width 4
2106 backward-delete-char-untabify-method 'hungry)
2107
2108 (:global "M-SPC" #'cycle-spacing))
2109
2110(setup (:straight whitespace-cleanup-mode) 2398(setup (:straight whitespace-cleanup-mode)
2111 (global-whitespace-cleanup-mode +1)) 2399 (global-whitespace-cleanup-mode +1))
2112 2400
2113(setup windmove
2114 (:option windmove-wrap-around t)
2115 (:global
2116 ;; moving
2117 "C-x 4 <left>" #'windmove-left
2118 "C-x 4 <right>" #'windmove-right
2119 "C-x 4 <up>" #'windmove-up
2120 "C-x 4 <down>" #'windmove-down
2121 ;; swapping
2122 "C-x 4 S-<left>" #'windmove-swap-states-left
2123 "C-x 4 S-<right>" #'windmove-swap-states-right
2124 "C-x 4 S-<up>" #'windmove-swap-states-up
2125 "C-x 4 S-<down>" #'windmove-swap-states-down)
2126
2127 ;; (when (fboundp 'repeat-mode)
2128 ;; (defvar windmove-repeat-map
2129 ;; (let ((map (make-sparse-keymap)))
2130 ;; ;; moving
2131 ;; (define-key map [left] #'windmove-left)
2132 ;; (define-key map [right] #'windmove-right)
2133 ;; (define-key map [up] #'windmove-up)
2134 ;; (define-key map [down] #'windmove-down)
2135 ;; ;; swapping
2136 ;; (define-key map [S-left] #'windmove-swap-states-left)
2137 ;; (define-key map [S-right] #'windmove-swap-states-right)
2138 ;; (define-key map [S-up] #'windmove-swap-states-up)
2139 ;; (define-key map [S-down] #'windmove-swap-states-down)
2140 ;; map)
2141 ;; "Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.")
2142
2143 ;; (dolist (sym '(windmove-left
2144 ;; windmove-right
2145 ;; windmove-up
2146 ;; windmove-down
2147 ;; windmove-swap-states-left
2148 ;; windmove-swap-states-right
2149 ;; windmove-swap-states-up
2150 ;; windmove-swap-states-down))
2151 ;; (put sym 'repeat-map 'windmove-repeat-map)))
2152 )
2153
2154(setup window
2155 (require 'acdw-bell)
2156 (:option
2157 ;; Man-notify-method 'pushy
2158 ;; display-buffer-alist ; from FrostyX
2159 ;; '(("shell.*" (display-buffer-same-window) ())
2160 ;; (".*" (display-buffer-reuse-window
2161 ;; display-buffer-same-window)
2162 ;; (reusable-frames . t)))
2163 recenter-positions '(top middle bottom)
2164 ring-bell-function (lambda ()
2165 (acdw-bell/flash-mode-line
2166 (acdw/system :home)))
2167 use-dialog-box nil
2168 use-file-dialog nil
2169 visible-bell nil)
2170
2171 (tooltip-mode -1))
2172
2173(setup winner
2174 ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html
2175 (:global "C-x 4 C-/" #'winner-undo
2176 "C-x 4 /" #'winner-undo
2177 "C-x 4 C-?" #'winner-redo
2178 "C-x 4 ?" #'winner-redo)
2179
2180 ;; add `winner-undo' and `winner-redo' to `repeat-mode'
2181 ;; (when (fboundp 'repeat-mode)
2182 ;; (defvar winner-mode-repeat-map
2183 ;; (let ((map (make-sparse-keymap)))
2184 ;; (define-key map "/" #'winner-undo)
2185 ;; (define-key map "?" #'winner-redo)
2186 ;; map)
2187 ;; "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.")
2188
2189 ;; (put 'winner-undo 'repeat-map 'winner-mode-repeat-map)
2190 ;; (put 'winner-redo 'repeat-map 'winner-mode-repeat-map))
2191
2192 (winner-mode +1))
2193
2194(setup (:straight winum) 2401(setup (:straight winum)
2195 (:option winum-scope 'frame-local 2402 (:option winum-scope 'frame-local
2196 winum-auto-setup-mode-line nil 2403 winum-auto-setup-mode-line nil