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