summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--README.md1378
-rw-r--r--config.org10
2 files changed, 833 insertions, 555 deletions
diff --git a/README.md b/README.md index 608d9f8..6d64472 100644 --- a/README.md +++ b/README.md
@@ -1,809 +1,1077 @@
1This is my Emacs configuration. It's also a literate `org-mode` file. Yeah, I'm a cool guy.
1 2
2 3
3# Preamble 4# About me
4 5
5I wanted to write my Emacs configuration in [Org mode](https://orgmode.org) for a while, but never could quite figure out how. Finally, I found [Lars Tveito](https://github.com/larstvei/dot-emacs)'s config, which does exactly what I want: `init.el` is small and simple, and replaced after the first run, and `init.org` is automatically tangled. So I'm very excited. 6 ;; init.el -*- lexical-binding: t -*-
7 (setq user-full-name "Case Duckworth"
8 user-mail-address "acdw@acdw.net")
6 9
7 10
8# License 11# License
9 12
10WTFPL. For more info, see `LICENSE`. 13Copyright © 2020 Case Duckworth <acdw@acdw.net>
11 14
12Probably that's not legal under the terms of the GPL or whatever Emacs is licensed under. 15This work is free. You can redistribute it and/or modify it under the terms of the Do What the Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See the `LICENSE` file, tangled from the following source block, for details.
13SUE ME, RMS 16
17 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
18
19 Version 2, December 2004
20
21 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
22
23 Everyone is permitted to copy and distribute verbatim or modified copies of
24 this license document, and changing it is allowed as long as the name is changed.
25
26 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
27
28 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
29
30 0. You just DO WHAT THE FUCK YOU WANT TO.
31
32
33## Note on the license
34
35It's highly likely that the WTFPL is completely incompatible with the GPL, for what should be fairly obvious reasons. To that, I say:
36
37**SUE ME, RMS!**
14 38
15 39
16# Bootstrap 40# Bootstrap
17 41
18*Check out Lars's config for the reasoning behind this.*
19 42
20When this configuration is loaded for the first time, this `init.el` is loaded: 43## Original init.el
21 44
22 ;; This file replaces itself with the actual configuration when first run. To keep only this version in git, run this command: 45 ;; This file replaces itself with the actual configuration when
23 ;; git update-index --assume-unchanged init.el 46 ;; first run. To keep only this version in git, run this command:
24 ;; 47 ;;
25 ;; If it needs to be changed, start tracking it again thusly: 48 ;; git update-index --assume-unchanged init.el
26 ;; git update-index --no-assume-unchanged init.el 49 ;;
27 50 ;; If it needs to be changed, start tracking it again thusly:
28 (require 'org) 51 ;;
29 (find-file (concat user-emacs-directory "init.org")) 52 ;; git update-index --no-assume-unchanged init.el
30 (org-babel-tangle) 53
31 (load-file (concat user-emacs-directory "early-init.el")) 54 (require 'org)
32 (load-file (concat user-emacs-directory "init.el")) 55 (find-file (concat user-emacs-directory "config.org"))
33 (byte-compile-file (concat user-emacs-directory "init.el")) 56 (org-babel-tangle)
57 (load-file (concat user-emacs-directory "early-init.el"))
58 (load-file (concat user-emacs-directory "init.el"))
59 (byte-compile-file (concat user-emacs-directory "init.el"))
34 60
35 61
36## Tangling 62## Tangling
37 63
38After the first run, the above `init.el` will be replaced by the tangled stuff here. However, when *this* file is edited, we'll need to re-tangle everything. However, nobody has time to do that manually with `C-c C-v t`, *every time*! Luckily, Emacs is highly programmable. 64 (defun acdw/tangle-init ()
65 "If the current buffer is `config.org', tangle it, then compile
66 and load the resulting files."
67 (when (equal (buffer-file-name)
68 (expand-file-name
69 (concat user-emacs-directory "config.org")))
70 (require 'async)
71 (async-start
72 (lambda ()
73 (let ((prog-mode-hook nil))
74 (require 'org)
75 (org-babel-tangle-file
76 (expand-file-name
77 (concat user-emacs-directory "config.org")))))
78 (lambda (response)
79 (acdw/load-init)
80 (message "Tangled and loaded: %s" response)))))
81
82 (add-hook 'after-save-hook #'acdw/tangle-init)
83
84 (defun acdw/load-init ()
85 (interactive)
86 (load-file (expand-file-name
87 (concat user-emacs-directory "early-init.el")))
88 (load-file (expand-file-name
89 (concat user-emacs-directory "init.el"))))
90
91
92## Miscellaneous bootstrappy stuff
93
39 94
40 (defun acdw/tangle-init () 95### Add `~/.emacs.d/lisp/` to `load-path`
41 "If the current buffer is `init.org', the code blocks are tangled, 96
42 and the tangled file is compiled and loaded." 97 (add-to-list 'load-path
43 (interactive) 98 (concat user-emacs-directory
44 (when (equal (buffer-file-name) 99 (convert-standard-filename "lisp/")))
45 (expand-file-name (concat user-emacs-directory "config.org"))) 100
46 ;; Avoid running hooks when tangling. 101
47 (let ((prog-mode-hook nil)) 102### Require my secrets
48 (org-babel-tangle)))) 103
49 104 (require 'acdw-secrets)
50 (add-hook 'after-save-hook #'acdw/tangle-init)
51 105
52 106
53# Early initiation 107# Early initiation
54 108
55Emacs 27.1+ uses `early-init.el`, which is evaluated before things like `package.el` and other stuff. So I have a few settings in there. 109 ;; early-init.el -*- lexical-binding: t; no-byte-compile: t -*-
56 110
111 (setq load-prefer-newer t)
57 112
58## Preamble
59 113
60Of course, first thing is the modeline. After that, I set `load-prefer-newer` because, well, it *should*. 114## Increase the garbage collector
61 115
62 ;;; early-init.el -*- lexical-binding: t; no-byte-compile: t -*- 116 (setq gc-cons-threshold (* 100 100 1000))
63
64 (setq load-prefer-newer t)
65 117
118 (add-hook 'after-init-hook
119 (lambda ()
120 (setq gc-cons-threshold (* 100 100 100))
121 (message "gc-cons-threshold restored to %S"
122 gc-cons-threshold)))
66 123
67## Computers
68 124
69I have to set these constants before bootstrapping the package manager, since `straight.el` depends on Git, and at work, those are in a weird place. 125## Add more paths to the `exec-path` when using Windows
70 126
71 (defconst *acdw/at-work* (eq system-type 'windows-nt)) 127 (when (eq system-type 'windows-nt)
72 (defconst *acdw/at-larry* (string= (system-name) "larry")) 128 (dolist (path '("~/bin"
73 (defconst *acdw/at-bax* (string= (system-name) "bax")) 129 "C:/Users/aduckworth/Downloads/PortableGit/bin"
74 (defconst *acdw/at-home* (or *acdw/at-larry* *acdw/at-bax*)) 130 "C:/Users/aduckworth/Downloads/PortableGit/usr/bin"))
131 (add-to-list 'exec-path path)))
75 132
76 133
77## Package management 134## Bootstrap `straight.el`
78 135
79I've started using straight.el, which is great. It grabs packages from git, and apparently will let me fork and edit them, which I'll probably get around to &#x2026; eventually. 136 (defvar bootstrap-version)
137 (let ((bootstrap-file
138 (expand-file-name "straight/repos/straight.el/bootstrap.el"
139 user-emacs-directory))
140 (bootstrap-version 5))
141 (unless (file-exists-p bootstrap-file)
142 (with-current-buffer
143 (url-retrieve-synchronously
144 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
145 'silent 'inhibit-cookies)
146 (goto-char (point-max))
147 (eval-print-last-sexp)))
148 (load bootstrap-file nil 'nomessage))
80 149
81 150
82### At work, Git's in a weird place 151## Use `use-package`
83 152
84 (when *acdw/at-work* 153 (setq straight-use-package-by-default t)
85 (add-to-list 'exec-path "~/bin") 154 (straight-use-package 'use-package)
86 (add-to-list 'exec-path "C:/Users/aduckworth/Downloads/PortableGit/bin"))
87 155
88 156
89### [straight.el](https://github.com/raxod502/straight.el) 157## Keep `~/.emacs.d` tidy
90 158
91I don't know why, but for some reason the bootstrapping doesn't work on Windows. I have to download the repo directly from github and put it in the right place (`~/.emacs.d/straight/repos/straight.el/`). 159 (straight-use-package 'no-littering)
160 (require 'no-littering)
92 161
93 (defvar bootstrap-version)
94 (let ((bootstrap-file
95 (expand-file-name "straight/repos/straight.el/bootstrap.el"
96 user-emacs-directory))
97 (bootstrap-version 5))
98 (unless (file-exists-p bootstrap-file)
99 (with-current-buffer
100 (url-retrieve-synchronously
101 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
102 'silent 'inhibit-cookies)
103 (goto-char (point-max))
104 (eval-print-last-sexp)))
105 (load bootstrap-file nil 'nomessage))
106 162
163## Additional `use-package` keywords
107 164
108### [use-package](https://github.com/jwiegley/use-package)
109 165
110Yeah, you know it, I know it, we all love it. It's use-package. 166### `:custom-update`
111 167
112 (setq straight-use-package-by-default t) 168 (use-package use-package-custom-update
113 (straight-use-package 'use-package) 169 :straight (use-package-custom-update
170 :host github
171 :repo "a13/use-package-custom-update"))
114 172
115 173
116# Begin init.el 174## Setup async
117 175
118 ;;; init.el -*- lexical-binding: t; coding: utf-8 -*- 176 (straight-use-package 'async)
119 <<tangle-on-save>> 177 (require 'async)
120 178
121 179
122# Macros 180# Macros
123 181
124 182
125## cuss 183## Customizing variables
126 184
127I like `use-package`, but I don't like doing the weird "pseudo-package" stuff a lot of people do in their emacs configs. Partially because I have to set `:straight nil` on a lot of built-in packages, but also because I think being *that* obsessive over one interface through the whole config is &#x2026; I don't know, short-sighted? 185 (defmacro cuss (var val)
186 "Basically `use-package''s `:custom', but without using either."
187 `(progn
188 (funcall (or (get ',var 'custom-set) #'set-default)
189 ',var ,val)))
128 190
129Either way, I *do* like the `:custom` interface that `use-package` has, so I've re-implemented it in my own macro. This way I don't have to worry about whether to `setq` or `custom-set-variable` or whatever. Just `cuss`!
130 191
131 (defmacro cuss (var val) 192# Theme
132 "Basically `use-package''s `:custom', but without either."
133 `(progn
134 (funcall (or (get ',var 'custom-set) #'set-default)
135 ',var ,val)))
136 193
194I'm using the [Modus](https://protesilaos.com/modus-themes/) themes.
137 195
138# Files 196 (defmacro modus-themes-format-sexp (sexp &rest objects)
197 `(eval (read (format ,(format "%S" sexp) ,@objects))))
139 198
199 (dolist (theme '("operandi" "vivendi"))
200 (modus-themes-format-sexp
201 (use-package modus-%1$s-theme
202 :init
203 (setq modus-%1$s-theme-slanted-constructs t
204 modus-%1$s-theme-bold-constructs t
205 modus-%1$s-theme-fringes 'subtle
206 modus-%1$s-theme-mode-line '3d
207 modus-%1$s-theme-syntax 'yellow-comments
208 modus-%1$s-theme-intense-hl-line nil
209 modus-%1$s-theme-intense-paren-match t
210 modus-%1$s-theme-links nil
211 modus-%1$s-theme-no-mixed-fonts nil
212 modus-%1$s-theme-prompts nil
213 modus-%1$s-theme-completions nil
214 modus-%1$s-theme-diffs nil
215 modus-%1$s-theme-org-blocks 'grayscale
216 modus-%1$s-theme-headings
217 '((1 . section)
218 (2 . line)
219 (t . rainbow-line-no-bold))
220 modus-%1$s-theme-variable-pitch-headings nil
221 modus-%1$s-theme-scale-headings t
222 modus-%1$s-theme-scale-1 1.1
223 modus-%1$s-theme-scale-2 1.15
224 modus-%1$s-theme-scale-3 1.21
225 modus-%1$s-theme-scale-4 1.27
226 modus-%1$s-theme-scale-5 1.33))
227 theme))
140 228
141## [Keep .emacs.d tidy](https://github.com/emacscollective/no-littering) 229I also want to switch themes between night and day.
142 230
143 (straight-use-package 'no-littering) 231 (use-package theme-changer
144 (require 'no-littering) 232 :custom
233 (calendar-latitude 30.39)
234 (calendar-longitude -91.83)
235 :config
236 (change-theme 'modus-operandi 'modus-vivendi))
145 237
146 238
147## Customize 239# Simplify GUI
148 240
149I don't like the customize interface, but I still sometimes use it when I'm not sure what the name of a variable is. So I save the stuff to a file, I just don't load it or keep track of it.
150 241
151 (cuss custom-file (no-littering-expand-etc-file-name "custom.el")) 242## Remove unneeded GUI elements
152 243
244 (menu-bar-mode -1)
245 (tool-bar-mode -1)
246 (scroll-bar-mode -1)
247 (horizontal-scroll-bar-mode -1)
153 248
154## Encoding
155 249
156 (prefer-coding-system 'utf-8-unix) 250## Word wrap and operate visually
157 (set-default-coding-systems 'utf-8-unix)
158 (set-terminal-coding-system 'utf-8-unix)
159 (set-keyboard-coding-system 'utf-8-unix)
160 (set-selection-coding-system 'utf-8-unix)
161 (set-file-name-coding-system 'utf-8-unix)
162 (set-clipboard-coding-system 'utf-8-unix)
163 (set-buffer-file-coding-system 'utf-8-unix)
164 (cuss locale-coding-system 'utf-8)
165 (cuss x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
166 251
252 (global-visual-line-mode 1)
167 253
168## Recent files
169 254
170 (use-package recentf 255## Modeline
171 :config
172 (add-to-list 'recentf-exclude no-littering-var-directory)
173 (add-to-list 'recentf-exclude no-littering-etc-directory)
174 :custom
175 (recentf-max-menu-items 100)
176 (recentf-max-saved-items 100)
177 :config
178 (recentf-mode 1))
179 256
257 (use-package smart-mode-line
258 :custom
259 (sml/no-confirm-load-theme t)
260 :config
261 (sml/setup))
180 262
181## Backups 263 (defun rm/whitelist-add (regexp)
264 "Add a REGEXP to the whitelist for `rich-minority'."
265 (if (listp 'rm--whitelist-regexps)
266 (add-to-list 'rm--whitelist-regexps regexp)
267 (setq rm--whitelist-regexps `(,regexp)))
268 (setq rm-whitelist
269 (mapconcat 'identity rm--whitelist-regexps "\\|")))
182 270
183 (cuss backup-directory-alist 271 (use-package rich-minority
184 `((".*" . ,(no-littering-expand-var-file-name "backup/")))) 272 :config
273 (rm/whitelist-add "^$"))
185 274
186 275
187## [Autosave](https://github.com/bbatsov/super-save) 276## Show `^L` as a line
188 277
189 (use-package super-save 278 (use-package form-feed
190 :custom 279 :hook
191 (auto-save-default nil) 280 ((text-mode prog-mode) . form-feed-mode))
192 (super-save-exclude '(".gpg"))
193 :config
194 (super-save-mode 1))
195 281
196 282
197## [Save places](https://www.emacswiki.org/emacs/SavePlace) 283## Cursor
198 284
199 (use-package saveplace 285 (cuss cursor-type 'bar)
200 :custom 286 (cuss cursor-in-non-selected-windows 'hollow)
201 (save-place-file (no-littering-expand-var-file-name "places"))
202 (save-place-forget-unreadable-files (not *acdw/at-work*))
203 :config
204 (save-place-mode 1))
205 287
206 288
207## [Save history](https://www.emacswiki.org/emacs/SaveHist) 289# Fonts
208 290
209 (use-package savehist 291See [this StackExchange question and answer](https://emacs.stackexchange.com/questions/12351/when-to-call-find-font-if-launching-emacs-in-daemon-mode) for more information on why I have these font settings applied in a hook.
210 :custom
211 (savehist-addtional-variables
212 '(kill-ring
213 search-ring
214 regexp-search-ring))
215 (savehist-save-minibuffer-history t)
216 :config
217 (savehist-mode 1))
218 292
293 (require 'cl)
294 (defun font-candidate (&rest fonts)
295 (loop for font in fonts
296 when (find-font (font-spec :name font))
297 return font))
219 298
220# User interface 299 (defun acdw/setup-fonts ()
300 "Setup fonts. This has to happen after the frame is set up for
301 the first time, so add it to `focus-in-hook'. It removes
302 itself."
303 (interactive)
304 (set-face-attribute 'default nil
305 :font
306 (font-candidate
307 "Libertinus Mono-11"
308 "Linux Libertine Mono O-11"
309 "Go Mono-11"
310 "Consolas-11"))
221 311
312 (set-face-attribute 'fixed-pitch nil
313 :font
314 (font-candidate
315 "Libertinus Mono-11"
316 "Linux Libertine Mono O-11"
317 "Go Mono-11"
318 "Consolas-11"))
222 319
223## Look 320 (set-face-attribute 'variable-pitch nil
321 :font
322 (font-candidate
323 "Libertinus Serif-14"
324 "Linux Libertine O-12"
325 "Georgia-11"))
224 326
327 (remove-hook 'focus-in-hook #'acdw/setup-fonts))
225 328
226### Frames and windows 329 (add-hook 'focus-in-hook #'acdw/setup-fonts)
227 330
2281. Frame defaults
229 331
230 (cuss default-frame-alist '((tool-bar-lines . 0) 332## Unicode
231 (menu-bar-lines . 0)
232 (vertical-scroll-bars . nil)
233 (horizontal-scroll-bars . nil)
234 (right-divider-width . 2)
235 (bottom-divider-width . 2)
236 (left-fringe-width . 2)
237 (right-fringe-width . 2)))
238
239 ;; also disable these with modes, so I can re-enable them more easily
240 (menu-bar-mode -1)
241 (tool-bar-mode -1)
242 (scroll-bar-mode -1)
243 333
2442. Resizing 334 (use-package unicode-fonts
335 :config
336 (unicode-fonts-setup))
245 337
246 (cuss frame-resize-pixelwise t)
247 (cuss window-combination-resize t)
248 338
339## Variable pitch faces
249 340
250### Buffers 341 (add-hook 'text-mode-hook #'variable-pitch-mode)
251 342
252 (cuss uniquify-buffer-name-style 'forward)
253
254 (cuss indicate-buffer-boundaries
255 '((top . right)
256 (bottom . right)
257 (t . nil)))
258 343
2591. Startup buffer 344# Ease of use
260 345
261 (cuss inhibit-startup-buffer-menu t)
262 (cuss inhibit-startup-screen t)
263 (cuss initial-buffer-choice t) ; start in *scratch*
264 (cuss initial-scratch-message nil)
265 346
347## Selectrum & Prescient
266 348
267### Cursor 349 (use-package selectrum
350 :config
351 (selectrum-mode 1))
268 352
269 (cuss cursor-type 'bar) 353 (use-package prescient
270 (cuss cursor-in-non-selected-windows 'hollow) 354 :config
271 (blink-cursor-mode 0) 355 (prescient-persist-mode 1))
272 356
357 (use-package selectrum-prescient
358 :after (selectrum prescient)
359 :config
360 (selectrum-prescient-mode 1))
273 361
274### Interactivity
275 362
2761. Mouse 363## CtrlF
277 364
278 (cuss mouse-yank-at-point t) 365 (use-package ctrlf
366 :custom
367 (ctrlf-show-match-count-at-eol nil)
368 :bind
369 ("C-s" . ctrlf-forward-regexp)
370 ("C-r" . ctrlf-backward-regexp)
371 ("C-M-s" . ctrlf-forward-literal)
372 ("C-M-r" . ctrlf-backward-literal)
373 :config
374 (ctrlf-mode 1))
279 375
2802. Dialogs
281 376
282 (cuss use-dialog-box nil) 377## Startup
283 378
2843. Disabled functions 379 (cuss inhibit-startup-buffer-menu t)
380 (cuss inhibit-startup-screen t)
381 (cuss initial-buffer-choice t)
382 (cuss initial-scratch-message ";; Hi there!\n")
285 383
286 (cuss disabled-command-function nil)
287 384
2884. Function aliases 385## Ignore case
289 386
290 (fset 'yes-or-no-p #'y-or-n-p) 387 (cuss completion-ignore-case t)
388 (cuss read-buffer-completion-ignore-case t)
389 (cuss read-file-name-completion-ignore-case t)
291 390
292 391
293### Miscellaneous 392## Which key
294 393
2951. Convert `^L` to a line 394 (use-package which-key
395 :custom
396 (which-key-popup-type 'minibuffer)
397 :config
398 (which-key-mode))
296 399
297 (use-package page-break-lines
298 :config
299 (global-page-break-lines-mode 1))
300 400
401## Miscellaneous settings
301 402
302## Themes: [Modus](https://github.com/protesilaos/modus-themes)
303 403
304 (use-package modus-operandi-theme) 404### Set view mode when in a read-only file
305 (use-package modus-vivendi-theme)
306 405
406 (cuss view-read-only t)
307 407
308### [Change themes](https://github.com/hadronzoo/theme-changer) based on time of day
309 408
310 (use-package theme-changer 409### Don't use dialog boxen
311 :init
312 (setq calendar-location-name "Baton Rouge, LA"
313 calendar-latitude 30.39
314 calendar-longitude -91.83)
315 :config
316 (change-theme 'modus-operandi 'modus-vivendi))
317 410
411 (cuss use-dialog-box nil)
318 412
319### Disable the current theme when a theme is interactively loaded
320 413
321This doesn't happen often, but I'll be ready when it does. 414### Enable all functions
322 415
323 (defadvice load-theme 416 (cuss disabled-command-function nil)
324 (before disable-before-load (theme &optional no-confirm no-enable) activate)
325 (mapc 'disable-theme custom-enabled-themes))
326 417
327 418
328## Modeline: [smart-mode-line](https://github.com/Malabarba/smart-mode-line) 419### Shorter confirmations
329 420
330 (use-package smart-mode-line 421 (fset 'yes-or-no-p #'y-or-n-p)
331 :config
332 (sml/setup))
333 422
334I hide all minor-modes by default for a clean modeline. However, I can add them back by adding them to the whitelist with `(add-to-list 'rm-whitelist " REGEX")`.
335 423
336 (defun rm-whitelist-add (regexp) 424### Uniquify buffer names
337 "Add a regexp to the whitelist."
338 (setq rm-whitelist
339 (mapconcat 'identity rm--whitelist-regexps "\\|")))
340
341 (setq rm--whitelist-regexps '("^$"))
342
343 (use-package rich-minority
344 :custom
345 (rm-whitelist
346 (mapconcat 'identity rm--whitelist-regexps "\\|")))
347 425
426 (require 'uniquify)
427 (cuss uniquify-buffer-name-style 'forward)
348 428
349## Fonts
350 429
351I'm sure there's a better way to do this, but for now, this is the best I've got. I append to the `face-font-family-alternatives` because I don't know what kind of weird magic they're doing in there. 430### Show buffer boundaries
352 431
353 (cuss face-font-family-alternatives 432 (cuss indicate-buffer-boundaries
354 '(("Monospace" "courier" "fixed") 433 '((top . right)
355 ("Monospace Serif" "Courier 10 Pitch" "Consolas" "Courier Std" "FreeMono" "Nimbus Mono L" "courier" "fixed") 434 (bottom . right)
356 ("courier" "CMU Typewriter Text" "fixed") 435 (t . nil)))
357 ("Sans Serif" "helv" "helvetica" "arial" "fixed")
358 ("helv" "helvetica" "arial" "fixed")
359 ;; now mine
360 ("FixedPitch" "Go Mono" "DejaVu Sans Mono" "Consolas" "fixed")
361 ("VariablePitch" "Go" "DejaVu Sans" "Georgia" "fixed")))
362
363 (set-face-attribute 'default nil
364 :family "FixedPitch"
365 :height 110)
366
367 (set-face-attribute 'fixed-pitch nil
368 :family "FixedPitch"
369 :height 110)
370
371 (set-face-attribute 'variable-pitch nil
372 :family "VariablePitch"
373 :height 130)
374 436
375 437
376### Ligatures 438### Hippie expand
377 439
378These cause big problems with cc-mode (as in, totally freezing everything), so I'm going to comment it out. 440 (global-set-key (kbd "M-/") 'hippie-expand)
379 441
380 ;; (use-package ligature
381 ;; :straight (ligature
382 ;; :host github
383 ;; :repo "mickeynp/ligature.el")
384 ;; :config
385 ;; (ligature-set-ligatures 'prog-mode
386 ;; '("++" "--" "/=" "&&" "||" "||="
387 ;; "->" "=>" "::" "__"
388 ;; "==" "===" "!=" "=/=" "!=="
389 ;; "<=" ">=" "<=>"
390 ;; "/*" "*/" "//" "///"
391 ;; "\\n" "\\\\"
392 ;; "<<" "<<<" "<<=" ">>" ">>>" ">>="
393 ;; "|=" "^="
394 ;; "**" "--" "---" "----" "-----"
395 ;; "==" "===" "====" "====="
396 ;; "</" "<!--" "</>" "-->" "/>"
397 ;; ":=" "..." ":>" ":<" ">:" "<:"
398 ;; "::=" ;; add others here
399 ;; ))
400 ;; :config
401 ;; (global-ligature-mode))
402 442
443### iBuffer
403 444
404### [Unicode fonts](https://github.com/rolandwalker/unicode-fonts) 445 (global-set-key (kbd "C-x C-b") 'ibuffer)
405 446
406 (use-package persistent-soft)
407
408 (use-package unicode-fonts
409 :after persistent-soft
410 :config
411 (unicode-fonts-setup))
412 447
448### Zap-up-to-char, not zap-to-char
413 449
414# Editing 450 (autoload 'zap-up-to-char "misc"
451 "Kill up to, but not including, ARGth occurrence of CHAR." t)
415 452
453 (global-set-key (kbd "M-z") 'zap-up-to-char)
416 454
417## Completion
418 455
419I was using company, but I think it might've been causing issues with `awk-mode`, so I'm trying `hippie-mode` right now. So far, I'm also enjoying not having a popup all the time. 456### Other "[better defaults](https://git.sr.ht/~technomancy/better-defaults/tree/master/better-defaults.el)"
420 457
421 (bind-key "M-/" #'hippie-expand) 458 (cuss save-interprogram-paste-before-kill t)
459 (cuss apropos-do-all t)
460 (cuss mouse-yank-at-point t)
461 (cuss require-final-newline t)
462 (cuss visible-bell (not (string= (system-name) "larry")))
463 (cuss ediff-window-setup-function #'ediff-setup-windows-plain)
422 464
423 465
424## Ignore case 466### So-long-mode
425 467
426 (cuss completion-ignore-case t) 468 (if (boundp 'global-so-long-mode)
427 (cuss read-buffer-completion-ignore-case t) 469 (global-so-long-mode))
428 (cuss read-file-name-completion-ignore-case t)
429 470
430 471
431## Selection & Minibuffer 472### Change `just-one-space` to `cycle-space`
432 473
474 (defun acdw/cycle-spacing-1 ()
475 (interactive)
476 (cycle-spacing -1))
433 477
434### Selectrum & Prescient 478 (bind-key [remap just-one-space] #'acdw/cycle-spacing-1)
435 479
436 (use-package selectrum
437 :config
438 (selectrum-mode +1))
439
440 (use-package prescient
441 :config
442 (prescient-persist-mode +1))
443
444 (use-package selectrum-prescient
445 :after (selectrum prescient)
446 :config
447 (selectrum-prescient-mode +1))
448 480
481# Persistence
449 482
450## Search
451 483
484## Auto-saves
452 485
453### CtrlF for searching 486 (use-package super-save
487 :custom
488 (auto-save-default nil)
489 (super-save-exclue '(".gpg"))
490 :config
491 (super-save-mode 1))
454 492
455 (use-package ctrlf
456 :custom
457 (ctrlf-show-match-count-at-eol nil)
458 :config
459 (ctrlf-mode +1)
460 :bind
461 ("C-s" . ctrlf-forward-regexp))
462 493
494## Backup files
495
496 (cuss backup-directory-alist
497 `((".*" . ,(no-littering-expand-var-file-name "backup/"))))
498
499 (cuss backup-by-copying 1)
500 (cuss delete-old-versions -1)
501 (cuss version-control t)
502 (cuss vc-make-backup-files t)
503
504
505## Recent files
506
507 (use-package recentf
508 :custom-update
509 (recentf-exclude
510 '(no-littering-var-directory
511 no-littering-etc-directory))
512 :custom
513 (recentf-max-menu-items 100)
514 (recentf-max-saved-items 100)
515 :config
516 (recentf-mode 1))
517
518
519### Easily navigate recent files
520
521 (defun recentf-find-file ()
522 "Find a recent file using `completing-read'."
523 (interactive)
524 (let ((file (completing-read "Recent file: " recentf-list nil t)))
525 (when file
526 (find-file file))))
527
528 (bind-key "C-x C-r" #'recentf-find-file)
529
530
531## Save places in visited files
532
533 (use-package saveplace
534 :custom
535 (save-place-file (no-littering-expand-var-file-name "places"))
536 (save-place-forget-unreadable-files (not
537 (eq system-type 'windows-nt))
538 :config
539 (save-place-mode 1)))
463 540
464### [Visual Regexp](https://github.com/benma/visual-regexp.el)
465 541
466 (use-package visual-regexp 542## Save history
467 :bind 543
468 ([remap query-replace] . 'vr/query-replace)) 544 (use-package savehist
545 :custom
546 (savehist-additional-variables
547 '(kill-ring
548 search-ring
549 regexp-search-ring))
550 (savehist-save-minibuffer-history t)
551 (history-length t)
552 (history-delete-duplicates t)
553 :config
554 (savehist-mode 1))
469 555
470 556
471## Undo 557## Undo
472 558
473 (use-package undo-fu 559 (use-package undo-fu-session
474 :bind 560 :after (no-littering undo-fu)
475 ("C-/" . undo-fu-only-undo) 561 :custom
476 ("C-?" . undo-fu-only-redo)) 562 (undo-fu-session-incompatible-files
477 563 '("COMMIT_EDITMSG\\'"
478 (use-package undo-fu-session 564 "/git-rebase-todo\\'"))
479 :after no-littering 565 (undo-fu-session-directory
480 :custom 566 (no-littering-expand-var-file-name "undos/"))
481 (undo-fu-session-incompatible-files 567 :config
482 '("/COMMIT_EDITMSG\\'" 568 (global-undo-fu-session-mode 1))
483 "/git-rebase-todo\\'"))
484 (undo-fu-session-directory
485 (no-littering-expand-var-file-name "undos/"))
486 :config
487 (global-undo-fu-session-mode +1))
488 569
489 570
490## Visual editing 571# General editing
491 572
492 573
493### `zap-to-char` replacement 574## File encoding
494 575
495 (use-package zop-to-char 576I'm going to be honest &#x2013; most of this is a stab in the dark.
496 :bind
497 ([remap zap-to-char] . zop-to-char)
498 ([remap zap-up-to-char] . zop-up-to-char))
499 577
578 (set-language-environment 'utf-8)
579 (set-terminal-coding-system 'utf-8)
580 (cuss locale-coding-system 'utf-8)
581 (set-default-coding-systems 'utf-8)
582 (set-selection-coding-system 'utf-8)
583 (prefer-coding-system 'utf-8)
500 584
501### Operate on a line if there's no current region 585 ;; from https://www.emacswiki.org/emacs/EndOfLineTips
502 586
503 (use-package whole-line-or-region 587 (defun acdw/no-junk-please-were-unixish ()
504 :config 588 "Convert line endings to UNIX, dammit."
505 (whole-line-or-region-global-mode +1)) 589 (let ((coding-str (symbol-name buffer-file-coding-system)))
590 (when (string-match "-\\(?:dos\\|mac\\)$" coding-str)
591 (set-buffer-file-coding-system 'unix))))
506 592
593 (add-hook 'find-file-hooks #'acdw/no-junk-please-were-unixish)
594
595
596## Undo
507 597
508### Expand-region 598 (use-package undo-fu
599 :bind
600 ("C-/" . undo-fu-only-undo)
601 ("C-?" . undo-fu-only-redo))
509 602
510 (use-package expand-region 603
511 :bind 604## Find/replace
512 ("C-=" . er/expand-region) 605
513 ("C-+" . er/contract-region)) 606 (use-package visual-regexp
607 :bind
608 ("C-c r" . 'vr/replace)
609 ("C-c q" . 'vr/query-replace))
610
611
612## Visual editing
514 613
515 614
516### Volatile highlights 615### Volatile highlights
517 616
518 (use-package volatile-highlights 617 (use-package volatile-highlights
519 :config 618 :config
520 (volatile-highlights-mode 1)) 619 (volatile-highlights-mode 1))
521 620
522 621
523### Visual line mode 622### Expand region
524 623
525 (global-visual-line-mode 1) 624 (use-package expand-region
625 :bind
626 ("C-=" . er/expand-region)
627 ("C-+" . er/contract-region))
526 628
527 629
528### A better `move-beginning-of-line` 630## Clean up white space on save
529 631
530 (defun my/smarter-move-beginning-of-line (arg) 632 (add-hook 'before-save-hook #'whitespace-cleanup)
531 "Move point back to indentation of beginning of line. 633 (add-hook 'before-save-hook #'delete-trailing-whitespace)
532
533 Move point to the first non-whitespace character on this line.
534 If point is already there, move to the beginning of the line.
535 Effectively toggle between the first non-whitespace character and
536 the beginning of the line.
537
538 If ARG is not nil or 1, move forward ARG - 1 lines first. If
539 point reaches the beginning or end of the buffer, stop there."
540 (interactive "^p")
541 (setq arg (or arg 1))
542
543 ;; Move lines first
544 (when (/= arg 1)
545 (let ((line-move-visual nil))
546 (forward-line (1- arg))))
547
548 (let ((orig-point (point)))
549 (back-to-indentation)
550 (when (= orig-point (point))
551 (move-beginning-of-line 1))))
552
553 (bind-key "C-a" #'my/smarter-move-beginning-of-line)
554 634
555 635
556## Delete the selection when typing 636## Automatically revert a file to what it is on disk
557 637
558 (delete-selection-mode 1) 638 (global-auto-revert-mode 1)
559 639
560 640
561## Clipboard 641# Writing
562 642
563 (cuss save-interprogram-paste-before-kill t)
564 643
644## Word count
565 645
566## Tabs & Spaces 646 (use-package wc-mode
647 :config
648 (rm/whitelist-add "WC")
649 :hook text-mode)
567 650
568 (cuss indent-tabs-mode nil)
569 (cuss sentence-end-double-space t)
570 651
652## Visual fill column mode
571 653
572# Programming 654 (use-package visual-fill-column
655 :custom
656 (split-window-preferred-function
657 'visual-fill-column-split-window-sensibly)
658 (visual-fill-column-center-text t)
659 (fill-column 80)
660 :config
661 (advice-add 'text-scale-adjust
662 :after #'visual-fill-column-adjust)
663 :hook
664 (text-mode . visual-fill-column-mode))
573 665
574 666
575## Git 667## Org mode
668
669 (use-package org
670 :custom
671 (org-startup-indented t)
672 (org-src-tab-acts-natively t)
673 (org-hide-emphasis-markers t)
674 (org-fontify-done-headline t)
675 (org-fontify-whole-heading-line t)
676 (org-hide-leading-stars t)
677 (org-hidden-keywords '(author date title))
678 (org-src-window-setup 'current-window)
679 (org-pretty-entities t))
680
681
682### Enable markdown export
683
684 (require 'ox-md)
685
686
687### Ensure blank lines between headings and before contents
688
689from [unpackaged.el](https://github.com/alphapapa/unpackaged.el#ensure-blank-lines-between-headings-and-before-contents)
690
691 ;;;###autoload
692 (defun unpackaged/org-fix-blank-lines (&optional prefix)
693 "Ensure that blank lines exist between headings and between
694 headings and their contents. With prefix, operate on whole
695 buffer. Ensures that blank lines exist after each headings's
696 drawers."
697 (interactive "P")
698 (org-map-entries
699 (lambda ()
700 (org-with-wide-buffer
701 ;; `org-map-entries' narrows the buffer, which prevents us
702 ;; from seeing newlines before the current heading, so we
703 ;; do this part widened.
704 (while (not (looking-back "\n\n" nil))
705 ;; Insert blank lines before heading.
706 (insert "\n")))
707 (let ((end (org-entry-end-position)))
708 ;; Insert blank lines before entry content.
709 (forward-line)
710 (while (and (org-at-planning-p)
711 (< (point) (point-max)))
712 ;; Skip planning lines
713 (forward-line))
714 (while (re-search-forward org-drawer-regexp end t)
715 ;; Skip drawers. You might think that
716 ;; `org-at-drawer-p' would suffice, but for some reason
717 ;; it doesn't work correctly when operating on hidden
718 ;; text. This works, taken from
719 ;; `org-agenda-get-some-entry-text'.
720 (re-search-forward "^[ \t]*:END:.*\n?" end t)
721 (goto-char (match-end 0)))
722 (unless (or (= (point) (point-max))
723 (org-at-heading-p)
724 (looking-at-p "\n"))
725 (insert "\n"))))
726 t (if prefix
727 nil
728 'tree)))
729
730
731### `org-return-dwim`
732
733from [unpackaged.el](https://github.com/alphapapa/unpackaged.el#org-return-dwim)
734
735 (defun unpackaged/org-element-descendant-of (type element)
736 "Return non-nil if ELEMENT is a descendant of TYPE.
737 TYPE should be an element type, like `item' or `paragraph'.
738 ELEMENT should be a list like that returned by
739 `org-element-context'."
740 ;; MAYBE: Use `org-element-lineage'.
741 (when-let* ((parent (org-element-property :parent element)))
742 (or (eq type (car parent))
743 (unpackaged/org-element-descendant-of type parent))))
744
745 ;;;###autoload
746 (defun unpackaged/org-return-dwim (&optional default)
747 "A helpful replacement for `org-return'. With prefix, call `org-return'.
748
749 On headings, move point to position after entry content. In
750 lists, insert a new item or end the list, with checkbox if
751 appropriate. In tables, insert a new row or end the table."
752 ;; Inspired by John Kitchin: http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/
753 (interactive "P")
754 (if default
755 (org-return)
756 (cond
757 ;; Act depending on context around point.
758
759 ;; NOTE: I prefer RET to not follow links, but by uncommenting this block,
760 ;; links will be followed.
761
762 ;; ((eq 'link (car (org-element-context)))
763 ;; ;; Link: Open it.
764 ;; (org-open-at-point-global))
765
766 ((org-at-heading-p)
767 ;; Heading: Move to position after entry content.
768 ;; NOTE: This is probably the most interesting feature of this function.
769 (let ((heading-start (org-entry-beginning-position)))
770 (goto-char (org-entry-end-position))
771 (cond ((and (org-at-heading-p)
772 (= heading-start (org-entry-beginning-position)))
773 ;; Entry ends on its heading; add newline after
774 (end-of-line)
775 (insert "\n\n"))
776 (t
777 ;; Entry ends after its heading; back up
778 (forward-line -1)
779 (end-of-line)
780 (when (org-at-heading-p)
781 ;; At the same heading
782 (forward-line)
783 (insert "\n")
784 (forward-line -1))
785 ;; FIXME: looking-back is supposed to be called with more arguments.
786 (while (not (looking-back (rx (repeat 3 (seq (optional blank) "\n")))))
787 (insert "\n"))
788 (forward-line -1)))))
789
790 ((org-at-item-checkbox-p)
791 ;; Checkbox: Insert new item with checkbox.
792 (org-insert-todo-heading nil))
793
794 ((org-in-item-p)
795 ;; Plain list. Yes, this gets a little complicated...
796 (let ((context (org-element-context)))
797 (if (or (eq 'plain-list (car context)) ; First item in list
798 (and (eq 'item (car context))
799 (not (eq (org-element-property :contents-begin context)
800 (org-element-property :contents-end context))))
801 (unpackaged/org-element-descendant-of 'item context)) ; Element in list item, e.g. a link
802 ;; Non-empty item: Add new item.
803 (org-insert-item)
804 ;; Empty item: Close the list.
805 ;; TODO: Do this with org functions rather than operating on the text. Can't seem to find the right function.
806 (delete-region (line-beginning-position) (line-end-position))
807 (insert "\n"))))
808
809 ((when (fboundp 'org-inlinetask-in-task-p)
810 (org-inlinetask-in-task-p))
811 ;; Inline task: Don't insert a new heading.
812 (org-return))
813
814 ((org-at-table-p)
815 (cond ((save-excursion
816 (beginning-of-line)
817 ;; See `org-table-next-field'.
818 (cl-loop with end = (line-end-position)
819 for cell = (org-element-table-cell-parser)
820 always (equal (org-element-property :contents-begin cell)
821 (org-element-property :contents-end cell))
822 while (re-search-forward "|" end t)))
823 ;; Empty row: end the table.
824 (delete-region (line-beginning-position) (line-end-position))
825 (org-return))
826 (t
827 ;; Non-empty row: call `org-return'.
828 (org-return))))
829 (t
830 ;; All other cases: call `org-return'.
831 (org-return)))))
832
833 (bind-key "RET" #'unpackaged/org-return-dwim 'org-mode-map)
834
835
836# Coding
837
838
839## Formatting
840
841
842### Indenting
843
844 (use-package aggressive-indent
845 :config
846 (global-aggressive-indent-mode 1))
576 847
577 (use-package magit
578 :bind
579 ("C-x g" . magit-status)
580 :config
581 (add-to-list 'magit-no-confirm 'stage-all-changes))
582
583 ;; hook into `prescient'
584 (define-advice magit-list-refs
585 (:around (orig &optional namespaces format sortby)
586 prescient-sort)
587 "Apply prescient sorting when listing refs."
588 (let ((res (funcall orig namespaces format sortby)))
589 (if (or sortby
590 magit-list-refs-sortby
591 (not selectrum-should-sort-p))
592 res
593 (prescient-sort res))))
594
595 (when (executable-find "cmake")
596 (use-package libgit)
597 (use-package magit-libgit))
598
599 (use-package forge
600 :after magit
601 :custom
602 (forge-owned-accounts '(("duckwork"))))
603 848
849### Smart tabs
850
851 (use-package smart-tabs-mode
852 :custom
853 (whitespace-style
854 '(face trailing tabs spaces lines newline
855 empty indentation space-before-tab
856 space-mark tab-mark newline-mark))
857 :config
858 (smart-tabs-insinuate 'c 'c++ 'javascript 'java 'ruby))
604 859
605## Code display
606 860
607 (add-hook 'prog-mode-hook #'prettify-symbols-mode) 861## Display
608 862
609 863
610### Parentheses 864### Prettify symbols mode
611 865
612 (cuss show-paren-style 'mixed) 866 (add-hook 'prog-mode-hook #'prettify-symbols-mode)
613 (show-paren-mode +1)
614
615 (use-package smartparens
616 :init
617 (defun acdw/setup-smartparens ()
618 (require 'smartparens-config)
619 (smartparens-mode +1))
620 :hook
621 (prog-mode . acdw/setup-smartparens))
622
623 (use-package rainbow-delimiters
624 :hook
625 (prog-mode . rainbow-delimiters-mode))
626 867
627 868
628## Line numbers 869### Parentheses and frens
629 870
630 (add-hook 'prog-mode-hook 8711. `show-paren-style`
631 (if (and (fboundp 'display-line-numbers-mode)
632 (display-graphic-p))
633 #'display-line-numbers-mode
634 #'linum-mode))
635 872
873 (cuss show-paren-style 'mixed)
874 (show-paren-mode 1)
636 875
637## Languages 8762. Smartparens
638 877
878 (use-package smartparens
879 :init
880 (defun acdw/setup-smartparens ()
881 (require 'smartparens-config)
882 (smartparens-mode 1))
883 :hook
884 (prog-mode . acdw/setup-smartparens))
639 885
640### Shell 8863. Rainbow delimiters
641 887
642 (use-package shfmt 888 (use-package rainbow-delimiters
643 :custom 889 :hook (prog-mode . rainbow-delimiters-mode))
644 (shfmt-arguments '("-i" "4" "-ci"))
645 :hook
646 (sh-mode . shfmt-on-save-mode))
647
648 ;; fish
649 (use-package fish-mode)
650 890
651 891
652### Lua 892### Rainbow mode
653 893
654 (use-package lua-mode 894 (use-package rainbow-mode
655 :mode "\\.lua\\'" 895 :custom
656 :interpreter "lua") 896 (rainbow-x-colors nil)
897 :hook prog-mode)
657 898
658 899
659### Fennel 900### Line numbers
660 901
661 (use-package fennel-mode 902 (defun acdw/enable-line-numbers ()
662 :mode "\\.fnl\\'") 903 "Enable line numbers, either through `display-line-numbers-mode'
904 or through `linum-mode'."
905 (if (and (fboundp 'display-line-numbers-mode)
906 (display-graphic-p))
907 (progn
908 (display-line-numbers-mode 1)
909 (cuss display-line-numbers-width 2))
910 (linum-mode 1)))
663 911
912 (add-hook 'prog-mode-hook #'acdw/enable-line-numbers)
664 913
665### Web
666 914
667 (use-package web-mode 915## Git
668 :custom
669 (web-mode-markup-indent-offset 2)
670 (web-mode-code-indent-offset 2)
671 (web-mode-css-indent-offset 2)
672 :mode (("\\.ts\\'" . web-mode)
673 ("\\.html?\\'" . web-mode)
674 ("\\.css?\\'" . web-mode)
675 ("\\.js\\'" . web-mode)))
676 916
917 (use-package magit
918 :bind
919 ("C-x g" . magit-status)
920 :custom-update
921 (magit-no-confirm '(stage-all-changes)))
677 922
678### SSH config
679 923
680 (use-package ssh-config-mode) 924### Hook into `prescient`
681 925
926 (define-advice magit-list-refs
927 (:around (orig &optional namespaces format sortby)
928 prescient-sort)
929 "Apply prescient sorting when listing refs."
930 (let ((res (funcall orig namespaces format sortby)))
931 (if (or sortby
932 magit-list-refs-sortby
933 (not selectrum-should-sort-p))
934 res
935 (prescient-sort res))))
682 936
683# Writing
684 937
938### Use `libgit` when I can build it (requires `cmake`)
685 939
686## Word count 940 (when (executable-find "cmake")
941 (use-package libgit)
942 (use-package magit-libgit))
687 943
688 (use-package wc-mode
689 :init
690 (rm-whitelist-add "WC")
691 :hook
692 (text-mode . wc-mode))
693 944
945### Git "forge" capabilities
694 946
695## Visual fill column 947 (use-package forge
948 :after magit
949 :unless (eq system-type 'windows-nt)
950 :custom
951 (forge-owned-accounts
952 '(("duckwork"))))
696 953
697 (use-package visual-fill-column
698 :custom
699 (split-window-preferred-function 'visual-fill-column-split-window-sensibly)
700 (visual-fill-column-center-text t)
701 (fill-column 100)
702 :config
703 (advice-add 'text-scale-adjust
704 :after #'visual-fill-column-adjust)
705 :hook
706 (org-mode . visual-fill-column-mode))
707 954
955## Programming languages
708 956
709## Mixed-pitch
710 957
711 (use-package mixed-pitch 958### Fish shell
712 :hook
713 (text-mode . mixed-pitch-mode))
714 959
960 (use-package fish-mode)
715 961
716## Org mode
717 962
718 (use-package org 963### Lisps
719 :custom
720 (org-startup-indented t)
721 (org-src-tab-acts-natively t)
722 (org-hide-emphasis-markers t)
723 (org-fontify-done-headline t)
724 (org-hide-leading-stars t)
725 (org-pretty-entities t)
726 (org-src-window-setup 'current-window))
727
728 (use-package org-superstar
729 :hook
730 (org-mode . org-superstar-mode))
731 964
9651. Common Lisp (SLIME)
732 966
733# Applications 967 (use-package slime
968 :when (executable-find "sbcl")
969 :custom
970 (inferior-lisp-program "sbcl")
971 (slime-contribs '(slime-fancy)))
734 972
9732. Fennel
974
975 (use-package fennel-mode
976 :mode "\\.fnl\\'")
977
978
979### Lua
980
981 (use-package lua-mode
982 :mode "\\.lua\\'"
983 :interpreter "lua")
735 984
736## Gemini & Gopher
737
738 (use-package elpher
739 :straight (elpher
740 :repo "git://thelambdalab.xyz/elpher.git")
741 :bind (:map elpher-mode-map
742 ("n" . elpher-next-link)
743 ("p" . elpher-prev-link)
744 ("o" . elpher-follow-current-link)
745 ("G" . elpher-go-current))
746 :hook
747 (elpher-mode . visual-fill-column-mode))
748
749 (use-package gemini-mode
750 :straight (gemini-mode
751 :repo "https://git.carcosa.net/jmcbray/gemini.el.git")
752 :mode "\\.\\(gemini|gmi\\)\\'")
753
754 (use-package gemini-write
755 :straight (gemini-write
756 :repo "https://alexschroeder.ch/cgit/gemini-write"))
757
758 (use-package post-to-gemlog-blue
759 :straight (post-to-gemlog-blue
760 :repo "https://git.sr.ht/~acdw/post-to-gemlog-blue.el"))
761
762
763## Pastebin
764
765 (use-package 0x0
766 :custom
767 (0x0-default-service 'ttm))
768 985
986### Web (HTML/CSS/JS)
769 987
770## Gnus 988 (use-package web-mode
989 :mode (("\\.ts\\'" . web-mode)
990 ("\\.html?\\'" . web-mode)
991 ("\\.css?\\'" . web-mode)
992 ("\\.js\\'" . web-mode)))
771 993
772 (cuss gnus-select-method
773 '(nnimap "imap.fastmail.com"
774 (nnimap-inbox "INBOX")
775 (nnimap-split-methods default)
776 (nnimap-expunge t)
777 (nnimap-stream ssl)))
778
779 (cuss gnus-secondary-select-methods
780 '((nntp "news.gwene.org")))
781 994
995### `~/.ssh/config`
782 996
783## Nov.el: read Ebooks 997 (use-package ssh-config-mode)
784 998
785 (use-package nov 999
786 :mode ("\\.epub\\'" . nov-mode) 1000### Go
1001
1002 (use-package go-mode
1003 :mode "\\.go\\'")
1004
1005
1006# Applications
1007
1008
1009## Elpher
1010
1011 (use-package elpher
1012 :straight (elpher
1013 :repo "git://thelambdalab.xyz/elpher.git")
1014 :custom
1015 (elpher-certificate-directory
1016 (no-littering-expand-var-file-name "elpher-certificates/"))
1017 (elpher-ipv4-always t)
1018 :custom-face
1019 (elpher-gemini-heading1
1020 ((t (:inherit (modus-theme-heading-1)))))
1021 (elpher-gemini-heading2
1022 ((t (:inherit (modus-theme-heading-2)))))
1023 (elpher-gemini-heading3
1024 ((t (:inherit (modus-theme-heading-3)))))
1025 :config
1026 (defun elpher:eww-browse-url (original url &optional new-window)
1027 "Handle gemini/gopher links with eww."
1028 (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
1029 (require 'elpher)
1030 (elpher-go url))
1031 (t (funcall original url new-window))))
1032 (advice-add 'eww-browse-url :around 'elpher:eww-browse-url)
1033 :bind (:map elpher-mode-map
1034 ("n" . elpher-next-link)
1035 ("p" . elpher-prev-link)
1036 ("o" . elpher-follow-current-link)
1037 ("G" . elpher-go-current))
1038 :hook
1039 (elpher-mode . visual-fill-column-mode))
1040
1041 (use-package gemini-mode
1042 :straight (gemini-mode
1043 :repo "https://git.carcosa.net/jmcbray/gemini.el.git")
1044 :mode "\\.\\(gemini|gmi\\)\\'"
1045 :custom-face
1046 (gemini-heading-face-1
1047 ((t (:inherit (elpher-gemini-heading1)))))
1048 (gemini-heading-face2
1049 ((t (:inherit (elpher-gemini-heading2)))))
1050 (gemini-heading-face3
1051 ((t (:inherit (elpher-gemini-heading3)))))
1052 :hook
1053 (gemini-mode . visual-fill-column-mode))
1054
1055 (use-package gemini-write
1056 :straight (gemini-write
1057 :repo "https://alexschroeder.ch/cgit/gemini-write")
1058 :config
1059 (add-to-list 'elpher-gemini-tokens
1060 (acdw-secrets/elpher-gemini-tokens)))
1061
1062 (use-package post-to-gemlog-blue
1063 :straight (post-to-gemlog-blue
1064 :repo "https://git.sr.ht/~acdw/post-to-gemlog-blue.el"))
1065
1066
1067## Pastebin (0x0)
1068
1069(use-package 0x0
787 :custom 1070 :custom
788 (nov-text-width t) 1071 (0x0-default-service 'ttm))
789 :hook 1072
790 (nov-mode . visual-line-mode) 1073
791 (nov-mode . visual-fill-column-mode)) 1074## EMMS
792
793
794# Machine-specific configurations
795
796 (cond
797 (*acdw/at-home*
798 (use-package su
799 :config
800 (su-mode 1))
801 (use-package trashed
802 :custom
803 (delete-by-moving-to-trash t))
804 (use-package exec-path-from-shell
805 :demand
806 :config
807 (exec-path-from-shell-initialize)))
808 )
809 1075
1076 (use-package bongo
1077 :commands 'bongo)
diff --git a/config.org b/config.org index 39d62ba..7b5de4e 100644 --- a/config.org +++ b/config.org
@@ -1,9 +1,13 @@
1#+TITLE:Emacs configuration, literate style 1#+TITLE:Emacs configuration, literate style
2#+AUTHOR:Case Duckworth 2#+AUTHOR:Case Duckworth
3#+PROPERTY: header-args :tangle init.el 3#+PROPERTY: header-args :tangle init.el
4#+EXPORT_FILE_NAME: README.md
4#+OPTIONS: toc:nil 5#+OPTIONS: toc:nil
6#+OPTIONS: title:t
5#+BANKRUPTCY_COUNT: 2 7#+BANKRUPTCY_COUNT: 2
6 8
9This is my Emacs configuration. It's also a literate =org-mode= file. Yeah, I'm a cool guy.
10
7* About me 11* About me
8 12
9#+begin_src emacs-lisp 13#+begin_src emacs-lisp
@@ -731,6 +735,12 @@ I'm going to be honest -- most of this is a stab in the dark.
731 (org-pretty-entities t)) 735 (org-pretty-entities t))
732#+end_src 736#+end_src
733 737
738*** Enable markdown export
739
740#+begin_src emacs-lisp
741 (require 'ox-md)
742#+end_src
743
734*** Ensure blank lines between headings and before contents 744*** Ensure blank lines between headings and before contents
735 745
736from [[https://github.com/alphapapa/unpackaged.el#ensure-blank-lines-between-headings-and-before-contents][unpackaged.el]] 746from [[https://github.com/alphapapa/unpackaged.el#ensure-blank-lines-between-headings-and-before-contents][unpackaged.el]]