summary refs log tree commit diff stats
path: root/init.el
diff options
context:
space:
mode:
Diffstat (limited to 'init.el')
-rw-r--r--init.el1312
1 files changed, 573 insertions, 739 deletions
diff --git a/init.el b/init.el index edbc99c..965ec06 100644 --- a/init.el +++ b/init.el
@@ -15,74 +15,59 @@
15;; - Make good choices. 15;; - Make good choices.
16 16
17;;; Code: 17;;; Code:
18
19;;; Setup
20
21;;;; `setup'
22(straight-use-package '(setup :host nil :repo "https://git.sr.ht/~pkal/setup"))
23(require 'setup)
24
25(setup setup
26 ;; Install a package using `straight-use-package'
27 (setup-define :straight
28 (lambda (recipe)
29 `(straight-use-package ',recipe))
30 :documentation
31 "Install RECIPE with `straight-use-package'.
32This macro can be used as HEAD, and will replace itself with the
33first RECIPE's package."
34 :repeatable t
35 :shorthand (lambda (sexp)
36 (let ((recipe (cadr sexp)))
37 (if (consp recipe)
38 (car recipe)
39 recipe))))
40 ;; Install a package with straight, but only under a condition
41 (setup-define :straight-if
42 (lambda (recipe condition)
43 `(if ,condition
44 (straight-use-package ',recipe)
45 ,(setup-quit)))
46 :documentation
47 "Install RECIPE with `straight-use-package' when CONDITION is met.
48If CONDITION is false, stop evaluating the body. This macro can
49be used as HEAD, and will replace itself with the RECIPE's
50package. This macro is not repeatable."
51 :repeatable nil
52 :shorthand (lambda (sexp)
53 (let ((recipe (cadr sexp)))
54 (if (consp recipe) (car recipe) recipe)))))
55
56;;;; `no-littering'
57(setup (:straight no-littering)
58 (:option no-littering-etc-directory (acdw/dir)
59 no-littering-var-directory (acdw/dir))
60 (require 'no-littering))
61
62;;;; My packages
63(when-let ((default-directory
64 (expand-file-name-exists-p "pkg/" user-emacs-directory)))
65 (normal-top-level-add-subdirs-to-load-path))
66
67;;;; Private stuff
68(acdw/require-private)
69
70;;;; Compatibility with older versions
71(require 'acdw-compat)
72
73;;;; Lisp
74(require 'acdw-lisp)
75 18
76 19;;; Built-ins
77;;; Basics
78;; NOTE that some of the names in `setup' forms are arbitrary. 20;; NOTE that some of the names in `setup' forms are arbitrary.
79 21
22(setup (:require auth-source)
23 (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg")))
24
25(setup (:require recentf)
26 (:option recentf-save-file (acdw/dir "recentf.el")
27 recentf-max-menu-items 100
28 recentf-max-saved-items nil
29 recentf-auto-cleanup 'mode
30 (append recentf-exclude) (acdw/dir))
31
32 (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify)
33
34 (recentf-mode +1))
35
36(setup (:require savehist)
37 (:option history-length t
38 history-delete-duplicates t
39 savehist-autosave-interval 60
40 savehist-file (acdw/dir "savehist.el"))
41
42 (dolist (var '(extended-command-history
43 global-mark-ring
44 kill-ring
45 regexp-search-ring
46 search-ring
47 mark-ring))
48 (add-to-list 'savehist-additional-variables var))
49
50 (savehist-mode +1))
51
52(setup (:require server)
53 (unless (server-running-p)
54 (server-start)))
55
56(setup Info
57 (:hook variable-pitch-mode
58 acdw/reading-mode))
59
80(setup acdw 60(setup acdw
61 (:also-load acdw-compat
62 acdw-lisp)
63 (acdw/require-private)
64
81 (:option user-full-name "Case Duckworth" 65 (:option user-full-name "Case Duckworth"
82 user-mail-address "acdw@acdw.net")) 66 user-mail-address "acdw@acdw.net")
83 67
84(setup (:require auth-source) 68 (when-let ((default-directory
85 (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg"))) 69 (expand-file-name-exists-p "pkg/" user-emacs-directory)))
70 (normal-top-level-add-subdirs-to-load-path)))
86 71
87(setup autorevert 72(setup autorevert
88 (:option global-auto-revert-non-file-buffers t) 73 (:option global-auto-revert-non-file-buffers t)
@@ -133,8 +118,7 @@ package. This macro is not repeatable."
133 (:global "C-x k" acdw/kill-a-buffer)) 118 (:global "C-x k" acdw/kill-a-buffer))
134 119
135(setup calendar 120(setup calendar
136 (:option calendar-week-start-day 1 ; Monday 121 (:option calendar-week-start-day 1))
137 ))
138 122
139(setup completion 123(setup completion
140 (:option completion-ignore-case t 124 (:option completion-ignore-case t
@@ -153,7 +137,6 @@ package. This macro is not repeatable."
153 (blink-cursor-mode +1)) 137 (blink-cursor-mode +1))
154 138
155(setup cus-edit 139(setup cus-edit
156
157 (:option custom-file null-device ; don't store customizations 140 (:option custom-file null-device ; don't store customizations
158 custom-magic-show nil 141 custom-magic-show nil
159 custom-magic-show-button t 142 custom-magic-show-button t
@@ -312,20 +295,10 @@ package. This macro is not repeatable."
312 (add-hook 'emacs-lisp-mode-hook #'turn-on-eldoc-mode) 295 (add-hook 'emacs-lisp-mode-hook #'turn-on-eldoc-mode)
313 (add-hook 'ielm-mode-hook #'turn-on-eldoc-mode) 296 (add-hook 'ielm-mode-hook #'turn-on-eldoc-mode)
314 297
315 (setup (:straight macrostep)
316 (define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand))
317
318 (setup (:straight eros)
319 (:hook-into emacs-lisp-mode))
320
321 ;; Add advice to pulse evaluated regions 298 ;; Add advice to pulse evaluated regions
322 (define-advice eval-region (:around (fn start end &rest args) pulse-region) 299 (define-advice eval-region (:around (fn start end &rest args) pulse-region)
323 (pulse-momentary-highlight-region start end) 300 (pulse-momentary-highlight-region start end)
324 (apply fn start end args)) 301 (apply fn start end args)))
325
326 (setup (:straight elisp-slime-nav)
327 (:hook-into emacs-lisp-mode
328 ielm-mode)))
329 302
330(setup encoding 303(setup encoding
331 (:option locale-coding-system 'utf-8-unix 304 (:option locale-coding-system 'utf-8-unix
@@ -351,104 +324,6 @@ package. This macro is not repeatable."
351 (_ (set-selection-coding-system 'utf-8) 324 (_ (set-selection-coding-system 'utf-8)
352 (set-clipboard-coding-system 'utf-8)))) 325 (set-clipboard-coding-system 'utf-8))))
353 326
354(setup erc
355 (:require acdw-erc)
356 (:also-load erc-autoaway
357 erc-track
358 erc-goodies)
359
360 (:option
361 erc-auto-discard-away t
362 erc-auto-set-away t
363 erc-autoaway-idle-seconds 600
364 erc-autoaway-message "BRB (autoaway: %i seconds)"
365 erc-button-url-regexp browse-url-button-regexp
366 erc-common-server-suffixes '(("tilde.chat\\'" . "~")
367 ("libera.chat\\'" . "LC"))
368 erc-default-server "irc.tilde.chat"
369 erc-fill-function #'erc-fill-static
370 erc-fill-static-center 14
371 erc-format-nick-function #'erc-format-truncate-@nick
372 erc-header-line-face-method #'erc/update-header-line-show-disconnected
373 erc-hide-list '("NICK" "MODE" "JOIN" "PART" "QUIT" "AWAY")
374 erc-interpret-controls-p t
375 erc-interpret-mirc-color t
376 erc-join-buffer 'bury
377 erc-kill-buffer-on-part t
378 erc-kill-queries-on-quit t
379 erc-kill-server-buffer-on-quit t
380 erc-nick "acdw"
381 erc-nick-truncate (- erc-fill-static-center 1)
382 erc-pcomplete-nick-postfix ":"
383 erc-prompt #'acdw-erc/prompt
384 erc-prompt-for-password nil ; use ~/.authinfo
385 erc-rename-buffers t
386 erc-server erc-default-server
387 erc/servers
388 (when (boundp 'erc-autojoin-channels-alist)
389 (mapcar #'car erc-autojoin-channels-alist))
390 erc-server-coding-system '(utf-8 . utf-8)
391 erc-timestamp-intangible t
392 erc-track-exclude-types (append erc-hide-list
393 '("AWAY" ; for some reason this triggers
394 ; track anyway... so it's in
395 ; `erc-hide-list'
396 "353" "324" "329" "332" "333" "477"))
397 erc-track-exclude-server-buffer t
398 erc-track-position-in-mode-line 'before-modes
399 erc-track-visibility nil ; only the selected frame
400 )
401
402 ;; Thanks bpalmer!
403 (advice-add 'show-paren-function :around
404 (defun show-paren@skip-in-erc (f &rest r)
405 "Skip `show-paren-mode' in `erc-mode'."
406 (unless (derived-mode-p 'erc-mode)
407 (apply f r))))
408
409 (add-hook 'kill-emacs-hook #'erc/disconnect)
410
411 (add-hook 'erc-mode-hook
412 (defun erc-mode@setup ()
413 (setq-local scroll-margin 0)))
414
415 (:hook erc-autoaway-mode
416 erc-track-mode
417 erc-truncate-mode)
418
419 ;; disable ERC tracking when working ... BE PRODUCTIVE!
420 (add-hook 'org-clock-in-hook #'erc-track-disable)
421 (add-hook 'org-clock-out-hook #'erc-track-enable)
422
423 (:bind "C-c C-b" acdw-erc/erc-switch-to-buffer
424 "C-c C-c" nil ; def: `erc-toggle-interpret-controls'
425 )
426
427 (with-eval-after-load 'erc
428 (when (acdw/system :work)
429 ;; IDK why, but on 28 this bit doesn't work -- which is at home.
430 (setup (:straight erc-hl-nicks)
431 (:option (append erc-modules) 'hl-nicks
432 erc-hl-nicks-minimum-contrast-ratio 4.5
433 erc-hl-nicks-color-contrast-strategy '(invert contrast))
434 (:hook-into erc-mode)
435 ;; Refresh nick colors after changing modus theme
436 ;; Ideally, there'd be a hook for /any/ time we changed theme... but
437 ;; whatever.
438 (add-hook 'modus-themes-after-load-theme-hook
439 #'erc-hl-nicks-refresh-colors)))
440
441 ;; (setup (:straight erc-image)
442 ;; (:option (append erc-modules) 'image
443 ;; erc-image-inline-rescale 300))
444
445 ;; Rewrite `erc-quit/part-reason-default'
446 (defun erc-quit/part-reason-default ()
447 "Default quit/part message."
448 (format "\C-iSee You, Space Cowpokes. . .\C-i"))
449
450 (erc-update-modules)))
451
452(setup eshell 327(setup eshell
453 (:also-load acdw-eshell 328 (:also-load acdw-eshell
454 em-smart) 329 em-smart)
@@ -516,16 +391,6 @@ like a dumbass."
516(setup flyspell 391(setup flyspell
517 (add-hook 'text-mode-hook #'flyspell-mode)) 392 (add-hook 'text-mode-hook #'flyspell-mode))
518 393
519(setup (:straight flyspell-correct)
520 (add-hook 'flyspell-mode-hook
521 (defun flyspell-mode@flyspell-correct ()
522 (dolist (keybind '(("C-;" . flyspell-correct-wrapper)
523 ("C-," . nil)
524 ("C-." . nil)
525 ("C-M-i" . nil)))
526 (define-key flyspell-mode-map
527 (kbd (car keybind)) (cdr keybind))))))
528
529(setup frames 394(setup frames
530 (:option frame-title-format '("%b@" 395 (:option frame-title-format '("%b@"
531 (:eval 396 (:eval
@@ -571,7 +436,9 @@ like a dumbass."
571 (mode . gnus-article-mode) 436 (mode . gnus-article-mode)
572 (name . "^\\.bbdb$") 437 (name . "^\\.bbdb$")
573 (name . "^\\.newsrc-dribble") 438 (name . "^\\.newsrc-dribble")
574 (mode . erc-mode))) 439 (mode . erc-mode)
440 (mode . circe-server-mode)
441 (mode . circe-channel-mode)))
575 ("shell" (or (mode . eshell-mode) 442 ("shell" (or (mode . eshell-mode)
576 (mode . shell-mode) 443 (mode . shell-mode)
577 (mode . vterm-mode))) 444 (mode . vterm-mode)))
@@ -591,10 +458,6 @@ like a dumbass."
591(setup imenu 458(setup imenu
592 (:option imenu-auto-rescan t)) 459 (:option imenu-auto-rescan t))
593 460
594(setup Info
595 (:hook variable-pitch-mode
596 acdw/reading-mode))
597
598(setup isearch 461(setup isearch
599 (:option search-default-mode t)) 462 (:option search-default-mode t))
600 463
@@ -726,17 +589,6 @@ like a dumbass."
726 "C-g" reb-quit 589 "C-g" reb-quit
727 "C-c C-k" reb-quit)))) 590 "C-c C-k" reb-quit))))
728 591
729(setup (:require recentf)
730 (:option recentf-save-file (acdw/dir "recentf.el")
731 recentf-max-menu-items 100
732 recentf-max-saved-items nil
733 recentf-auto-cleanup 'mode
734 (append recentf-exclude) (acdw/dir))
735
736 (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify)
737
738 (recentf-mode +1))
739
740(setup repeat 592(setup repeat
741 ;; new for Emacs 28! 593 ;; new for Emacs 28!
742 (:only-if (fboundp #'repeat-mode)) 594 (:only-if (fboundp #'repeat-mode))
@@ -746,22 +598,6 @@ like a dumbass."
746 598
747 (repeat-mode +1)) 599 (repeat-mode +1))
748 600
749(setup (:require savehist)
750 (:option history-length t
751 history-delete-duplicates t
752 savehist-autosave-interval 60
753 savehist-file (acdw/dir "savehist.el"))
754
755 (dolist (var '(extended-command-history
756 global-mark-ring
757 kill-ring
758 regexp-search-ring
759 search-ring
760 mark-ring))
761 (add-to-list 'savehist-additional-variables var))
762
763 (savehist-mode +1))
764
765(setup saveplace 601(setup saveplace
766 (:option save-place-file (acdw/dir "places.el") 602 (:option save-place-file (acdw/dir "places.el")
767 save-place-forget-unreadable-files (acdw/system :home)) 603 save-place-forget-unreadable-files (acdw/system :home))
@@ -803,10 +639,6 @@ like a dumbass."
803 639
804 (delete-selection-mode +1)) 640 (delete-selection-mode +1))
805 641
806(setup (:require server)
807 (unless (server-running-p)
808 (server-start)))
809
810(setup sh-mode 642(setup sh-mode
811 (:option sh-basic-offset tab-width 643 (:option sh-basic-offset tab-width
812 sh-indent-after-case 0 644 sh-indent-after-case 0
@@ -864,10 +696,18 @@ like a dumbass."
864(setup view 696(setup view
865 (:option view-read-only t) 697 (:option view-read-only t)
866 698
867 (defun acdw/read-view-mode () 699 (add-hook 'view-mode-hook
868 (acdw/reading-mode (if view-mode +1 -1))) 700 (defun acdw/read-view-mode ()
869 701 (acdw/reading-mode (if view-mode +1 -1)))))
870 (:hook acdw/read-view-mode)) 702
703(setup w32
704 (:option w32-allow-system-shell t
705 w32-pass-lwindow-to-system nil
706 w32-lwindow-modifier 'super
707 w32-pass-rwindow-to-system nil
708 w32-rwindow-modifier 'super
709 w32-pass-apps-to-system nil
710 w32-apps-modifier 'hyper))
871 711
872(setup whitespace 712(setup whitespace
873 (:option whitespace-style 713 (:option whitespace-style
@@ -878,40 +718,6 @@ like a dumbass."
878 718
879 (:global "M-SPC" cycle-spacing)) 719 (:global "M-SPC" cycle-spacing))
880 720
881(setup windows
882 (require 'acdw-bell)
883 (:option use-dialog-box nil
884 use-file-dialog nil
885 tab-bar-show 1
886 visible-bell nil
887 ring-bell-function (lambda ()
888 (acdw-bell/flash-mode-line
889 (acdw/system :home)))
890 recenter-positions '(top middle bottom))
891
892 (tooltip-mode -1))
893
894(setup winner
895 ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html
896 (:global "C-x 4 C-/" winner-undo
897 "C-x 4 /" winner-undo
898 "C-x 4 C-?" winner-redo
899 "C-x 4 ?" winner-redo)
900
901 ;; add `winner-undo' and `winner-redo' to `repeat-mode'
902 (when (fboundp 'repeat-mode)
903 (defvar winner-mode-repeat-map
904 (let ((map (make-sparse-keymap)))
905 (define-key map "/" #'winner-undo)
906 (define-key map "?" #'winner-redo)
907 map)
908 "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.")
909
910 (put 'winner-undo 'repeat-map 'winner-mode-repeat-map)
911 (put 'winner-redo 'repeat-map 'winner-mode-repeat-map))
912
913 (winner-mode +1))
914
915(setup windmove 721(setup windmove
916 (:option windmove-wrap-around t) 722 (:option windmove-wrap-around t)
917 (:global 723 (:global
@@ -952,19 +758,44 @@ like a dumbass."
952 windmove-swap-states-down)) 758 windmove-swap-states-down))
953 (put sym 'repeat-map 'windmove-repeat-map)))) 759 (put sym 'repeat-map 'windmove-repeat-map))))
954 760
955(setup w32 761(setup windows
956 (:option w32-allow-system-shell t 762 (require 'acdw-bell)
957 w32-pass-lwindow-to-system nil 763 (:option use-dialog-box nil
958 w32-lwindow-modifier 'super 764 use-file-dialog nil
959 w32-pass-rwindow-to-system nil 765 tab-bar-show 1
960 w32-rwindow-modifier 'super 766 visible-bell nil
961 w32-pass-apps-to-system nil 767 ring-bell-function (lambda ()
962 w32-apps-modifier 'hyper)) 768 (acdw-bell/flash-mode-line
769 (acdw/system :home)))
770 recenter-positions '(top middle bottom))
771
772 (tooltip-mode -1))
963 773
964;;; "Et cetera" settings 774(setup winner
965;; This should stay as /minimal/ as possible. Anything that can go somewhere 775 ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html
966;; else /should/ go there. 776 (:global "C-x 4 C-/" winner-undo
967(setup emacs 777 "C-x 4 /" winner-undo
778 "C-x 4 C-?" winner-redo
779 "C-x 4 ?" winner-redo)
780
781 ;; add `winner-undo' and `winner-redo' to `repeat-mode'
782 (when (fboundp 'repeat-mode)
783 (defvar winner-mode-repeat-map
784 (let ((map (make-sparse-keymap)))
785 (define-key map "/" #'winner-undo)
786 (define-key map "?" #'winner-redo)
787 map)
788 "Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.")
789
790 (put 'winner-undo 'repeat-map 'winner-mode-repeat-map)
791 (put 'winner-redo 'repeat-map 'winner-mode-repeat-map))
792
793 (winner-mode +1))
794
795(setup x-emacs
796 ;; "Et cetera" settings
797 ;; This should stay as /minimal/ as possible. Anything that can go somewhere
798 ;; else /should/ go there.
968 (:option 799 (:option
969 attempt-orderly-shutdown-on-fatal-signal nil 800 attempt-orderly-shutdown-on-fatal-signal nil
970 attempt-stack-overflow-recovery nil 801 attempt-stack-overflow-recovery nil
@@ -1007,7 +838,6 @@ like a dumbass."
1007 (defalias 'backward-word-with-case 'backward-word 838 (defalias 'backward-word-with-case 'backward-word
1008 "Alias for `backward-word for use in `case-repeat-map'.") 839 "Alias for `backward-word for use in `case-repeat-map'.")
1009 840
1010 ;; XXX: this isn't repeating correctly ...
1011 (defvar case-repeat-map 841 (defvar case-repeat-map
1012 (let ((map (make-sparse-keymap))) 842 (let ((map (make-sparse-keymap)))
1013 (define-key map "c" #'capitalize-word) 843 (define-key map "c" #'capitalize-word)
@@ -1027,7 +857,12 @@ like a dumbass."
1027 downcase-dwim 857 downcase-dwim
1028 forward-word-with-case 858 forward-word-with-case
1029 backward-word-with-case)) 859 backward-word-with-case))
1030 (put command 'repeat-map 'case-repeat-map))) 860 (put command 'repeat-map 'case-repeat-map))
861
862 (add-hook 'after-make-frame-functions
863 (defun after-make-frame@maximize (frame)
864 (unless (bound-and-true-p edit-server-frame-p)
865 (toggle-frame-maximized frame)))))
1031 866
1032 867
1033;;; Packages 868;;; Packages
@@ -1053,152 +888,9 @@ like a dumbass."
1053 (apheleia--get-formatter-command))) 888 (apheleia--get-formatter-command)))
1054 (indent-region (point-min) (point-max)))))) 889 (indent-region (point-min) (point-max))))))
1055 890
1056(setup (:straight-if affe
1057 (and (or (executable-find "fd")
1058 (executable-find "find"))
1059 (executable-find "rg")))
1060 ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find'
1061 (defun affe-orderless-regexp-compiler (input _type)
1062 (setq input (orderless-pattern-compiler input))
1063 (cons input (lambda (str) (orderless--highlight input str))))
1064
1065 (:option affe-regexp-compiler #'affe-orderless-regexp-compiler))
1066
1067(setup (:straight async)
1068 (autoload 'dired-async-mode "dired-async.el" nil t)
1069 (dired-async-mode +1)
1070 (add-hook 'dired-mode
1071 (defun dired@disable-dired-async-mode-line ()
1072 (autoload 'dired-async--modeline-mode "dired-async.el" nil t)
1073 (dired-async--modeline-mode -1))))
1074
1075(setup (:straight alert)
1076 (:option alert-default-style (acdw/system
1077 (:home 'libnotify)
1078 (_ 'message))))
1079
1080(setup (:straight avy)
1081 (:global "C-'" avy-goto-char-timer
1082 "M-g f" avy-goto-line
1083 "M-g w" avy-goto-word-1
1084 "C-c C-j" avy-resume)
1085
1086 (with-eval-after-load "isearch"
1087 (define-key isearch-mode-map (kbd "C-'") #'avy-isearch)))
1088
1089(setup (:straight (beginend)) 891(setup (:straight (beginend))
1090 (beginend-global-mode +1)) 892 (beginend-global-mode +1))
1091 893
1092(setup (:straight circe)
1093 (require 'circe)
1094 (require 'acdw-irc)
1095
1096 (setq acdw-irc/post-my-nick "-> ")
1097
1098 (setq circe-default-nick "acdw"
1099 circe-default-part-message "See You, Space Cowpokes . . ."
1100 circe-highlight-nick-type 'all
1101 circe-network-options
1102 (("Libera Chat"
1103 :channels ("#emacs" "#systemcrafters" "##webpals")
1104 :sasl-username "acdw"
1105 :sasl-password ,(acdw/fetch-password :host "libera.chat"))
1106 ("Tilde Chat"
1107 :channels ("#meta" "#bread" "#dadjokes" "#team")
1108 :host "irc.tilde.chat" :port 6697 :use-tls t
1109 :sasl-username "acdw"
1110 :sasl-password ,(acdw/fetch-password :host "tilde.chat"))
1111 ("Casa"
1112 :channels ("#basement")
1113 :host "m455.casa" :port 6697 :use-tls t
1114 :sasl-username "acdw"
1115 :sasl-password ,(acdw/fetch-password :host "m455.casa")))
1116 circe-reduce-lurker-spam t
1117 circe-server-auto-join-default-type :after-auth)
1118
1119 (defun irc ()
1120 "Connect to IRC."
1121 (interactive)
1122 (dolist (network (mapcar #'car circe-network-options))
1123 (circe-maybe-connect network)))
1124
1125 (defun circe-network-connected-p (network)
1126 "Return non-nil if there's any Circe server-buffer whose
1127`circe-server-netwok' is NETWORK."
1128 (catch 'return
1129 (dolist (buffer (circe-server-buffers))
1130 (with-current-buffer buffer
1131 (if (string= network circe-server-network)
1132 (throw 'return t))))))
1133
1134 (defun circe-maybe-connect (network)
1135 "Connect to NETWORK, but ask user for confirmation if it's
1136already been connected to."
1137 (interactive "sNetwork: ")
1138 (if (or (not (circe-network-connected-p network))
1139 (y-or-n-p (format "Already connected to %s, reconnect?" network)))
1140 (circe network)))
1141
1142 (add-hook 'circe-chat-mode-hook
1143 (defun circe-chat@setup ()
1144 (lui-set-prompt
1145 (concat (propertize (acdw-irc/margin-format (buffer-name)
1146 ""
1147 ">")
1148 'face 'circe-prompt-face
1149 'read-only t 'intangible t
1150 'cursor-intangible t)
1151 " "))
1152 (enable-circe-color-nicks)
1153 (enable-circe-display-images)
1154 (enable-circe-new-day-notifier)))
1155
1156 (add-hook 'modus-themes-after-load-theme-hook
1157 #'circe-nick-color-reset)
1158
1159 (let ((len (number-to-string (- acdw-irc/left-margin 1
1160 (+ (length acdw-irc/pre-nick)
1161 (length acdw-irc/post-nick)))))
1162 (my-len (number-to-string (- acdw-irc/left-margin 1
1163 (+ (length acdw-irc/pre-my-nick)
1164 (length acdw-irc/post-my-nick))))))
1165 (setq circe-format-say (concat acdw-irc/pre-nick
1166 "{nick:" len "." len "s} "
1167 acdw-irc/post-nick
1168 "{body}")
1169 circe-format-self-say (concat acdw-irc/pre-my-nick
1170 "{nick:" my-len "." my-len "s} "
1171 acdw-irc/post-my-nick
1172 "{body}")
1173 circe-format-action (concat "*"
1174 (repeat-string
1175 (- acdw-irc/left-margin 3)
1176 " ")
1177 "* {nick} {body}")
1178 circe-format-self-action (concat "-*"
1179 (repeat-string
1180 (- acdw-irc/left-margin 4)
1181 " ")
1182 "* {nick} {body}")
1183 lui-fill-type (concat
1184 (repeat-string (- acdw-irc/left-margin 2)
1185 " ")
1186 " ")))
1187
1188 (setq lui-time-stamp-position 'right-margin
1189 lui-time-stamp-format "%H:%M")
1190 (add-hook 'lui-mode-hook
1191 (defun lui-mode@setup ()
1192 (setq-local fringes-outside-margins t
1193 lui-track-bar-behavior 'before-switch-to-buffer
1194 right-margin-width 5
1195 scroll-margin 0
1196 word-wrap t
1197 wrap-prefix (repeat-string
1198 acdw-irc/left-margin " "))
1199 ;; (enable-lui-track-bar)
1200 )))
1201
1202(setup (:straight (consult 894(setup (:straight (consult
1203 :host github 895 :host github
1204 :repo "minad/consult")) 896 :repo "minad/consult"))
@@ -1321,6 +1013,307 @@ already been connected to."
1321 (run-at-time 0 nil #'vertico-exit) 1013 (run-at-time 0 nil #'vertico-exit)
1322 (funcall #'vertico-exit))))) 1014 (funcall #'vertico-exit)))))
1323 1015
1016(setup (:straight (electric-cursor
1017 :host github
1018 :repo "duckwork/electric-cursor"))
1019 (electric-cursor-mode +1))
1020
1021(setup (:straight (elpher :host nil
1022 :repo "git://thelambdalab.xyz/elpher.git"))
1023 (:option elpher-ipv4-always t
1024 elpher-certificate-directory (acdw/dir "elpher/")
1025 elpher-gemini-max-fill-width fill-column)
1026
1027 (:bind "n" elpher-next-link
1028 "p" elpher-prev-link
1029 "o" elpher-follow-current-link
1030 "G" elpher-go-current)
1031
1032 (:hook acdw/reading-mode)
1033
1034 (autoload 'elpher-bookmarks "elpher" nil t)
1035 (autoload 'elpher-go "elpher" nil t)
1036
1037 ;; Make `eww' gemini/gopher aware. From Emacswiki.
1038 (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher)
1039 (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
1040 (require 'elpher)
1041 (elpher-go url))
1042 (t (apply fn url args)))))
1043
1044(setup (:straight (gemini-mode
1045 :host nil
1046 :repo "https://git.carcosa.net/jmcbray/gemini.el.git"))
1047 (add-to-list 'auto-mode-alist '("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode))
1048 (:hook turn-off-auto-fill))
1049
1050(setup (:straight (gemini-write
1051 :host nil
1052 :repo "https://alexschroeder.ch/cgit/gemini-write"
1053 :branch "main"))
1054 (require 'gemini-write))
1055
1056(setup (:straight (mastodon
1057 :host github
1058 :repo "mooseyboots/mastodon.el"))
1059 (:straight request)
1060 (:option mastodon-instance-url "https://writing.exchange"
1061 mastodon-auth-source-file (car auth-sources)
1062 mastodon-client--token-file (acdw/dir "mastodon.plstore"))
1063 (:hook hl-line-mode
1064 acdw/reading-mode))
1065
1066(setup (:straight (modus-themes
1067 :host gitlab
1068 :repo "protesilaos/modus-themes"))
1069 (:option modus-themes-slanted-constructs t
1070 modus-themes-bold-constructs t
1071 modus-themes-region 'bg-only
1072 modus-themes-org-blocks 'grayscale
1073 modus-themes-headings '((1 . section)
1074 (t . no-color))
1075 modus-themes-mode-line nil)
1076
1077 (acdw/sunrise-sunset #'modus-themes-load-operandi
1078 #'modus-themes-load-vivendi))
1079
1080(setup (:straight (orderless
1081 :host github
1082 :repo "oantolin/orderless"))
1083 (require 'orderless)
1084
1085 (:option (append completion-styles) 'orderless
1086 orderless-component-separator #'orderless-escapable-split-on-space
1087 orderless-style-dispatchers '(acdw/orderless-dispatch))
1088
1089 (defun fix-dollar (args)
1090 (if (string-suffix-p "$" (car args))
1091 (list (concat (substring (car args) 0 -1) "[\x100000-\x10FFFD]*$"))
1092 args))
1093 (advice-add #'orderless-regexp :filter-args #'fix-dollar)
1094
1095 (defun acdw/orderless-dispatch (pattern _index _total)
1096 "My custom dispatcher for `orderless'."
1097 (cond
1098 ;; Ensure that $ works with Consult commands, which add disambiguation
1099 ;; suffixes -- see `fix-dollar'
1100 ((string-suffix-p "$" pattern)
1101 `(orderless-regexp . ,(concat (substring pattern 0 -1)
1102 "[\x100000-\x10FFFD]*$")))
1103 ;; File extensions
1104 ((string-match-p "\\`\\.." pattern)
1105 `(orderless-regexp . ,(concat "\\." (substring pattern 1)
1106 "[\x100000-\x10FFFD]*$")))
1107 ;; Ignore single !
1108 ((string= "!" pattern)
1109 `(orderless-literal . ""))
1110 ;; Character folding
1111 ((string-prefix-p "%" pattern)
1112 `(char-fold-to-regexp . ,(substring pattern 1)))
1113 ((string-suffix-p "%" pattern)
1114 `(char-fold-to-regexp . ,(substring pattern 0 -1)))
1115 ;; Without literal
1116 ((string-prefix-p "!" pattern)
1117 `(orderless-without-literal . ,(substring pattern 1)))
1118 ((string-suffix-p "!" pattern)
1119 `(orderless-without-literal . ,(substring pattern 0 -1)))
1120 ;; Initialism matching
1121 ((string-prefix-p "`" pattern)
1122 `(orderless-initialism . ,(substring pattern 1)))
1123 ((string-suffix-p "`" pattern)
1124 `(orderless-initialism . ,(substring pattern 0 -1)))
1125 ;; Literal matching
1126 ((string-prefix-p "=" pattern)
1127 `(orderless-literal . ,(substring pattern 1)))
1128 ((string-suffix-p "=" pattern)
1129 `(orderless-literal . ,(substring pattern 0 -1)))
1130 ;; Flex matching
1131 ((string-prefix-p "~" pattern)
1132 `(orderless-flex . ,(substring pattern 1)))
1133 ((string-suffix-p "~" pattern)
1134 `(orderless-flex . ,(substring pattern 0 -1))))))
1135
1136(setup (:straight (topsy
1137 :host github
1138 :repo "alphapapa/topsy.el"))
1139 (:hook-into prog-mode))
1140
1141(setup (:straight (unfocused
1142 :host github
1143 :repo "duckwork/unfocused"))
1144 (unfocused-mode +1))
1145
1146(setup (:straight (vertico
1147 :host github
1148 :repo "minad/vertico"
1149 :files ("*" "extensions/*"
1150 (:exclude ".git"))))
1151
1152 (:option resize-mini-windows 'grow-only
1153 vertico-count-format nil
1154 vertico-cycle t)
1155
1156 (defun up-directory (arg)
1157 "Move up a directory (delete backwards to /)."
1158 (interactive "p")
1159 (if (string-match-p "/." (minibuffer-contents))
1160 (zap-up-to-char (- arg) ?/)
1161 (backward-kill-word arg)))
1162
1163 (with-eval-after-load 'vertico
1164 (define-key vertico-map (kbd "<C-backspace>") #'up-directory))
1165
1166 (if (boundp 'comp-deferred-compilation-deny-list)
1167 (add-to-list 'comp-deferred-compilation-deny-list "vertico"))
1168
1169 (vertico-mode +1)
1170
1171 ;; Extensions!
1172 (:also-load vertico-mouse)
1173 (vertico-mouse-mode +1)
1174
1175 ;; Prefix the current candidate with "> ". From Vertico wiki.
1176 (defun vertico-format@add-arrow (orig cand prefix suffix index _start)
1177 (setq cand (funcall orig cand prefix suffix index _start))
1178 (concat
1179 (if (= vertico--index index)
1180 (propertize "> " 'face 'vertico-current)
1181 " ")
1182 cand))
1183 (advice-add #'vertico--format-candidate :around #'vertico-format@add-arrow))
1184
1185(setup (:straight alert)
1186 (:option alert-default-style (acdw/system
1187 (:home 'libnotify)
1188 (_ 'message))))
1189
1190(setup (:straight async)
1191 (autoload 'dired-async-mode "dired-async.el" nil t)
1192 (dired-async-mode +1)
1193 (add-hook 'dired-mode
1194 (defun dired@disable-dired-async-mode-line ()
1195 (autoload 'dired-async--modeline-mode "dired-async.el" nil t)
1196 (dired-async--modeline-mode -1))))
1197
1198(setup (:straight avy)
1199 (:global "C-'" avy-goto-char-timer
1200 "M-g f" avy-goto-line
1201 "M-g w" avy-goto-word-1
1202 "C-c C-j" avy-resume)
1203
1204 (with-eval-after-load "isearch"
1205 (define-key isearch-mode-map (kbd "C-'") #'avy-isearch)))
1206
1207(setup (:straight circe)
1208 (require 'circe)
1209 (require 'acdw-irc)
1210
1211 (setq acdw-irc/post-my-nick "-> ")
1212
1213 (setq circe-default-nick "acdw"
1214 circe-default-part-message "See You, Space Cowpokes . . ."
1215 circe-highlight-nick-type 'all
1216 circe-network-options
1217 `(("Libera Chat"
1218 :channels ("#emacs" "#systemcrafters" "##webpals")
1219 :sasl-username "acdw"
1220 :sasl-password ,(acdw/fetch-password :host "libera.chat"))
1221 ("Tilde Chat"
1222 :channels ("#meta" "#bread" "#dadjokes" "#team")
1223 :host "irc.tilde.chat" :port 6697 :use-tls t
1224 :sasl-username "acdw"
1225 :sasl-password ,(acdw/fetch-password :host "tilde.chat"))
1226 ("Casa"
1227 :channels ("#basement")
1228 :host "m455.casa" :port 6697 :use-tls t
1229 :sasl-username "acdw"
1230 :sasl-password ,(acdw/fetch-password :host "m455.casa")))
1231 circe-reduce-lurker-spam t
1232 circe-server-auto-join-default-type :after-auth)
1233
1234 (defun irc ()
1235 "Connect to IRC."
1236 (interactive)
1237 (dolist (network (mapcar #'car circe-network-options))
1238 (circe-maybe-connect network)))
1239
1240 (defun circe-network-connected-p (network)
1241 "Return non-nil if there's any Circe server-buffer whose
1242`circe-server-netwok' is NETWORK."
1243 (catch 'return
1244 (dolist (buffer (circe-server-buffers))
1245 (with-current-buffer buffer
1246 (if (string= network circe-server-network)
1247 (throw 'return t))))))
1248
1249 (defun circe-maybe-connect (network)
1250 "Connect to NETWORK, but ask user for confirmation if it's
1251already been connected to."
1252 (interactive "sNetwork: ")
1253 (if (or (not (circe-network-connected-p network))
1254 (y-or-n-p (format "Already connected to %s, reconnect?" network)))
1255 (circe network)))
1256
1257 (add-hook 'circe-chat-mode-hook
1258 (defun circe-chat@setup ()
1259 (lui-set-prompt
1260 (concat (propertize (acdw-irc/margin-format (buffer-name)
1261 ""
1262 ">")
1263 'face 'circe-prompt-face
1264 'read-only t 'intangible t
1265 'cursor-intangible t)
1266 " "))
1267 (enable-circe-color-nicks)
1268 (enable-circe-display-images)
1269 (enable-circe-new-day-notifier)))
1270
1271 (add-hook 'modus-themes-after-load-theme-hook
1272 #'circe-nick-color-reset)
1273
1274 (let ((len (number-to-string (- acdw-irc/left-margin 1
1275 (+ (length acdw-irc/pre-nick)
1276 (length acdw-irc/post-nick)))))
1277 (my-len (number-to-string (- acdw-irc/left-margin 1
1278 (+ (length acdw-irc/pre-my-nick)
1279 (length acdw-irc/post-my-nick))))))
1280 (setq circe-format-say (concat acdw-irc/pre-nick
1281 "{nick:" len "." len "s} "
1282 acdw-irc/post-nick
1283 "{body}")
1284 circe-format-self-say (concat acdw-irc/pre-my-nick
1285 "{nick:" my-len "." my-len "s} "
1286 acdw-irc/post-my-nick
1287 "{body}")
1288 circe-format-action (concat "*"
1289 (repeat-string
1290 (- acdw-irc/left-margin 3)
1291 " ")
1292 "* {nick} {body}")
1293 circe-format-self-action (concat "-*"
1294 (repeat-string
1295 (- acdw-irc/left-margin 4)
1296 " ")
1297 "* {nick} {body}")
1298 lui-fill-type (concat
1299 (repeat-string (- acdw-irc/left-margin 2)
1300 " ")
1301 " ")))
1302
1303 (setq lui-time-stamp-position 'right-margin
1304 lui-time-stamp-format "%H:%M")
1305 (add-hook 'lui-mode-hook
1306 (defun lui-mode@setup ()
1307 (setq-local fringes-outside-margins t
1308 lui-track-bar-behavior 'before-switch-to-buffer
1309 right-margin-width 5
1310 scroll-margin 0
1311 word-wrap t
1312 wrap-prefix (repeat-string
1313 acdw-irc/left-margin " "))
1314 ;; (enable-lui-track-bar)
1315 )))
1316
1324(setup (:straight crux) 1317(setup (:straight crux)
1325 1318
1326 (:global "C-x o" acdw/other-window-or-switch-buffer 1319 (:global "C-x o" acdw/other-window-or-switch-buffer
@@ -1358,11 +1351,6 @@ already been connected to."
1358 (defun edit-server@set-a-variable (&rest _) 1351 (defun edit-server@set-a-variable (&rest _)
1359 (setq-local edit-server-frame-p t))))) 1352 (setq-local edit-server-frame-p t)))))
1360 1353
1361(setup (:straight (electric-cursor
1362 :host github
1363 :repo "duckwork/electric-cursor"))
1364 (electric-cursor-mode +1))
1365
1366(setup (:straight elfeed 1354(setup (:straight elfeed
1367 elfeed-protocol) 1355 elfeed-protocol)
1368 (:option elfeed-use-curl t 1356 (:option elfeed-use-curl t
@@ -1380,35 +1368,9 @@ already been connected to."
1380 ;; see https://irreal.org/blog/?p=8885 1368 ;; see https://irreal.org/blog/?p=8885
1381 ) 1369 )
1382 1370
1383(setup (:straight (elpher :host nil 1371(setup (:straight elisp-slime-nav)
1384 :repo "git://thelambdalab.xyz/elpher.git")) 1372 (:hook-into emacs-lisp-mode
1385 (:option elpher-ipv4-always t 1373 ielm-mode))
1386 elpher-certificate-directory (acdw/dir "elpher/")
1387 elpher-gemini-max-fill-width fill-column)
1388
1389 (:bind "n" elpher-next-link
1390 "p" elpher-prev-link
1391 "o" elpher-follow-current-link
1392 "G" elpher-go-current)
1393
1394 (:hook acdw/reading-mode)
1395
1396 (autoload 'elpher-bookmarks "elpher" nil t)
1397 (autoload 'elpher-go "elpher" nil t)
1398
1399 ;; Make `eww' gemini/gopher aware. From Emacswiki.
1400 (define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher)
1401 (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
1402 (require 'elpher)
1403 (elpher-go url))
1404 (t (apply fn url args))))
1405
1406 (:when-loaded
1407 (setup (:straight (gemini-write
1408 :host nil
1409 :repo "https://alexschroeder.ch/cgit/gemini-write"
1410 :branch "main"))
1411 (require 'gemini-write))))
1412 1374
1413(setup (:straight embark) 1375(setup (:straight embark)
1414 (:global "C-." embark-act) 1376 (:global "C-." embark-act)
@@ -1428,9 +1390,9 @@ already been connected to."
1428 embark-become-indicator embark-action-indicator) 1390 embark-become-indicator embark-action-indicator)
1429 1391
1430 (with-eval-after-loads (embark consult) 1392 (with-eval-after-loads (embark consult)
1431 (setup (:straight embark-consult) 1393 (:straight embark-consult)
1432 (add-hook 'embark-collect-mode-hook 1394 (add-hook 'embark-collect-mode-hook
1433 #'consult-preview-at-point-mode)))) 1395 #'consult-preview-at-point-mode)))
1434 1396
1435(setup (:straight epithet) 1397(setup (:straight epithet)
1436 (add-hook 'Info-selection-hook #'epithet-rename-buffer) 1398 (add-hook 'Info-selection-hook #'epithet-rename-buffer)
@@ -1438,44 +1400,8 @@ already been connected to."
1438 (add-hook 'help-mode-hook #'epithet-rename-buffer) 1400 (add-hook 'help-mode-hook #'epithet-rename-buffer)
1439 (add-hook 'occur-mode-hook #'epithet-rename-buffer)) 1401 (add-hook 'occur-mode-hook #'epithet-rename-buffer))
1440 1402
1441(setup (:straight-if eradio 1403(setup (:straight eros)
1442 (executable-find "mpv")) 1404 (:hook-into emacs-lisp-mode))
1443 (:option
1444 eradio-player '("mpv" "--no-video" "--no-terminal")
1445 eradio-channels `(("KLSU" .
1446 "http://130.39.238.143:8010/stream.mp3")
1447 ("Soma FM Synphaera" .
1448 "https://somafm.com/synphaera256.pls")
1449 ("SomaFM BAGel Radio" .
1450 "https://somafm.com/bagel.pls")
1451 ("SomaFM Boot Liquor" .
1452 "https://somafm.com/bootliquor320.pls")
1453 ("SomaFM Deep Space One" .
1454 "https://somafm.com/deepspaceone.pls")
1455 ("SomaFM Fluid" .
1456 "https://somafm.com/fluid.pls")
1457 ("SomaFM Underground 80s" .
1458 "https://somafm.com/u80s256.pls")
1459 ("WBRH: Jazz & More" .
1460 "http://wbrh.streamguys1.com/wbrh-mp3")
1461 ("KBRH Blues & Rhythm Hits" .
1462 "http://wbrh.streamguys1.com/kbrh-mp3")
1463 ("WRKF HD-2" .
1464 ,(concat "https://playerservices.streamtheworld.com/"
1465 "api/livestream-redirect/WRKFHD2.mp3"))
1466 ("WRKF: NPR for the Capital Region" .
1467 ,(concat "https://playerservices.streamtheworld.com/"
1468 "api/livestream-redirect/WRKFFM.mp3"))
1469 ("BadRadio: 24/7 PHONK" .
1470 "https://s2.radio.co/s2b2b68744/listen")
1471 ("tilderadio" .
1472 "https://radio.tildeverse.org/radio/8000/radio.ogg")
1473 ("vantaradio" .
1474 "https://vantaa.black/radio")))
1475 (:global "C-c r r" eradio-play ; mnemonic: radio
1476 "C-c r s" eradio-stop ; mnemonic: stop
1477 "C-c r p" eradio-toggle ; mnemonic: play/pause
1478 ))
1479 1405
1480(setup (:straight expand-region) 1406(setup (:straight expand-region)
1481 1407
@@ -1504,73 +1430,28 @@ successive invocations."
1504 (:global "C-=" er/expand-region 1430 (:global "C-=" er/expand-region
1505 "C-SPC" acdw/set-mark-or-expand-region)) 1431 "C-SPC" acdw/set-mark-or-expand-region))
1506 1432
1507(setup (:straight-if fennel-mode 1433(setup (:straight flyspell-correct)
1508 (executable-find "fennel")) 1434 (add-hook 'flyspell-mode-hook
1509 (autoload 'fennel-repl "fennel-mode" nil t) 1435 (defun flyspell-mode@flyspell-correct ()
1510 (add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode))) 1436 (dolist (keybind '(("C-;" . flyspell-correct-wrapper)
1437 ("C-," . nil)
1438 ("C-." . nil)
1439 ("C-M-i" . nil)))
1440 (define-key flyspell-mode-map
1441 (kbd (car keybind)) (cdr keybind))))))
1511 1442
1512(setup (:straight gcmh) 1443(setup (:straight gcmh)
1513 (:option gcmh-idle-delay 'auto) 1444 (:option gcmh-idle-delay 'auto)
1514 (gcmh-mode +1)) 1445 (gcmh-mode +1))
1515 1446
1516(setup (:straight-if geiser 1447;; TODO: figure out a popper.el / shackle.el ... thing to fix this
1517 (progn
1518 (defvar acdw/schemes
1519 (let (schemes) ; these binaries should be checked...
1520 (dolist (scheme '(("scheme" . geiser-chez) ; chez
1521 ("petite" . geiser-chez) ; petite
1522 ("csi" . geiser-chez) ; chicken
1523 ("gsi" . geiser-gambit) ; gambit
1524 ("gosh" . geiser-gauche) ; gauche
1525 ("guile" . geiser-guile)
1526 ("kawa" . geiser-kawa)
1527 ("mit-scheme" . geiser-mit)
1528 ("racket" . geiser-racket)
1529 ("stklos" . geiser-stklos)))
1530 (when-let (binary (executable-find (car scheme)))
1531 (push binary schemes)
1532 ;; and install the proper helper package
1533 (straight-use-package (cdr scheme))))
1534 (nreverse schemes)))
1535 acdw/schemes)))
1536
1537(setup (:straight (gemini-mode
1538 :host nil
1539 :repo "https://git.carcosa.net/jmcbray/gemini.el.git"))
1540 (add-to-list 'auto-mode-alist '("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode))
1541 (:hook turn-off-auto-fill))
1542
1543(setup gforth
1544 (when (locate-library "gforth")
1545 (autoload 'forth-mode "gforth")
1546 (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode))
1547 (autoload 'forth-block-mode "gforth")
1548 (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))))
1549
1550(setup (:straight helpful) 1448(setup (:straight helpful)
1551 (:option helpful-max-buffers 5 1449 (:option helpful-max-buffers 5)
1552 ;; helpful-switch-buffer-function #'pop-to-buffer
1553 ;; helpful-switch-buffer-function
1554 ;; (lambda (buf)
1555 ;; (pop-to-buffer buf
1556 ;; '((display-buffer-reuse-mode-window
1557 ;; display-buffer-pop-up-window)
1558 ;; (mode . helpful-mode))
1559 ;; :norecord))
1560 )
1561 (:global "<help> f" helpful-callable 1450 (:global "<help> f" helpful-callable
1562 "<help> v" helpful-variable 1451 "<help> v" helpful-variable
1563 "<help> k" helpful-key 1452 "<help> k" helpful-key
1564 "<help> o" helpful-symbol 1453 "<help> o" helpful-symbol
1565 "C-c C-d" helpful-at-point) 1454 "C-c C-d" helpful-at-point))
1566 ;; (with-eval-after-load 'helpful
1567 ;; (define-key helpful-mode-map "q"
1568 ;; (defun helpful-mode|quit ()
1569 ;; (interactive)
1570 ;; (bury-buffer)
1571 ;; (unless (window-parameter (frame-selected-window) 'no-other-window)
1572 ;; (delete-window)))))
1573 )
1574 1455
1575(setup (:straight iscroll) 1456(setup (:straight iscroll)
1576 (:hook-into text-mode)) 1457 (:hook-into text-mode))
@@ -1578,9 +1459,6 @@ successive invocations."
1578(setup (:straight lacarte) 1459(setup (:straight lacarte)
1579 (:global "<f10>" lacarte-execute-menu-command)) 1460 (:global "<f10>" lacarte-execute-menu-command))
1580 1461
1581(setup (:straight-if ledger-mode
1582 (executable-find "ledger")))
1583
1584(setup (:straight link-hint) 1462(setup (:straight link-hint)
1585 ;; Browse web URLs with a browser with a prefix argument. 1463 ;; Browse web URLs with a browser with a prefix argument.
1586 (dolist (type '(gnus-w3m-image-url 1464 (dolist (type '(gnus-w3m-image-url
@@ -1612,6 +1490,9 @@ browser defined in `browse-url-secondary-browser-function'."
1612(setup (:straight lua-mode) 1490(setup (:straight lua-mode)
1613 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))) 1491 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode)))
1614 1492
1493(setup (:straight macrostep)
1494 (define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand))
1495
1615(setup (:straight magit) 1496(setup (:straight magit)
1616 (:global "C-c g" magit-status) 1497 (:global "C-c g" magit-status)
1617 1498
@@ -1628,30 +1509,6 @@ browser defined in `browse-url-secondary-browser-function'."
1628 marginalia-annotators-light)) 1509 marginalia-annotators-light))
1629 (marginalia-mode +1)) 1510 (marginalia-mode +1))
1630 1511
1631(setup (:straight (mastodon
1632 :host github
1633 :repo "mooseyboots/mastodon.el"))
1634 (:straight request)
1635 (:option mastodon-instance-url "https://writing.exchange"
1636 mastodon-auth-source-file (car auth-sources)
1637 mastodon-client--token-file (acdw/dir "mastodon.plstore"))
1638 (:hook hl-line-mode
1639 olivetti-mode))
1640
1641(setup (:straight (modus-themes
1642 :host gitlab
1643 :repo "protesilaos/modus-themes"))
1644 (:option modus-themes-slanted-constructs t
1645 modus-themes-bold-constructs t
1646 modus-themes-region 'bg-only
1647 modus-themes-org-blocks 'grayscale
1648 modus-themes-headings '((1 . section)
1649 (t . no-color))
1650 modus-themes-mode-line nil)
1651
1652 (acdw/sunrise-sunset #'modus-themes-load-operandi
1653 #'modus-themes-load-vivendi))
1654
1655(setup (:straight markdown-mode)) 1512(setup (:straight markdown-mode))
1656 1513
1657(setup (:straight mwim) 1514(setup (:straight mwim)
@@ -1662,10 +1519,6 @@ browser defined in `browse-url-secondary-browser-function'."
1662 (:option nov-text-width fill-column) 1519 (:option nov-text-width fill-column)
1663 (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) 1520 (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)))
1664 1521
1665(setup (:straight package-lint))
1666
1667(setup (:straight package-lint-flymake))
1668
1669(setup (:straight olivetti) 1522(setup (:straight olivetti)
1670 (:option olivetti-body-width (+ fill-column 4) 1523 (:option olivetti-body-width (+ fill-column 4)
1671 olivetti-minimum-body-width fill-column) 1524 olivetti-minimum-body-width fill-column)
@@ -1677,62 +1530,6 @@ browser defined in `browse-url-secondary-browser-function'."
1677 indicate-buffer-boundaries nil) 1530 indicate-buffer-boundaries nil)
1678 (acdw/setup-fringes))))) 1531 (acdw/setup-fringes)))))
1679 1532
1680(setup (:straight (orderless
1681 :host github
1682 :repo "oantolin/orderless"))
1683 (require 'orderless)
1684
1685 (:option (append completion-styles) 'orderless
1686 orderless-component-separator #'orderless-escapable-split-on-space
1687 orderless-style-dispatchers '(acdw/orderless-dispatch))
1688
1689 (defun fix-dollar (args)
1690 (if (string-suffix-p "$" (car args))
1691 (list (concat (substring (car args) 0 -1) "[\x100000-\x10FFFD]*$"))
1692 args))
1693 (advice-add #'orderless-regexp :filter-args #'fix-dollar)
1694
1695 (defun acdw/orderless-dispatch (pattern _index _total)
1696 "My custom dispatcher for `orderless'."
1697 (cond
1698 ;; Ensure that $ works with Consult commands, which add disambiguation
1699 ;; suffixes -- see `fix-dollar'
1700 ((string-suffix-p "$" pattern)
1701 `(orderless-regexp . ,(concat (substring pattern 0 -1)
1702 "[\x100000-\x10FFFD]*$")))
1703 ;; File extensions
1704 ((string-match-p "\\`\\.." pattern)
1705 `(orderless-regexp . ,(concat "\\." (substring pattern 1)
1706 "[\x100000-\x10FFFD]*$")))
1707 ;; Ignore single !
1708 ((string= "!" pattern)
1709 `(orderless-literal . ""))
1710 ;; Character folding
1711 ((string-prefix-p "%" pattern)
1712 `(char-fold-to-regexp . ,(substring pattern 1)))
1713 ((string-suffix-p "%" pattern)
1714 `(char-fold-to-regexp . ,(substring pattern 0 -1)))
1715 ;; Without literal
1716 ((string-prefix-p "!" pattern)
1717 `(orderless-without-literal . ,(substring pattern 1)))
1718 ((string-suffix-p "!" pattern)
1719 `(orderless-without-literal . ,(substring pattern 0 -1)))
1720 ;; Initialism matching
1721 ((string-prefix-p "`" pattern)
1722 `(orderless-initialism . ,(substring pattern 1)))
1723 ((string-suffix-p "`" pattern)
1724 `(orderless-initialism . ,(substring pattern 0 -1)))
1725 ;; Literal matching
1726 ((string-prefix-p "=" pattern)
1727 `(orderless-literal . ,(substring pattern 1)))
1728 ((string-suffix-p "=" pattern)
1729 `(orderless-literal . ,(substring pattern 0 -1)))
1730 ;; Flex matching
1731 ((string-prefix-p "~" pattern)
1732 `(orderless-flex . ,(substring pattern 1)))
1733 ((string-suffix-p "~" pattern)
1734 `(orderless-flex . ,(substring pattern 0 -1))))))
1735
1736(setup (:straight org 1533(setup (:straight org
1737 org-contrib) 1534 org-contrib)
1738 (require 'acdw-org) ; so I don't clutter up init.el 1535 (require 'acdw-org) ; so I don't clutter up init.el
@@ -1803,10 +1600,14 @@ browser defined in `browse-url-secondary-browser-function'."
1803 (lambda (start end) "Count words stupidly with a limit." 1600 (lambda (start end) "Count words stupidly with a limit."
1804 (acdw-org/count-words-stupidly start 1601 (acdw-org/count-words-stupidly start
1805 end 1602 end
1806 999))))) 1603 999))))))
1807 1604
1808 (setup (:straight org-appear) 1605(setup (:straight org-appear)
1809 (:hook-into org-mode))) 1606 (:hook-into org-mode))
1607
1608(setup (:straight package-lint))
1609
1610(setup (:straight package-lint-flymake))
1810 1611
1811(setup (:straight page-break-lines) 1612(setup (:straight page-break-lines)
1812 (global-page-break-lines-mode +1)) 1613 (global-page-break-lines-mode +1))
@@ -1830,7 +1631,6 @@ browser defined in `browse-url-secondary-browser-function'."
1830 1631
1831 (require 'eldoc) 1632 (require 'eldoc)
1832 (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)) 1633 (eldoc-add-command 'paredit-backward-delete 'paredit-close-round))
1833
1834(setup (:straight paren-face) 1634(setup (:straight paren-face)
1835 (dolist (mode lispy-modes) 1635 (dolist (mode lispy-modes)
1836 (add-hook (intern (concat (symbol-name mode) "-hook")) #'paren-face-mode))) 1636 (add-hook (intern (concat (symbol-name mode) "-hook")) #'paren-face-mode)))
@@ -1838,7 +1638,9 @@ browser defined in `browse-url-secondary-browser-function'."
1838(setup (:straight persistent-scratch) 1638(setup (:straight persistent-scratch)
1839 (:option persistent-scratch-backup-directory (acdw/dir "scratch" t) 1639 (:option persistent-scratch-backup-directory (acdw/dir "scratch" t)
1840 persistent-scratch-keep-n-newest-backups 12) 1640 persistent-scratch-keep-n-newest-backups 12)
1641
1841 (persistent-scratch-setup-default) 1642 (persistent-scratch-setup-default)
1643
1842 (mapc (lambda (buf) 1644 (mapc (lambda (buf)
1843 (with-current-buffer buf 1645 (with-current-buffer buf
1844 (when (funcall persistent-scratch-scratch-buffer-p-function) 1646 (when (funcall persistent-scratch-scratch-buffer-p-function)
@@ -1893,45 +1695,15 @@ browser defined in `browse-url-secondary-browser-function'."
1893 1695
1894 (simple-modeline-mode +1)) 1696 (simple-modeline-mode +1))
1895 1697
1896(setup (:straight-if sly
1897 (progn (defvar acdw/lisp-bin
1898 (or (executable-find "sbcl")
1899 (executable-find "clisp")
1900 ""))
1901 (executable-find acdw/lisp-bin)))
1902
1903 (:option inferior-lisp-program acdw/lisp-bin
1904 sly-kill-without-query-p t)
1905
1906 (:also-load sly-autoloads)
1907 (setup (:straight clhs))
1908
1909 (:with-feature sly-mrepl
1910 (dolist (key '("RET" "<return>"))
1911 (:bind key sly-mrepl-return-at-end))
1912 (:bind "C-c C-c" sly-mrepl-return))
1913
1914 (defun sly-mrepl-return-at-end ()
1915 (interactive)
1916 (if (<= (point-max) (point))
1917 (sly-mrepl-return)
1918 (if (bound-and-true-p paredit-mode)
1919 (paredit-newline)
1920 (electric-newline-and-maybe-indent)))))
1921
1922(setup (:straight ssh-config-mode) 1698(setup (:straight ssh-config-mode)
1923 (dolist (spec '(("/\\.ssh/config\\'" . ssh-config-mode) 1699 (dolist (spec '(("/\\.ssh/config\\'" . ssh-config-mode)
1924 ("/sshd?_config\\'" . ssh-config-mode) 1700 ("/sshd?_config\\'" . ssh-config-mode)
1925 ("/knownhosts\\'" . ssh-known-hosts-mode) 1701 ("/knownhosts\\'" . ssh-known-hosts-mode)
1926 ("/authorized_keys2?\\'" . ssh-authorized-keys-mode))) 1702 ("/authorized_keys2?\\'" . ssh-authorized-keys-mode)))
1927 (add-to-list 'auto-mode-alist spec)) 1703 (add-to-list 'auto-mode-alist spec))
1704
1928 (add-hook 'ssh-config-mode-hook #'turn-on-font-lock)) 1705 (add-hook 'ssh-config-mode-hook #'turn-on-font-lock))
1929 1706
1930(setup (:straight (topsy
1931 :host github
1932 :repo "alphapapa/topsy.el"))
1933 (:hook-into prog-mode))
1934
1935(setup (:straight typo) 1707(setup (:straight typo)
1936 1708
1937 ;; Enable C-c 8 map in all buffers 1709 ;; Enable C-c 8 map in all buffers
@@ -1966,8 +1738,7 @@ If used with a numeric prefix argument N, N backticks will be inserted."
1966 ("`" "‘")) 1738 ("`" "‘"))
1967 1739
1968 (:bind "'" typo-cycle-apostrophe 1740 (:bind "'" typo-cycle-apostrophe
1969 "`" typo-cycle-backtick) 1741 "`" typo-cycle-backtick)))
1970 ))
1971 1742
1972(setup (:straight undo-fu) 1743(setup (:straight undo-fu)
1973 (:global "C-/" undo-fu-only-undo 1744 (:global "C-/" undo-fu-only-undo
@@ -1983,50 +1754,6 @@ If used with a numeric prefix argument N, N backticks will be inserted."
1983 1754
1984(setup (:straight unfill)) 1755(setup (:straight unfill))
1985 1756
1986(setup (:straight (unfocused
1987 :host github
1988 :repo "duckwork/unfocused"))
1989 (unfocused-mode +1))
1990
1991(setup (:straight (vertico
1992 :host github
1993 :repo "minad/vertico"
1994 :files ("*" "extensions/*"
1995 (:exclude ".git"))))
1996
1997 (:option resize-mini-windows 'grow-only
1998 vertico-count-format nil
1999 vertico-cycle t)
2000
2001 (defun up-directory (arg)
2002 "Move up a directory (delete backwards to /)."
2003 (interactive "p")
2004 (if (string-match-p "/." (minibuffer-contents))
2005 (zap-up-to-char (- arg) ?/)
2006 (backward-kill-word arg)))
2007
2008 (with-eval-after-load 'vertico
2009 (define-key vertico-map (kbd "<C-backspace>") #'up-directory))
2010
2011 (if (boundp 'comp-deferred-compilation-deny-list)
2012 (add-to-list 'comp-deferred-compilation-deny-list "vertico"))
2013
2014 (vertico-mode +1)
2015
2016 ;; Extensions!
2017 (:also-load vertico-mouse)
2018 (vertico-mouse-mode +1)
2019
2020 ;; Prefix the current candidate with "> ". From Vertico wiki.
2021 (defun vertico-format@add-arrow (orig cand prefix suffix index _start)
2022 (setq cand (funcall orig cand prefix suffix index _start))
2023 (concat
2024 (if (= vertico--index index)
2025 (propertize "> " 'face 'vertico-current)
2026 " ")
2027 cand))
2028 (advice-add #'vertico--format-candidate :around #'vertico-format@add-arrow))
2029
2030(setup (:straight wc-mode) ; TODO: move some of this stuff around 1757(setup (:straight wc-mode) ; TODO: move some of this stuff around
2031 1758
2032 (:option wc-modeline-format "[%tww]" 1759 (:option wc-modeline-format "[%tww]"
@@ -2043,6 +1770,7 @@ If used with a numeric prefix argument N, N backticks will be inserted."
2043 (:option css-level-offset 2 1770 (:option css-level-offset 2
2044 js-indent-level 2 1771 js-indent-level 2
2045 sgml-indent-offset 2) 1772 sgml-indent-offset 2)
1773
2046 (dolist (ext '("\\.\\(p\\|dj\\)?html\\'" 1774 (dolist (ext '("\\.\\(p\\|dj\\)?html\\'"
2047 "\\.html?\\'" 1775 "\\.html?\\'"
2048 "\\.\\(tpl\\.\\)?php\\'" 1776 "\\.\\(tpl\\.\\)?php\\'"
@@ -2102,35 +1830,141 @@ call `zzz-to-char'."
2102 1830
2103 (:global "M-z" acdw/zzz-up-to-char)) 1831 (:global "M-z" acdw/zzz-up-to-char))
2104 1832
2105 1833(setup (:straight-if (pdf-tools
2106;;; System-dependent 1834 :host github
2107 1835 :repo "vedang/pdf-tools")
2108;;;; Home 1836 (acdw/system :home))
2109(when (acdw/system :home) 1837 (add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode))
1838 (pdf-loader-install))
2110 1839
2111 (setup (:straight exec-path-from-shell) 1840(setup (:straight-if affe
2112 (when (daemonp) 1841 (and (or (executable-find "fd")
2113 (exec-path-from-shell-initialize))) 1842 (executable-find "find"))
1843 (executable-find "rg")))
1844 ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find'
1845 (defun affe-orderless-regexp-compiler (input _type)
1846 (setq input (orderless-pattern-compiler input))
1847 (cons input (lambda (str) (orderless--highlight input str))))
2114 1848
2115 (setup (:straight pkgbuild-mode)) 1849 (:option affe-regexp-compiler #'affe-orderless-regexp-compiler))
1850
1851(setup (:straight-if ahk-mode
1852 (acdw/system :work)))
1853
1854;; TODO: look into emms or something related for this
1855(setup (:straight-if eradio
1856 (executable-find "mpv"))
1857 (:option
1858 eradio-player '("mpv" "--no-video" "--no-terminal")
1859 eradio-channels `(("KLSU" .
1860 "http://130.39.238.143:8010/stream.mp3")
1861 ("Soma FM Synphaera" .
1862 "https://somafm.com/synphaera256.pls")
1863 ("SomaFM BAGel Radio" .
1864 "https://somafm.com/bagel.pls")
1865 ("SomaFM Boot Liquor" .
1866 "https://somafm.com/bootliquor320.pls")
1867 ("SomaFM Deep Space One" .
1868 "https://somafm.com/deepspaceone.pls")
1869 ("SomaFM Fluid" .
1870 "https://somafm.com/fluid.pls")
1871 ("SomaFM Underground 80s" .
1872 "https://somafm.com/u80s256.pls")
1873 ("WBRH: Jazz & More" .
1874 "http://wbrh.streamguys1.com/wbrh-mp3")
1875 ("KBRH Blues & Rhythm Hits" .
1876 "http://wbrh.streamguys1.com/kbrh-mp3")
1877 ("WRKF HD-2" .
1878 ,(concat "https://playerservices.streamtheworld.com/"
1879 "api/livestream-redirect/WRKFHD2.mp3"))
1880 ("WRKF: NPR for the Capital Region" .
1881 ,(concat "https://playerservices.streamtheworld.com/"
1882 "api/livestream-redirect/WRKFFM.mp3"))
1883 ("BadRadio: 24/7 PHONK" .
1884 "https://s2.radio.co/s2b2b68744/listen")
1885 ("tilderadio" .
1886 "https://radio.tildeverse.org/radio/8000/radio.ogg")
1887 ("vantaradio" .
1888 "https://vantaa.black/radio")))
1889 (:global "C-c r r" eradio-play ; mnemonic: radio
1890 "C-c r s" eradio-stop ; mnemonic: stop
1891 "C-c r p" eradio-toggle ; mnemonic: play/pause
1892 ))
1893
1894(setup (:straight-if exec-path-from-shell
1895 (acdw/system :home))
1896 (when (daemonp)
1897 (exec-path-from-shell-initialize)))
1898
1899(setup (:straight-if fennel-mode
1900 (executable-find "fennel"))
1901 (autoload 'fennel-repl "fennel-mode" nil t)
1902 (add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode)))
1903
1904(setup (:straight-if geiser
1905 (progn
1906 (defvar acdw/schemes
1907 (let (schemes) ; these binaries should be checked...
1908 (dolist (scheme '(("scheme" . geiser-chez) ; chez
1909 ("petite" . geiser-chez) ; petite
1910 ("csi" . geiser-chez) ; chicken
1911 ("gsi" . geiser-gambit) ; gambit
1912 ("gosh" . geiser-gauche) ; gauche
1913 ("guile" . geiser-guile)
1914 ("kawa" . geiser-kawa)
1915 ("mit-scheme" . geiser-mit)
1916 ("racket" . geiser-racket)
1917 ("stklos" . geiser-stklos)))
1918 (when-let (binary (executable-find (car scheme)))
1919 (push binary schemes)
1920 ;; and install the proper helper package
1921 (straight-use-package (cdr scheme))))
1922 (nreverse schemes)))
1923 acdw/schemes)))
1924
1925(setup (:straight-if ledger-mode
1926 (executable-find "ledger")))
1927
1928(setup (:straight-if pkgbuild-mode
1929 (executable-find "makepkg")))
1930
1931(setup (:straight-if sly
1932 (progn (defvar acdw/lisp-bin
1933 (or (executable-find "sbcl")
1934 (executable-find "clisp")
1935 ""))
1936 (executable-find acdw/lisp-bin)))
1937
1938 (:option inferior-lisp-program acdw/lisp-bin
1939 sly-kill-without-query-p t)
2116 1940
2117 (setup (:straight (pdf-tools 1941 (:also-load sly-autoloads)
2118 :host github 1942 (setup (:straight clhs))
2119 :repo "vedang/pdf-tools"))
2120 (add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode))
2121 (pdf-loader-install))
2122 1943
2123 (setup (:straight systemd)) 1944 (:with-feature sly-mrepl
1945 (dolist (key '("RET" "<return>"))
1946 (:bind key sly-mrepl-return-at-end))
1947 (:bind "C-c C-c" sly-mrepl-return))
2124 1948
2125 (setup (:straight vterm)) 1949 (defun sly-mrepl-return-at-end ()
1950 (interactive)
1951 (if (<= (point-max) (point))
1952 (sly-mrepl-return)
1953 (if (bound-and-true-p paredit-mode)
1954 (paredit-newline)
1955 (electric-newline-and-maybe-indent)))))
2126 1956
2127 (add-hook 'after-make-frame-functions 1957(setup (:straight-if systemd
2128 (defun after-make-frame@maximize (frame) 1958 (executable-find "systemd")))
2129 (unless (bound-and-true-p edit-server-frame-p)
2130 (toggle-frame-maximized frame)))))
2131 1959
2132;;;; Work 1960(setup (:straight-if vterm
2133(when (acdw/system :work) 1961 (acdw/system :home)))
2134 (setup (:straight ahk-mode))) 1962
1963(setup gforth
1964 (when (locate-library "gforth")
1965 (autoload 'forth-mode "gforth")
1966 (add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode))
1967 (autoload 'forth-block-mode "gforth")
1968 (add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))))
2135 1969
2136;;; init.el ends here 1970;;; init.el ends here