diff options
-rw-r--r-- | early-init.el | 82 | ||||
-rw-r--r-- | gnus.el | 7 | ||||
-rw-r--r-- | init.el | 64 | ||||
-rw-r--r-- | lisp/acdw.el | 134 |
4 files changed, 193 insertions, 94 deletions
diff --git a/early-init.el b/early-init.el index 622d220..d3d9a29 100644 --- a/early-init.el +++ b/early-init.el | |||
@@ -34,11 +34,12 @@ | |||
34 | inhibit-x-resources t) | 34 | inhibit-x-resources t) |
35 | (acdw/gc-disable) | 35 | (acdw/gc-disable) |
36 | 36 | ||
37 | (hook-defun post-init-reset after-init-hook | 37 | (add-hook 'after-init-hook |
38 | (acdw/gc-enable) | 38 | (defun after-init@reset () |
39 | (dolist (handler file-name-handler-alist) | 39 | (acdw/gc-enable) |
40 | (add-to-list 'orig-file-name-handler-alist handler)) | 40 | (dolist (handler file-name-handler-alist) |
41 | (setq file-name-handler-alist orig-file-name-handler-alist)) | 41 | (add-to-list 'orig-file-name-handler-alist handler)) |
42 | (setq file-name-handler-alist orig-file-name-handler-alist))) | ||
42 | 43 | ||
43 | ;;; Frame settings | 44 | ;;; Frame settings |
44 | (setq default-frame-alist ; Remove most UI | 45 | (setq default-frame-alist ; Remove most UI |
@@ -60,42 +61,41 @@ | |||
60 | inhibit-x-resources t ; Don't load ~/.Xresources | 61 | inhibit-x-resources t ; Don't load ~/.Xresources |
61 | ) | 62 | ) |
62 | 63 | ||
63 | (hook-defun disable-ui-modes after-init-hook | 64 | (add-hook 'after-init-hook |
64 | (dolist (mode ;; each mode is of the form (MODE . FRAME-ALIST-VAR) | 65 | (defun after-init@disable-ui-modes () |
65 | '((tool-bar-mode . tool-bar-lines) | 66 | (dolist (mode ;; each mode is of the form (MODE . FRAME-ALIST-VAR) |
66 | (menu-bar-mode . menu-bar-lines) | 67 | '((tool-bar-mode . tool-bar-lines) |
67 | (scroll-bar-mode . vertical-scroll-bars) | 68 | (menu-bar-mode . menu-bar-lines) |
68 | (horizontal-scroll-bar-mode . horizontal-scroll-bars) | 69 | (scroll-bar-mode . vertical-scroll-bars) |
69 | )) | 70 | (horizontal-scroll-bar-mode . horizontal-scroll-bars) |
70 | (let ((setting (alist-get (cdr mode) default-frame-alist))) | 71 | )) |
71 | (when (or (not setting) | 72 | (let ((setting (alist-get (cdr mode) default-frame-alist))) |
72 | (= 0 setting)) | 73 | (when (or (not setting) |
73 | (funcall (car mode) -1))))) | 74 | (= 0 setting)) |
74 | 75 | (funcall (car mode) -1)))))) | |
75 | (add-function :after after-focus-change-function | 76 | |
76 | (defun acdw/first-frame-setup () | 77 | (add-hook 'after-make-frame-functions |
77 | ;; fonts | 78 | (defun acdw/frame-setup (&rest args) |
78 | (require 'acdw-fonts) | 79 | (ignore args) |
79 | (setq acdw-fonts/monospace (acdw/system | 80 | ;; fonts |
80 | (:home "DejaVu Sans Mono") | 81 | (require 'acdw-fonts) |
81 | (:work "Consolas") | 82 | (setq acdw-fonts/monospace (acdw/system |
82 | (:other "monospace")) | 83 | (:home "DejaVu Sans Mono") |
83 | acdw-fonts/monospace-size 10 | 84 | (:work "Consolas") |
84 | acdw-fonts/variable (acdw/system | 85 | (:other "monospace")) |
85 | (:home "DejaVu Sans") | 86 | acdw-fonts/monospace-size 10 |
86 | (:work "Calibri") | 87 | acdw-fonts/variable (acdw/system |
87 | (:other "sans-serif")) | 88 | (:home "DejaVu Sans") |
88 | acdw-fonts/variable-size 12) | 89 | (:work "Calibri") |
89 | (acdw-fonts/set) | 90 | (:other "sans-serif")) |
90 | (acdw-fonts/setup-emoji-fonts "Segoe UI Emoji" | 91 | acdw-fonts/variable-size 12) |
91 | "Noto Color Emoji" | 92 | (acdw-fonts/set) |
92 | "Apple Color Emoji" | 93 | (acdw-fonts/setup-emoji-fonts "Segoe UI Emoji" |
93 | "Symbola") | 94 | "Noto Color Emoji" |
94 | ;; fringes | 95 | "Apple Color Emoji" |
95 | (acdw/setup-fringes) | 96 | "Symbola") |
96 | ;; only run this once | 97 | ;; fringes |
97 | (remove-function after-focus-change-function | 98 | (acdw/setup-fringes))) |
98 | 'acdw/first-frame-setup))) | ||
99 | 99 | ||
100 | 100 | ||
101 | ;;; Bootstrap package manager (`straight.el') | 101 | ;;; Bootstrap package manager (`straight.el') |
diff --git a/gnus.el b/gnus.el index 5fdb08f..6c244d7 100644 --- a/gnus.el +++ b/gnus.el | |||
@@ -109,9 +109,10 @@ | |||
109 | (t (mailcap-parse-mailcaps)))) | 109 | (t (mailcap-parse-mailcaps)))) |
110 | 110 | ||
111 | ;;; Composing mail | 111 | ;;; Composing mail |
112 | (hook-defun setup-message-mode message-mode-hook | 112 | (add-hook 'message-mode-hook |
113 | (flyspell-mode +1) | 113 | (defun message-mode@setup () |
114 | (local-set-key (kbd "TAB") #'bbdb-complete-mail)) | 114 | (flyspell-mode +1) |
115 | (local-set-key (kbd "TAB") #'bbdb-complete-mail))) | ||
115 | 116 | ||
116 | ;;; Sending mail | 117 | ;;; Sending mail |
117 | (setq send-mail-function #'smtpmail-send-it | 118 | (setq send-mail-function #'smtpmail-send-it |
diff --git a/init.el b/init.el index 864c4ff..f215f9d 100644 --- a/init.el +++ b/init.el | |||
@@ -279,10 +279,12 @@ | |||
279 | 279 | ||
280 | (:leader "s" eshell-pop-or-quit) | 280 | (:leader "s" eshell-pop-or-quit) |
281 | 281 | ||
282 | (hook-defun eshell-setup 'eshell-mode-hook | 282 | (add-hook 'eshell-mode-hook |
283 | (define-key eshell-mode-map (kbd "C-d") #'eshell-quit-or-delete-char) | 283 | (defun eshell-mode@setup () |
284 | (when (boundp 'simple-modeline--mode-line) | 284 | (define-key eshell-mode-map (kbd "C-d") |
285 | (setq mode-line-format '(:eval simple-modeline--mode-line))))) | 285 | #'eshell-quit-or-delete-char) |
286 | (when (boundp 'simple-modeline--mode-line) | ||
287 | (setq mode-line-format '(:eval simple-modeline--mode-line)))))) | ||
286 | 288 | ||
287 | (setup eww | 289 | (setup eww |
288 | (:option eww-search-prefix "https://duckduckgo.com/html?q=" | 290 | (:option eww-search-prefix "https://duckduckgo.com/html?q=" |
@@ -355,6 +357,8 @@ | |||
355 | (:option ibuffer-saved-filter-groups | 357 | (:option ibuffer-saved-filter-groups |
356 | '(("default" | 358 | '(("default" |
357 | ("dired" (mode . dired-mode)) | 359 | ("dired" (mode . dired-mode)) |
360 | ("elpher" (or (mode . elpher-mode) | ||
361 | (mode . gemini-mode))) | ||
358 | ("emacs" (or (name . "^\\*scratch\\*$") | 362 | ("emacs" (or (name . "^\\*scratch\\*$") |
359 | (name . "^\\*Messages\\*$"))) | 363 | (name . "^\\*Messages\\*$"))) |
360 | ("gnus" (or (mode . message-mode) | 364 | ("gnus" (or (mode . message-mode) |
@@ -423,9 +427,10 @@ | |||
423 | (setup prog | 427 | (setup prog |
424 | (:option smie-indent-basic tab-width) | 428 | (:option smie-indent-basic tab-width) |
425 | 429 | ||
426 | (hook-defun auto-fill-prog-mode prog-mode-hook | 430 | (add-hook 'prog-mode-hook |
427 | (setq-local comment-auto-fill-only-comments t) | 431 | (defun prog-mode@auto-fill () |
428 | (turn-on-auto-fill)) | 432 | (setq-local comment-auto-fill-only-comments t) |
433 | (turn-on-auto-fill))) | ||
429 | 434 | ||
430 | (:option show-paren-delay 0 | 435 | (:option show-paren-delay 0 |
431 | show-paren-style 'mixed | 436 | show-paren-style 'mixed |
@@ -531,11 +536,12 @@ | |||
531 | "Welcome to GNU Emacs.\n\n") | 536 | "Welcome to GNU Emacs.\n\n") |
532 | initial-major-mode 'emacs-lisp-mode) | 537 | initial-major-mode 'emacs-lisp-mode) |
533 | 538 | ||
534 | (hook-defun immortal-scratch kill-buffer-query-functions | 539 | (add-hook 'kill-buffer-query-functions |
535 | (if (eq (current-buffer) (get-buffer "*scratch*")) | 540 | (defun kill-buffer-query@immortal-scratch () |
536 | (progn (bury-buffer) | 541 | (if (eq (current-buffer) (get-buffer "*scratch*")) |
537 | nil) | 542 | (progn (bury-buffer) |
538 | t))) | 543 | nil) |
544 | t)))) | ||
539 | 545 | ||
540 | (setup scrolling | 546 | (setup scrolling |
541 | (:option auto-window-vscroll nil | 547 | (:option auto-window-vscroll nil |
@@ -678,14 +684,16 @@ | |||
678 | (apheleia-global-mode +1) | 684 | (apheleia-global-mode +1) |
679 | 685 | ||
680 | ;; Use a dumb formatter on modes that `apheleia' doesn't work for. | 686 | ;; Use a dumb formatter on modes that `apheleia' doesn't work for. |
681 | (hook-defun dumb-auto-format before-save-hook | 687 | (add-hook 'before-save-hook |
682 | (setq stupid-modes '(makefile-mode | 688 | (defun before-save@dumb-auto-format () |
683 | org-mode)) | 689 | (setq stupid-modes '(makefile-mode |
684 | ;; If there's no apheleia formatter for the mode, just indent the buffer. | 690 | org-mode)) |
685 | (unless (or (apply #'derived-mode-p stupid-modes) | 691 | ;; If there's no apheleia formatter for the mode, just indent the |
686 | (and (fboundp 'apheleia--get-formatter-command) | 692 | ;; buffer. |
687 | (apheleia--get-formatter-command))) | 693 | (unless (or (apply #'derived-mode-p stupid-modes) |
688 | (indent-region (point-min) (point-max))))) | 694 | (and (fboundp 'apheleia--get-formatter-command) |
695 | (apheleia--get-formatter-command))) | ||
696 | (indent-region (point-min) (point-max)))))) | ||
689 | 697 | ||
690 | (setup (:straight async) | 698 | (setup (:straight async) |
691 | (autoload 'dired-async-mode "dired-async.el" nil t) | 699 | (autoload 'dired-async-mode "dired-async.el" nil t) |
@@ -712,17 +720,17 @@ | |||
712 | :repo "minad/consult")) | 720 | :repo "minad/consult")) |
713 | 721 | ||
714 | ;; "Sensible" functions | 722 | ;; "Sensible" functions |
715 | (defun consult-sensible-grep () | 723 | (defun consult-sensible-grep (&optional arg) |
716 | "Perform `consult-git-grep' if in a git project, otherwise `consult-ripgrep' | 724 | "Perform `consult-git-grep' if in a git project, otherwise `consult-ripgrep' |
717 | if ripgrep is installed, otherwise `consult-grep'." | 725 | if ripgrep is installed, otherwise `consult-grep'." |
718 | (interactive "P") | 726 | (interactive "P") |
719 | (cond ((= (vc-backend buffer-file-name) "Git") | 727 | (cond ((string-equal (vc-backend buffer-file-name) "Git") |
720 | (call-interactively #'consult-git-grep)) | 728 | (call-interactively #'consult-git-grep)) |
721 | ((executable-find "rg") | 729 | ((executable-find "rg") |
722 | (call-interactively #'consult-ripgrep)) | 730 | (call-interactively #'consult-ripgrep)) |
723 | (t (call-interactively #'consult-grep)))) | 731 | (t (call-interactively #'consult-grep)))) |
724 | 732 | ||
725 | (defun consult-sensible-find () | 733 | (defun consult-sensible-find (&optional arg) |
726 | "Peform `consult-locate' if locate is installed, otehrwise `consult-find'." | 734 | "Peform `consult-locate' if locate is installed, otehrwise `consult-find'." |
727 | (interactive "P") | 735 | (interactive "P") |
728 | (cond ((executable-find "locate") (call-interactively #'consult-locate)) | 736 | (cond ((executable-find "locate") (call-interactively #'consult-locate)) |
@@ -833,9 +841,7 @@ if ripgrep is installed, otherwise `consult-grep'." | |||
833 | (setup (:straight (gemini-write | 841 | (setup (:straight (gemini-write |
834 | :host nil | 842 | :host nil |
835 | :repo "https://alexschroeder.ch/cgit/gemini-write" | 843 | :repo "https://alexschroeder.ch/cgit/gemini-write" |
836 | :fork | 844 | :branch "main")) |
837 | (:repo "https://tildegit.org/acdw/gemini-write" | ||
838 | :branch "main"))) | ||
839 | (require 'gemini-write)))) | 845 | (require 'gemini-write)))) |
840 | 846 | ||
841 | (setup (:straight expand-region) | 847 | (setup (:straight expand-region) |
@@ -943,7 +949,7 @@ if ripgrep is installed, otherwise `consult-grep'." | |||
943 | (:option org-adapt-indentation nil | 949 | (:option org-adapt-indentation nil |
944 | org-catch-invisible-edits 'smart | 950 | org-catch-invisible-edits 'smart |
945 | org-confirm-babel-evaluate nil | 951 | org-confirm-babel-evaluate nil |
946 | org-ellipsis " ⌵" | 952 | org-ellipsis " …" |
947 | org-export-coding-system 'utf-8-unix | 953 | org-export-coding-system 'utf-8-unix |
948 | org-export-headline-levels 8 | 954 | org-export-headline-levels 8 |
949 | org-export-with-section-numbers nil | 955 | org-export-with-section-numbers nil |
@@ -986,7 +992,9 @@ if ripgrep is installed, otherwise `consult-grep'." | |||
986 | (defun setup-paredit-mode () | 992 | (defun setup-paredit-mode () |
987 | "Correct weirdnesses and set up paredit mode." | 993 | "Correct weirdnesses and set up paredit mode." |
988 | (paredit-mode +1) | 994 | (paredit-mode +1) |
989 | (define-key lisp-mode-shared-map (kbd "DEL") #'paredit-backward-delete)) | 995 | (let ((map lisp-mode-shared-map)) |
996 | (define-key map (kbd "DEL") #'paredit-backward-delete) | ||
997 | (define-key map (kbd "C-M-;") #'comment-or-uncomment-sexp))) | ||
990 | 998 | ||
991 | (dolist (mode lispy-modes) | 999 | (dolist (mode lispy-modes) |
992 | (add-hook (intern (concat (symbol-name mode) "-hook")) | 1000 | (add-hook (intern (concat (symbol-name mode) "-hook")) |
diff --git a/lisp/acdw.el b/lisp/acdw.el index a1c364d..8b87dd5 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el | |||
@@ -28,21 +28,21 @@ | |||
28 | (_ :other)) | 28 | (_ :other)) |
29 | "Which computer system is currently being used.") | 29 | "Which computer system is currently being used.") |
30 | 30 | ||
31 | (defmacro acdw/system (&rest arg) | 31 | (defmacro acdw/system (&rest args) |
32 | "Convenience macro for interfacing with `acdw/system'. | 32 | "Convenience macro for interfacing with `acdw/system'. |
33 | 33 | ||
34 | When called without arguments, it returns `acdw/system'. | 34 | When called without arguments, it returns `acdw/system'. When |
35 | When called with one argument, it returns (eq acdw/system ARG). | 35 | called with one (symbol) argument, it returns (eq acdw/system |
36 | When called with multiple arguments, it returns `pcase' over each argument." | 36 | ARG). When called with multiple arguments or a list, it returns |
37 | `pcase' over each argument." | ||
37 | (cond | 38 | (cond |
38 | ((not arg) acdw/system) | 39 | ((null args) acdw/system) |
39 | ((not (cdr arg)) | 40 | ((atom (car args)) |
40 | `(when (eq acdw/system ,(car arg)) | 41 | `(when (eq acdw/system ,(car args)) |
41 | ,(car arg))) | 42 | ,(car args))) |
42 | ((cdr arg) | 43 | (t |
43 | `(pcase acdw/system | 44 | `(pcase acdw/system |
44 | ,@arg)) | 45 | ,@args)))) |
45 | (t (error "Wrong argument type: %s" (type-of arg))))) | ||
46 | 46 | ||
47 | 47 | ||
48 | ;;; Utility functions | 48 | ;;; Utility functions |
@@ -65,17 +65,17 @@ When called with multiple arguments, it returns `pcase' over each argument." | |||
65 | file | 65 | file |
66 | nil))) | 66 | nil))) |
67 | 67 | ||
68 | (defmacro hook-defun (name hooks &rest forms) | 68 | ;; (defmacro hook-defun (name hooks &rest forms) |
69 | "Define a function NAME that executes FORMS, and add it to | 69 | ;; "Define a function NAME that executes FORMS, and add it to |
70 | each hook in HOOKS." | 70 | ;; each hook in HOOKS." |
71 | (declare (indent 2)) | 71 | ;; (declare (indent 2)) |
72 | (let ((func-name (intern (concat "hook-defun-" (symbol-name name)))) | 72 | ;; (let ((func-name (intern (concat "hook-defun-" (symbol-name name)))) |
73 | (hook-list (if (consp hooks) hooks (list hooks))) | 73 | ;; (hook-list (if (consp hooks) hooks (list hooks))) |
74 | (hook-defun-add-hook-list)) | 74 | ;; (hook-defun-add-hook-list)) |
75 | `(progn | 75 | ;; `(progn |
76 | (defun ,func-name () "Defined by `hook-defun'." ,@forms) | 76 | ;; (defun ,func-name () "Defined by `hook-defun'." ,@forms) |
77 | ,@(dolist (hook hook-list hook-defun-add-hook-list) | 77 | ;; ,@(dolist (hook hook-list hook-defun-add-hook-list) |
78 | (push `(add-hook ',hook #',func-name) hook-defun-add-hook-list))))) | 78 | ;; (push `(add-hook ',hook #',func-name) hook-defun-add-hook-list))))) |
79 | 79 | ||
80 | (defun kill-region-or-backward-word (arg) | 80 | (defun kill-region-or-backward-word (arg) |
81 | "Kill region if active, or backward word if not." | 81 | "Kill region if active, or backward word if not." |
@@ -106,6 +106,96 @@ is unfocused." | |||
106 | (message "%s... Done." ,message))) | 106 | (message "%s... Done." ,message))) |
107 | 107 | ||
108 | 108 | ||
109 | ;;; Comment-or-uncomment-sexp | ||
110 | ;; from https://endlessparentheses.com/a-comment-or-uncomment-sexp-command.html | ||
111 | |||
112 | (defun uncomment-sexp (&optional n) | ||
113 | "Uncomment a sexp around point." | ||
114 | (interactive "P") | ||
115 | (let* ((initial-point (point-marker)) | ||
116 | (inhibit-field-text-motion t) | ||
117 | (p) | ||
118 | (end (save-excursion | ||
119 | (when (elt (syntax-ppss) 4) | ||
120 | (re-search-backward comment-start-skip | ||
121 | (line-beginning-position) | ||
122 | t)) | ||
123 | (setq p (point-marker)) | ||
124 | (comment-forward (point-max)) | ||
125 | (point-marker))) | ||
126 | (beg (save-excursion | ||
127 | (forward-line 0) | ||
128 | (while (and (not (bobp)) | ||
129 | (= end (save-excursion | ||
130 | (comment-forward (point-max)) | ||
131 | (point)))) | ||
132 | (forward-line -1)) | ||
133 | (goto-char (line-end-position)) | ||
134 | (re-search-backward comment-start-skip | ||
135 | (line-beginning-position) | ||
136 | t) | ||
137 | (ignore-errors | ||
138 | (while (looking-at-p comment-start-skip) | ||
139 | (forward-char -1))) | ||
140 | (point-marker)))) | ||
141 | (unless (= beg end) | ||
142 | (uncomment-region beg end) | ||
143 | (goto-char p) | ||
144 | ;; Indentify the "top-level" sexp inside the comment. | ||
145 | (while (and (ignore-errors (backward-up-list) t) | ||
146 | (>= (point) beg)) | ||
147 | (skip-chars-backward (rx (syntax expression-prefix))) | ||
148 | (setq p (point-marker))) | ||
149 | ;; Re-comment everything before it. | ||
150 | (ignore-errors | ||
151 | (comment-region beg p)) | ||
152 | ;; And everything after it. | ||
153 | (goto-char p) | ||
154 | (forward-sexp (or n 1)) | ||
155 | (skip-chars-forward "\r\n[:blank:]") | ||
156 | (if (< (point) end) | ||
157 | (ignore-errors | ||
158 | (comment-region (point) end)) | ||
159 | ;; If this is a closing delimiter, pull it up. | ||
160 | (goto-char end) | ||
161 | (skip-chars-forward "\r\n[:blank:]") | ||
162 | (when (eq 5 (car (syntax-after (point)))) | ||
163 | (delete-indentation)))) | ||
164 | ;; Without a prefix, it's more useful to leave point where | ||
165 | ;; it was. | ||
166 | (unless n | ||
167 | (goto-char initial-point)))) | ||
168 | |||
169 | (defun comment-sexp--raw () | ||
170 | "Comment the sexp at point or ahead of point." | ||
171 | (pcase (or (bounds-of-thing-at-point 'sexp) | ||
172 | (save-excursion | ||
173 | (skip-chars-forward "\r\n[:blank:]") | ||
174 | (bounds-of-thing-at-point 'sexp))) | ||
175 | (`(,l . ,r) | ||
176 | (goto-char r) | ||
177 | (skip-chars-forward "\r\n[:blank:]") | ||
178 | (save-excursion | ||
179 | (comment-region l r)) | ||
180 | (skip-chars-forward "\r\n[:blank:]")))) | ||
181 | |||
182 | (defun comment-or-uncomment-sexp (&optional n) | ||
183 | "Comment the sexp at point and move past it. | ||
184 | If already inside (or before) a comment, uncomment instead. | ||
185 | With a prefix argument N, (un)comment that many sexps." | ||
186 | (interactive "P") | ||
187 | (if (or (elt (syntax-ppss) 4) | ||
188 | (< (save-excursion | ||
189 | (skip-chars-forward "\r\n[:blank:]") | ||
190 | (point)) | ||
191 | (save-excursion | ||
192 | (comment-forward 1) | ||
193 | (point)))) | ||
194 | (uncomment-sexp n) | ||
195 | (dotimes (_ (or n 1)) | ||
196 | (comment-sexp--raw)))) | ||
197 | |||
198 | |||
109 | ;;; Emacs configuration functions | 199 | ;;; Emacs configuration functions |
110 | 200 | ||
111 | (defun emacs-git-pull-config (&optional remote branch) | 201 | (defun emacs-git-pull-config (&optional remote branch) |