diff options
-rw-r--r-- | early-init.el | 61 | ||||
-rw-r--r-- | init.el | 744 |
2 files changed, 77 insertions, 728 deletions
diff --git a/early-init.el b/early-init.el index b0314ae..5e9d585 100644 --- a/early-init.el +++ b/early-init.el | |||
@@ -1,72 +1,23 @@ | |||
1 | ;;; early-init.el ~ acdw -*- lexical-binding: t; no-byte-compile: t -*- | 1 | ;;; early-init.el -*- lexical-binding: t; no-byte-compile: t -*- |
2 | |||
3 | ;;; Commentary: | ||
4 | ;; `early-init.el' is new as of Emacs 27.1. It contains ... /early initiation/. | ||
5 | ;; What does that mean? Who knows. What I /do know/ is that it runs /before/ | ||
6 | ;; `package.el' is loaded, so I can stop it from loading, since I use `straight.el'. | ||
7 | ;; Other than that, there's some other init stuff that needs to happen as early | ||
8 | ;; as possible -- think bootstrap-level. | ||
9 | |||
10 | ;;; Settings | ||
11 | |||
12 | ;; (setq debug-on-error t) | ||
13 | 2 | ||
14 | (setq load-prefer-newer t) | 3 | (setq load-prefer-newer t) |
15 | 4 | ||
16 | ;;; Speed up startup | 5 | ;;; Bootstrap `straight.el' |
17 | (setq gc-cons-threshold most-positive-fixnum) | ||
18 | (defconst *acdw/gc-cons* 800000 "'Regular' garbage collection amount") | ||
19 | |||
20 | (defvar file-name-handler-alist-old file-name-handler-alist) | ||
21 | (setq file-name-handler-alist nil) | ||
22 | |||
23 | (setq message-log-max 16384) | ||
24 | (setq byte-compile-warnings | ||
25 | '(not free-vars unresolved noruntime lexical make-local)) | ||
26 | |||
27 | ;;; Restore stuff after startup | ||
28 | (add-hook 'after-init-hook | ||
29 | (lambda () | ||
30 | (setq file-name-handler-alist file-name-handler-alist-old) | ||
31 | (setq gc-cons-threshold *acdw/gc-cons*) | ||
32 | (garbage-collect)) | ||
33 | t) | ||
34 | |||
35 | ;;; Define the platforms I work on | ||
36 | (defconst *acdw/at-work* (eq system-type 'windows-nt)) | ||
37 | (defconst *acdw/at-larry* (string= (system-name) "larry")) | ||
38 | (defconst *acdw/at-bax* (string= (system-name) "bax")) | ||
39 | (defconst *acdw/at-home* (or *acdw/at-larry* *acdw/at-bax*)) | ||
40 | |||
41 | ;;;; When at work, I have to use Portable Git. | ||
42 | (when *acdw/at-work* | ||
43 | (add-to-list 'exec-path "~/bin") | ||
44 | (add-to-list 'exec-path "C:/Users/aduckworth/Downloads/PortableGit/bin")) | ||
45 | |||
46 | ;;; `straight.el' ~ github.com/raxod502/straight.el | ||
47 | |||
48 | ;;;; Bootstrap | ||
49 | ;; NOTE: this doesn't work on Windows (download straight directly) | ||
50 | (defvar bootstrap-version) | 6 | (defvar bootstrap-version) |
51 | (let ((bootstrap-file | 7 | (let ((bootstrap-file |
52 | (expand-file-name "straight/repos/straight.el/bootstrap.el" | 8 | (expand-file-name "straight/repos/straight.el/bootstrap.el" |
53 | user-emacs-directory)) | 9 | user-emacs-directory)) |
54 | (bootstrap-version 5)) | 10 | (bootstrap-version 5)) |
55 | (unless (file-exists-p bootstrap-file) | 11 | (unless (file-exists-p bootstrap-file) |
56 | (with-current-buffer | 12 | (with-current-buffer |
57 | (url-retrieve-synchronously | 13 | (url-retrieve-synchronously |
58 | "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" | 14 | "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" |
59 | 'silent 'inhibit-cookies) | 15 | 'silent 'inhibit-cookies) |
60 | (goto-char (point-max)) | 16 | (goto-char (point-max)) |
61 | (eval-print-last-sexp))) | 17 | (eval-print-last-sexp))) |
62 | (load bootstrap-file nil 'nomessage)) | 18 | (load bootstrap-file nil 'nomessage)) |
63 | 19 | ||
64 | ;;; Bootstrap `use-package' | 20 | ;;; Bootstrap `use-package' |
65 | (setq-default use-package-verbose nil | ||
66 | use-package-expand-minimally t | ||
67 | use-package-enable-imenu-support t | ||
68 | use-package-hook-name-suffix nil) | ||
69 | |||
70 | (straight-use-package 'use-package) | 21 | (straight-use-package 'use-package) |
71 | 22 | ||
72 | (setq straight-use-package-by-default t) | 23 | (setq straight-use-package-by-default t) |
diff --git a/init.el b/init.el index b7de877..60f854a 100644 --- a/init.el +++ b/init.el | |||
@@ -1,243 +1,29 @@ | |||
1 | ;;; init.el -*- lexical-binding: t; coding: utf-8; fill-column: 70 -*- | 1 | ;;; init.el -*- lexical-binding: t; coding: utf-8; -*- |
2 | ;;; Commentary: | ||
3 | ;; I /was/ going to convert this to org-mode, but then I found this | ||
4 | ;; page: https://yiufung.net/post/pure-emacs-lisp-init-skeleton/, | ||
5 | ;; which pointed out that I could use `outline-minor-mode' (or in my case, | ||
6 | ;; `outshine') to fold and navigate a pure-elisp `init.el'. So that's | ||
7 | ;; what I'm doing. | ||
8 | |||
9 | ;;; Custom Functions | ||
10 | (defun acdw/split-and-follow-window-below () | ||
11 | "Split the window below and switch to the split." | ||
12 | (interactive) | ||
13 | (split-window-below) | ||
14 | (balance-windows) | ||
15 | (other-window 1)) | ||
16 | |||
17 | (defun acdw/split-and-follow-window-right () | ||
18 | "Split the window right and switch to the split." | ||
19 | (interactive) | ||
20 | (split-window-right) | ||
21 | (balance-windows) | ||
22 | (other-window 1)) | ||
23 | |||
24 | (defun acdw/kill-this-buffer () | ||
25 | "Kill the current buffer." | ||
26 | (interactive) | ||
27 | (kill-buffer nil)) | ||
28 | |||
29 | ;; https://bling.github.io/blog/2016/01/18/why-are-you-changing-gc-cons-threshold/ | ||
30 | (defun acdw/stop-gc () | ||
31 | "Stop garbage collection by setting it to a very high number." | ||
32 | (setq gc-cons-threshold most-positive-fixnum)) | ||
33 | |||
34 | (defun acdw/start-gc () | ||
35 | "Start garbage collection by resetting it to `*acdw/gc-cons*'." | ||
36 | (setq gc-cons-threshold *acdw/gc-cons*)) | ||
37 | |||
38 | (defun post-to-gemlog-blue (post-title user pass) | ||
39 | "Post current buffer to gemlog.blue." | ||
40 | (interactive | ||
41 | (let* ((title-maybe (progn ;; TODO this is ... clunky | ||
42 | (goto-char (point-min)) | ||
43 | (if (re-search-forward "^# \\(.*\\)" nil t) | ||
44 | (buffer-substring-no-properties | ||
45 | (match-beginning 1) | ||
46 | (match-end 1)) | ||
47 | ""))) | ||
48 | (title (read-string | ||
49 | (format "Title%s: " | ||
50 | (if (string= "" title-maybe) | ||
51 | "" | ||
52 | (concat " (" title-maybe ")"))) | ||
53 | nil nil title-maybe)) | ||
54 | (user (read-string "User: " nil)) | ||
55 | (pass (read-passwd "Pass: " nil))) | ||
56 | (list title user pass))) | ||
57 | |||
58 | (require 'mm-url) | ||
59 | (let ((url-request-method "POST") | ||
60 | (url-request-extra-headers | ||
61 | '(("Content-Type" . "application/x-www-form-urlencoded"))) | ||
62 | (url-request-data | ||
63 | (mm-url-encode-www-form-urlencoded | ||
64 | `(("title" . ,post-title) | ||
65 | ("gemloguser" . ,user) | ||
66 | ("pw" . ,pass) | ||
67 | ("post" . ,(buffer-string)))))) | ||
68 | (with-current-buffer | ||
69 | (url-retrieve-synchronously "https://gemlog.blue/post.php") | ||
70 | (goto-char (point-min)) | ||
71 | (re-search-forward "\\(gemini://.*\\.gmi\\)") | ||
72 | (elpher-go (match-string 1))))) | ||
73 | |||
74 | ;;; Basic emacs config & built-in packages | ||
75 | ;;;; /Really/ basic emacs config | ||
76 | (use-package emacs | ||
77 | :straight nil | ||
78 | :demand t | ||
79 | :custom | ||
80 | ;; completion | ||
81 | (completion-ignore-case t) | ||
82 | (read-buffer-completion-ignore-case t) | ||
83 | (read-file-name-completion-ignore-case t) | ||
84 | ;; etc. | ||
85 | (indent-tabs-mode nil "Indentation won't insert tabs.") | ||
86 | (visible-bell (not *acdw/at-larry*) "Don't ring a bell, unless at larry.") | ||
87 | (use-dialog-box nil "Ask questions in the modeline.") | ||
88 | (disabled-command-function nil) | ||
89 | (mark-even-if-inactive nil "Don't use the mark when inactive.") | ||
90 | ;; paragraphs | ||
91 | (sentence-end-double-space t "Sentences end with two spaces.") | ||
92 | ;; cursor | ||
93 | (cursor-type 'bar) | ||
94 | (cursor-in-non-selected-windows 'hollow) | ||
95 | (default-frame-alist '((tool-bar-lines . 0) | ||
96 | (menu-bar-lines . 0) | ||
97 | (vertical-scroll-bars . nil) | ||
98 | (horizontal-scroll-bars . nil) | ||
99 | (right-divider-width . 2) | ||
100 | (bottom-divider-width . 2) | ||
101 | (left-fringe-width . 2) | ||
102 | (right-fringe-width . 2))) | ||
103 | (inhibit-startup-buffer-menu t) | ||
104 | (inhibit-startup-screen t) | ||
105 | (initial-buffer-choice t "Start out in *scratch*.") | ||
106 | (initial-scratch-message nil) | ||
107 | :config | ||
108 | (fset 'yes-or-no-p 'y-or-n-p) | ||
109 | (blink-cursor-mode 0) | ||
110 | :bind | ||
111 | ("C-z" . nil) | ||
112 | ("C-x k" . acdw/kill-this-buffer) | ||
113 | ("C-x K" . kill-buffer) | ||
114 | :hook | ||
115 | (prog-mode-hook . prettify-symbols-mode) | ||
116 | (before-save-hook . delete-trailing-whitespace) | ||
117 | (minibuffer-setup-hook . acdw/stop-gc) | ||
118 | (minibuffer-exit-hook . acdw/start-gc)) | ||
119 | |||
120 | (use-package calendar | ||
121 | :straight nil | ||
122 | :custom | ||
123 | (calendar-location-name "Baton Rouge, LA") | ||
124 | (calendar-latitude 30.39) | ||
125 | (calendar-longitude -91.83)) | ||
126 | |||
127 | (use-package browse-url | ||
128 | :straight nil | ||
129 | :custom | ||
130 | (browse-url-browser-function 'browse-url-firefox) | ||
131 | (browse-url-new-window-flag t) | ||
132 | (browse-url-firefox-new-window-is-tab t)) | ||
133 | 2 | ||
134 | (use-package paren | 3 | ;;; Commentary: |
135 | :straight nil | 4 | ;; BANKRUPT_SCORE: 1 |
136 | :custom | 5 | ;; ^ the number of times I've declared Emacs bankruptcy. |
137 | (show-paren-style 'mixed) | 6 | ;; Does this mean I'm part of the cool kids now? |
138 | :config | ||
139 | (show-paren-mode)) | ||
140 | |||
141 | (use-package simple | ||
142 | :straight nil | ||
143 | :custom | ||
144 | (save-interprogram-paste-before-kill | ||
145 | t "Save existing clipboard text into killring before replacing it.") | ||
146 | :config | ||
147 | (global-visual-line-mode)) | ||
148 | |||
149 | (use-package delsel | ||
150 | :straight nil | ||
151 | :config | ||
152 | (delete-selection-mode)) | ||
153 | |||
154 | (use-package display-line-numbers | ||
155 | :straight nil | ||
156 | :when (and (fboundp 'display-line-numbers-mode) | ||
157 | (display-graphic-p)) | ||
158 | :hook | ||
159 | (prog-mode-hook . display-line-numbers-mode)) | ||
160 | |||
161 | (use-package linum | ||
162 | :straight nil | ||
163 | :unless (and (fboundp 'display-line-numbers-mode) | ||
164 | (display-graphic-p)) | ||
165 | :hook | ||
166 | (prog-mode-hook . linum-mode)) | ||
167 | |||
168 | (use-package mule | ||
169 | :straight nil | ||
170 | :init | ||
171 | (set-charset-priority 'unicode) | ||
172 | (set-language-environment "UTF-8") | ||
173 | (set-default-coding-systems 'utf-8) | ||
174 | (set-terminal-coding-system 'utf-8) | ||
175 | (set-keyboard-coding-system 'utf-8) | ||
176 | (set-selection-coding-system 'utf-8) | ||
177 | (prefer-coding-system 'utf-8) | ||
178 | :custom | ||
179 | (default-buffer-file-coding-system 'utf-8) | ||
180 | (default-process-coding-system '(utf-8-unix . utf-8-unix)) | ||
181 | (locale-coding-system 'utf-8)) | ||
182 | |||
183 | (use-package mouse | ||
184 | :straight nil | ||
185 | :custom | ||
186 | (mouse-yank-at-point t "Yank at point instead of click.")) | ||
187 | |||
188 | (use-package files | ||
189 | :straight nil | ||
190 | :custom | ||
191 | (require-final-newline t) | ||
192 | (confirm-kill-processes nil) | ||
193 | (confirm-kill-emacs nil) | ||
194 | :bind | ||
195 | ("C-x f" . find-file)) | ||
196 | |||
197 | (use-package window | ||
198 | :straight nil | ||
199 | :bind | ||
200 | ([remap split-window-below] . acdw/split-and-follow-window-below) | ||
201 | ([remap split-window-right] . acdw/split-and-follow-window-right)) | ||
202 | 7 | ||
203 | ;;;; Keep .emacs.d clean | 8 | ;;; Macros |
204 | ;; load this early for other packages to use | 9 | (defmacro cuss (var val) |
205 | (use-package no-littering | 10 | "Basically `use-package' `:custom' but without either." |
206 | :demand | 11 | `(progn |
207 | :custom | 12 | (funcall (or (get ',var 'custom-set) #'set-default) |
208 | (create-lockfiles nil) | 13 | ',var ,val))) |
209 | (delete-old-versions t) | ||
210 | (kept-new-versions 6) | ||
211 | (kept-old-versions 2) | ||
212 | (version-control t) | ||
213 | :config | ||
214 | (setq custom-file (no-littering-expand-etc-file-name "custom.el")) | ||
215 | (setq backup-directory-alist | ||
216 | `((".*" . ,(no-littering-expand-var-file-name "backup/"))))) | ||
217 | 14 | ||
218 | ;;;; Uniquily name buffers | 15 | ;;; Files |
219 | (use-package uniquify | 16 | ;; keep `emacs-user-directory' tidy |
220 | :straight nil | 17 | (use-package no-littering) |
221 | :custom | ||
222 | (uniquify-buffer-name-style 'forward)) | ||
223 | 18 | ||
224 | ;;;; Use async when possible | 19 | ;; don't clutter `init.el' with customize crap |
225 | (use-package async | 20 | (cuss custom-file (no-littering-expand-etc-file-name "custom.el")) |
226 | :config ;; not sure when this is loaded | ||
227 | (dired-async-mode)) | ||
228 | 21 | ||
229 | ;;;; Autocompile elisp files (like this one) | 22 | ;; backups |
230 | (use-package auto-compile | 23 | (cuss backup-directory-alist |
231 | :custom | 24 | `((".*" . ,(no-littering-expand-var-file-name "backup/")))) |
232 | (load-prefer-newer t) | ||
233 | :init | ||
234 | (defun acdw/setup-auto-compile () | ||
235 | (auto-compile-on-load-mode) | ||
236 | (auto-compile-on-save-mode)) | ||
237 | :hook | ||
238 | (emacs-lisp-mode-hook . acdw/setup-auto-compile)) | ||
239 | 25 | ||
240 | ;;;; Recent files | 26 | ;; recent files |
241 | (use-package recentf | 27 | (use-package recentf |
242 | :config | 28 | :config |
243 | (add-to-list 'recentf-exclude no-littering-var-directory) | 29 | (add-to-list 'recentf-exclude no-littering-var-directory) |
@@ -246,469 +32,81 @@ | |||
246 | (recentf-max-menu-items 100) | 32 | (recentf-max-menu-items 100) |
247 | (recentf-max-saved-items 100) | 33 | (recentf-max-saved-items 100) |
248 | :config | 34 | :config |
249 | (recentf-mode)) | 35 | (recentf-mode +1)) |
250 | 36 | ||
251 | ;;;; Save places in files | 37 | ;;; Save/Restore |
38 | ;; save places in files | ||
252 | (use-package saveplace | 39 | (use-package saveplace |
253 | :custom | 40 | :custom |
254 | (save-place-file (no-littering-expand-var-file-name "places")) | 41 | (save-place-file (no-littering-expand-var-file-name "places")) |
255 | (save-place-forget-unreadable-files (not *acdw/at-work*)) | ||
256 | :config | 42 | :config |
257 | (save-place-mode)) | 43 | (save-place-mode +1)) |
258 | 44 | ||
259 | ;;;; Save history of commands, etc. | 45 | ;; save history of variables |
260 | (use-package savehist | 46 | (use-package savehist |
261 | :custom | 47 | :custom |
262 | (savehist-additional-variables | 48 | (savehist-additional-variables |
263 | '(kill-ring | 49 | '(kill-ring |
264 | search-ring | 50 | search-ring |
265 | regexp-search-ring)) | 51 | regexp-search-ring)) |
266 | (savehist-mode)) | ||
267 | |||
268 | ;;;; Authority sources for logins | ||
269 | ;; TODO: use gpg | ||
270 | (use-package auth-source | ||
271 | :init | ||
272 | (setq auth-sources '("~/.authinfo")) | ||
273 | (setq user-full-name "Case Duckworth") | ||
274 | (setq user-mail-address "acdw@acdw.net")) | ||
275 | |||
276 | ;;; General-ish Packages | ||
277 | ;;;; General improvements | ||
278 | ;;;;; Better auto-save | ||
279 | (use-package super-save | ||
280 | :custom | ||
281 | (auto-save-default nil) | ||
282 | (super-save-auto-save-when-idle t) | ||
283 | (super-save-exclude '(".gpg")) | ||
284 | :config | ||
285 | (super-save-mode)) | ||
286 | |||
287 | ;;;;; Restart emacs /from within/ emacs | ||
288 | (use-package restart-emacs) | ||
289 | |||
290 | ;;;; User interface | ||
291 | ;;;;; Pop-up help for keys | ||
292 | (use-package which-key | ||
293 | :custom | ||
294 | (which-key-enable-extended-define-key t) | ||
295 | :config | ||
296 | (which-key-mode)) | ||
297 | |||
298 | ;;;;; A better help buffer | ||
299 | (use-package helpful | ||
300 | :bind | ||
301 | ("C-h f" . helpful-callable) | ||
302 | ("C-h v" . helpful-variable) | ||
303 | ("C-h k" . helpful-key) | ||
304 | ("C-c C-d" . helpful-at-point) | ||
305 | ("C-h F" . helpful-function) | ||
306 | ("C-h C" . helpful-command)) | ||
307 | |||
308 | ;;;;; A better `outline-mode' | ||
309 | (use-package outshine | ||
310 | :custom | ||
311 | (outshine-cycle-emulate-tab t) | ||
312 | :bind (:map outshine-mode-map | ||
313 | ("<S-iso-lefttab>" . outshine-cycle-buffer) | ||
314 | ("<backtab>" . outshine-cycle-buffer)) | ||
315 | :hook | ||
316 | (emacs-lisp-mode-hook . outshine-mode)) | ||
317 | |||
318 | ;;;;; Item selection & narrowing | ||
319 | (use-package selectrum | ||
320 | :custom | ||
321 | (enable-recursive-minibuffers t) | ||
322 | :init | ||
323 | (minibuffer-depth-indicate-mode) | ||
324 | :config | ||
325 | (selectrum-mode)) | ||
326 | |||
327 | (use-package prescient | ||
328 | :config | ||
329 | (prescient-persist-mode)) | ||
330 | |||
331 | (use-package selectrum-prescient | ||
332 | :config | ||
333 | (selectrum-prescient-mode)) | ||
334 | |||
335 | ;;;;; Searching | ||
336 | (use-package ctrlf | ||
337 | :custom | ||
338 | (ctrlf-show-match-count-at-eol nil) | ||
339 | :config | ||
340 | (ctrlf-mode)) | ||
341 | |||
342 | ;;;;; Visually switch windows | ||
343 | (use-package ctrlxo | ||
344 | :straight (ctrlxo | ||
345 | :host github | ||
346 | :repo "muffinmad/emacs-ctrlxo") | ||
347 | :bind | ||
348 | ([remap other-window] . ctrlxo)) | ||
349 | |||
350 | ;;;;; Undo-Fu | ||
351 | (use-package undo-fu | ||
352 | :bind | ||
353 | ("C-/" . undo-fu-only-undo) | ||
354 | ("C-?" . undo-fu-only-redo)) | ||
355 | |||
356 | (use-package undo-fu-session | ||
357 | :after no-littering | ||
358 | :custom | ||
359 | (undo-fu-session-incompatible-files | ||
360 | '("/COMMIT_EDITMSG\\'" | ||
361 | "/git-rebase-todo\\'")) | ||
362 | (undo-fu-session-directory | ||
363 | (no-littering-expand-var-file-name "undos/")) | ||
364 | :config | ||
365 | (global-undo-fu-session-mode)) | ||
366 | |||
367 | ;;;; Theming, looks, fonts | ||
368 | ;;;;; Fonts | ||
369 | ;; https://github.com/kaushalmodi/.emacs.d/blob/master/init.el#L376 | ||
370 | ;; modi/font-check | ||
371 | (defun acdw/setup-fonts () | ||
372 | (let* ((fixed-pitch-sans-serif-family | ||
373 | (cond | ||
374 | ((x-list-fonts "Fantasque Sans Mono") '(:family "Fantasque Sans Mono" | ||
375 | :height 110)) | ||
376 | ((x-list-fonts "Fira Code") '(:family "Fira Code")) | ||
377 | ((x-list-fonts "Consolas") '(:family "Consolas")) | ||
378 | ((x-list-fonts "DejaVu Sans Mono") '(:family "DejaVu Sans Mono")) | ||
379 | ((x-list-fonts "Fixed") '(:family "Fixed")) | ||
380 | (nil (warn "Can't find a good fixed pitch sans-serif font.")))) | ||
381 | (fixed-pitch-serif-family | ||
382 | (cond ((x-list-fonts "Go Mono") '(:family "Go Mono")) | ||
383 | ((x-list-fonts "Courier Prime") '(:family "Courier Prime")) | ||
384 | ((x-list-fonts "Courier New") '(:family "Courier New")) | ||
385 | ((x-list-fonts "Courier") '(:family "Courier")) | ||
386 | (nil (warn "Can't find a good fixed pitch serif font.")))) | ||
387 | (variable-pitch-sans-serif-family | ||
388 | (cond ((x-list-fonts "DejaVu Sans") '(:family "DejaVu Sans")) | ||
389 | ((x-list-fonts "Go") '(:family "Go")) | ||
390 | ((x-list-fonts "Arial") '(:family "Arial")) | ||
391 | (nil (warn "Cant't find a good variable pitch sans-serif font.")))) | ||
392 | (variable-pitch-serif-family | ||
393 | (cond ((x-list-fonts "DejaVu Serif") '(:family "DejaVu Serif")) | ||
394 | ((x-list-fonts "Georgia") '(:family "Georgia")) | ||
395 | ((x-list-fonts "Times New Roman") '(:family "Times New Roman")) | ||
396 | ((x-list-fonts "Times") '(:family "Times")) | ||
397 | (nil (warn "Can't find a good variable pitch serif font.")))) | ||
398 | |||
399 | (fixed-pitch-family fixed-pitch-sans-serif-family) | ||
400 | (variable-pitch-family variable-pitch-serif-family) | ||
401 | (default-family fixed-pitch-family)) | ||
402 | (custom-theme-set-faces | ||
403 | 'user | ||
404 | `(fixed-pitch ((t (,@fixed-pitch-family)))) | ||
405 | `(fixed-pitch-serif ((t (,@fixed-pitch-serif-family)))) | ||
406 | `(variable-pitch ((t (,@variable-pitch-family)))) | ||
407 | `(default ((t (,@default-family)))))) | ||
408 | (remove-hook 'focus-in-hook #'acdw/setup-fonts)) | ||
409 | (add-hook 'focus-in-hook #'acdw/setup-fonts) | ||
410 | |||
411 | ;;;;; Modeline | ||
412 | (use-package doom-modeline | ||
413 | :custom | ||
414 | (doom-modeline-icon nil) | ||
415 | (doom-modeline-enable-word-count t) | ||
416 | :hook | ||
417 | (after-init-hook . doom-modeline-mode)) | ||
418 | |||
419 | ;;;;; Ligatures | ||
420 | (use-package ligature | ||
421 | :straight (ligature | ||
422 | :host github | ||
423 | :repo "mickeynp/ligature.el") | ||
424 | :config | ||
425 | (ligature-set-ligatures 'prog-mode | ||
426 | '("++" "--" "/=" "&&" "||" "||=" | ||
427 | "->" "=>" "::" "__" | ||
428 | "==" "===" "!=" "=/=" "!==" | ||
429 | "<=" ">=" "<=>" | ||
430 | "/*" "*/" "//" "///" | ||
431 | "\\n" "\\\\" | ||
432 | "<<" "<<<" "<<=" ">>" ">>>" ">>=" | ||
433 | "|=" "^=" | ||
434 | "**" "--" "---" "----" "-----" | ||
435 | "==" "===" "====" "=====" | ||
436 | "</" "<!--" "</>" "-->" "/>" | ||
437 | ":=" "..." ":>" ":<" ">:" "<:" | ||
438 | "::=" ;; add others here | ||
439 | )) | ||
440 | :config | ||
441 | (global-ligature-mode)) | ||
442 | |||
443 | ;;;;; Unicode | ||
444 | (use-package unicode-fonts | ||
445 | :config | 52 | :config |
446 | (unicode-fonts-setup)) | 53 | (savehist-mode +1)) |
447 | 54 | ||
448 | ;;;;; Modus themes | 55 | ;;; Buffers |
56 | ;; uniquely name buffers | ||
57 | (cuss uniquify-buffer-name-style 'forward) | ||
58 | |||
59 | ;;; UI | ||
60 | ;; frame defaults | ||
61 | (cuss default-frame-alist '((tool-bar-lines . 0) | ||
62 | (menu-bar-lines . 0) | ||
63 | (vertical-scroll-bars . nil) | ||
64 | (horizontal-scroll-bars . nil) | ||
65 | (right-divider-width . 2) | ||
66 | (bottom-divider-width . 2) | ||
67 | (left-fringe-width . 2) | ||
68 | (right-fringe-width . 2))) | ||
69 | |||
70 | ;; cursor | ||
71 | (cuss cursor-type 'bar) | ||
72 | (cuss cursor-in-non-selected-windows 'hollow) | ||
73 | (blink-cursor-mode 0) | ||
74 | |||
75 | ;; mouse | ||
76 | (cuss mouse-yank-at-point t) ; yank at the point instead of where clicked | ||
77 | |||
78 | ;; startup screen | ||
79 | (cuss inhibit-startup-buffer-menu t) | ||
80 | (cuss inhibit-startup-screen t) | ||
81 | (cuss initial-buffer-choice t) ; start in *scratch* | ||
82 | (cuss initial-scratch-message nil) | ||
83 | |||
84 | ;; interactivity | ||
85 | (fset 'yes-or-no-p #'y-or-n-p) | ||
86 | |||
87 | ;; themes | ||
449 | (use-package modus-operandi-theme | 88 | (use-package modus-operandi-theme |
450 | :config | 89 | :config |
451 | (load-theme 'modus-operandi t t) | 90 | (load-theme 'modus-operandi t)) |
452 | |||
453 | (defun acdw/sunrise () | ||
454 | (enable-theme 'modus-operandi)) | ||
455 | |||
456 | (if *acdw/at-work* | ||
457 | (enable-theme 'modus-operandi) | ||
458 | (run-at-time (nth 1 (split-string (sunrise-sunset))) | ||
459 | (* 60 60 24) #'acdw/sunrise))) | ||
460 | |||
461 | (when *acdw/at-home* | ||
462 | (use-package modus-vivendi-theme | ||
463 | :config | ||
464 | (load-theme 'modus-vivendi t t) | ||
465 | |||
466 | (defun acdw/sunset () | ||
467 | (enable-theme 'modus-vivendi)) | ||
468 | |||
469 | (run-at-time (nth 4 (split-string (sunrise-sunset))) | ||
470 | (* 60 60 24) #'acdw/sunset) | ||
471 | (run-at-time "12am" (* 60 60 24) #'acdw/sunset))) | ||
472 | |||
473 | ;;;;; Convert ^L to a line | ||
474 | (use-package page-break-lines | ||
475 | :config | ||
476 | (global-page-break-lines-mode)) | ||
477 | |||
478 | ;;;; General text editing | ||
479 | ;;;;; Jump to characters fast | ||
480 | (use-package avy | ||
481 | :bind | ||
482 | ("C-'" . avy-goto-char-timer)) | ||
483 | |||
484 | ;;;;; Show text commands acted on | ||
485 | (use-package volatile-highlights | ||
486 | :config | ||
487 | (volatile-highlights-mode)) | ||
488 | |||
489 | ;;;;; Visual replacement for `zap-to-char' | ||
490 | (use-package zop-to-char | ||
491 | :bind | ||
492 | ([remap zap-to-char] . zop-to-char) | ||
493 | ([remap zap-up-to-char] . zop-up-to-char)) | ||
494 | 91 | ||
495 | ;;;;; Kill & mark things more visually | 92 | ;;; Text editing |
496 | (use-package easy-kill | 93 | ;; visual line mode |
497 | :bind | 94 | (global-visual-line-mode +1) |
498 | ([remap kill-ring-save] . easy-kill) | ||
499 | ([remap mark-sexp] . easy-mark)) | ||
500 | 95 | ||
501 | ;;;;; Operate on the current line if no region is active | 96 | ;; delete the selection when typing |
502 | (use-package whole-line-or-region | 97 | (delete-selection-mode +1) |
503 | :config | ||
504 | (whole-line-or-region-global-mode)) | ||
505 | 98 | ||
506 | ;;;;; Expand region | 99 | ;; clipboard |
507 | (use-package expand-region | 100 | (cuss save-interprogram-paste-before-kill t) ; save existing clipboard text to kill ring before replacing it |
508 | :bind | ||
509 | ("C-=" . er/expand-region)) | ||
510 | 101 | ||
511 | ;;;; Programming | 102 | ;;; Programming |
512 | ;;;;; Code completion | 103 | ;; Git |
513 | (use-package company | ||
514 | :custom | ||
515 | (company-idle-delay 0.1) | ||
516 | (company-show-numbers t) | ||
517 | :config | ||
518 | (let ((map company-active-map)) | ||
519 | (mapc (lambda (x) | ||
520 | (define-key map (format "%d" x) | ||
521 | `(lambda () | ||
522 | (interactive) | ||
523 | (company-complete-number ,x)))) | ||
524 | (number-sequence 0 9))) | ||
525 | :hook | ||
526 | (prog-mode-hook . company-mode) | ||
527 | :bind (:map company-active-map | ||
528 | ("C-n" . company-select-next) | ||
529 | ("C-p" . company-select-previous))) | ||
530 | |||
531 | (use-package company-quickhelp | ||
532 | :hook | ||
533 | (company-mode-hook . company-quickhelp-local-mode)) | ||
534 | |||
535 | (use-package company-prescient | ||
536 | :hook | ||
537 | (company-mode-hook . company-prescient-mode)) | ||
538 | |||
539 | ;;;;; Git integration | ||
540 | (use-package magit | 104 | (use-package magit |
541 | :when *acdw/at-home* | ||
542 | :bind | 105 | :bind |
543 | ("C-x g" . magit-status) | 106 | ("C-x g" . magit-status) |
544 | :config | 107 | :config |
545 | (add-to-list 'magit-no-confirm 'stage-all-changes)) | 108 | (add-to-list 'magit-no-confirm 'stage-all-changes)) |
546 | 109 | ||
547 | ;; use libgit to speed up magit, only when cmake is available | ||
548 | (when (executable-find "cmake") | 110 | (when (executable-find "cmake") |
549 | (use-package libgit) | 111 | (use-package libgit) |
550 | 112 | (use-package magit-libgit)) | |
551 | (use-package magit-libgit | ||
552 | :after (magit libgit)) | ||
553 | ) | ||
554 | |||
555 | (use-package forge | ||
556 | :when *acdw/at-home* | ||
557 | :after magit | ||
558 | :config | ||
559 | (setq forge-owned-accounts '(("duckwork")))) | ||
560 | |||
561 | ;;;;; Code formatting & display | ||
562 | (use-package format-all | ||
563 | :hook | ||
564 | (prog-mode-hook . format-all-mode)) | ||
565 | |||
566 | ;;;;;; Smartly deal with pairs | ||
567 | (use-package smartparens | ||
568 | :init | ||
569 | (defun acdw/setup-smartparens () | ||
570 | (require 'smartparens-config) | ||
571 | (smartparens-mode)) | ||
572 | :hook | ||
573 | (prog-mode-hook . acdw/setup-smartparens)) | ||
574 | |||
575 | ;;;;;; Show delimiters as different colors | ||
576 | (use-package rainbow-delimiters | ||
577 | :hook | ||
578 | (prog-mode-hook . rainbow-delimiters-mode)) | ||
579 | |||
580 | ;;;;;; Show colors as they appear in the buffer | ||
581 | (use-package rainbow-mode | ||
582 | :hook | ||
583 | (prog-mode-hook . rainbow-mode)) | ||
584 | |||
585 | ;;;; Writing | ||
586 | ;;;;; `fill-column', but in `visual-line-mode' | ||
587 | (use-package visual-fill-column | ||
588 | :custom | ||
589 | (split-window-preferred-function 'visual-fill-column-split-window-sensibly) | ||
590 | (visual-fill-column-center-text t) | ||
591 | :config | ||
592 | (advice-add 'text-scale-adjust | ||
593 | :after #'visual-fill-column-adjust)) | ||
594 | |||
595 | ;;;; Machine-specific | ||
596 | ;;;;; Linux at home | ||
597 | (when *acdw/at-home* | ||
598 | ;;;;;; Edit files with `sudo' (I think?) | ||
599 | (use-package su | ||
600 | :config | ||
601 | (su-mode)) | ||
602 | |||
603 | ;;;;;; Implement XDG Trash specification | ||
604 | (use-package trashed | ||
605 | :custom | ||
606 | (delete-by-moving-to-trash t)) | ||
607 | |||
608 | ;;;;;; Build exec-path from $PATH | ||
609 | (use-package exec-path-from-shell | ||
610 | :demand | ||
611 | :config | ||
612 | (exec-path-from-shell-initialize)) | ||
613 | ) | ||
614 | |||
615 | ;;; Specialized packages | ||
616 | ;;;; Gemini & Gopher | ||
617 | (use-package elpher | ||
618 | :straight (elpher | ||
619 | :repo "git://thelambdalab.xyz/elpher.git") | ||
620 | :bind (:map elpher-mode-map | ||
621 | ("n" . elpher-next-link) | ||
622 | ("p" . elpher-prev-link) | ||
623 | ("o" . elpher-follow-current-link) | ||
624 | ("G" . elpher-go-current)) | ||
625 | :init | ||
626 | (defun acdw/setup-elpher () | ||
627 | (variable-pitch-mode) | ||
628 | (set-fill-column 100) | ||
629 | (visual-fill-column-mode)) | ||
630 | :hook (elpher-mode-hook . acdw/setup-elpher)) | ||
631 | |||
632 | (use-package gemini-mode | ||
633 | :straight (gemini-mode | ||
634 | :repo "https://git.carcosa.net/jmcbray/gemini.el.git") | ||
635 | :init | ||
636 | (defun acdw/setup-gemini-mode () | ||
637 | (set-fill-column 100) | ||
638 | (visual-fill-column-mode)) | ||
639 | :hook (gemini-mode-hook . acdw/setup-gemini-mode)) | ||
640 | |||
641 | (use-package gemini-write | ||
642 | :straight (gemini-write | ||
643 | :repo "https://alexschroeder.ch/cgit/gemini-write")) | ||
644 | |||
645 | ;;;; org-mode | ||
646 | (use-package org | ||
647 | :custom | ||
648 | (org-startup-indented t) | ||
649 | (org-src-tab-acts-natively t) | ||
650 | (org-hide-emphasis-markers t) | ||
651 | (org-fontify-done-headline t) | ||
652 | (org-hide-leading-stars t) | ||
653 | (org-pretty-entities t) | ||
654 | :config | ||
655 | (font-lock-add-keywords 'org-mode | ||
656 | '(("^ *\\([-+*]\\) " | ||
657 | (0 (prog1 () (compose-region (match-beginning 1) | ||
658 | (match-end 1) | ||
659 | "•")))))) | ||
660 | :hook | ||
661 | (org-mode-hook . variable-pitch-mode)) | ||
662 | |||
663 | (use-package org-bullets | ||
664 | :hook | ||
665 | (org-mode-hook . org-bullets-mode)) | ||
666 | |||
667 | ;;;; SLIME -- for LISP | ||
668 | (use-package slime | ||
669 | :custom | ||
670 | (inferior-lisp-program (cond ((executable-find "sbcl") | ||
671 | (executable-find "sbcl"))))) | ||
672 | |||
673 | ;;;; Lua | ||
674 | (use-package lua-mode | ||
675 | :mode "\\.lua\\'" | ||
676 | :interpreter "lua") | ||
677 | |||
678 | ;;;; Fennel | ||
679 | (use-package fennel-mode | ||
680 | :mode "\\.fnl\\'") | ||
681 | |||
682 | ;;;; Web-mode | ||
683 | (use-package web-mode | ||
684 | :custom | ||
685 | (web-mode-markup-indent-offset 2) | ||
686 | (web-mode-code-indent-offset 2) | ||
687 | (web-mode-css-indent-offset 2) | ||
688 | :mode (("\\.ts\\'" . web-mode) | ||
689 | ("\\.html?\\'" . web-mode) | ||
690 | ("\\.css?\\'" . web-mode) | ||
691 | ("\\.js\\'" . web-mode)) | ||
692 | :init | ||
693 | (defun acdw/setup-web-mode () | ||
694 | (set (make-local-variable 'company-backends | ||
695 | '(company-css | ||
696 | company-web-html | ||
697 | company-files)))) | ||
698 | :hook | ||
699 | (web-mode-hook . acdw/setup-web-mode)) | ||
700 | |||
701 | (use-package emmet-mode | ||
702 | :init | ||
703 | (defun acdw/setup-emmet-in-web-mode () | ||
704 | (let ((web-mode-cur-language | ||
705 | (web-mode-language-at-pos))) | ||
706 | (if (string= web-mode-cur-language "css") | ||
707 | (setq emmet-use-css-transform t) | ||
708 | (setq emmet-use-css-transform nil)))) | ||
709 | :hook | ||
710 | (web-mode-hook . emmet-mode) | ||
711 | (web-mode-before-auto-complete-hooks . acdw/setup-emmet-in-web-mode)) | ||
712 | |||
713 | (provide 'init) | ||
714 | ;;; init.el ends here | ||