diff options
-rw-r--r-- | config.org | 1496 | ||||
-rw-r--r-- | var/elpher-bookmarks.el | 3 |
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 | ||
10 | I 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 | ||
14 | Copyright © 2020 Case Duckworth <acdw@acdw.net> | 17 | Copyright © 2020 Case Duckworth <acdw@acdw.net> |
15 | This work is free. You can redistribute it and/or modify it under the | 18 | |
16 | terms of the Do What The Fuck You Want To Public License, Version 2, | 19 | This 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. |
17 | as 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 | 40 | It'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 | ||
38 | Probably that's not legal under the terms of the GPL or whatever Emacs is licensed under. | 42 | *SUE ME, RMS!* |
39 | SUE 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 | ||
45 | When 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 |
63 | After 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 |
91 | Emacs 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 |
94 | Of 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 |
102 | I 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 |
122 | I 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 |
141 | Yeah, 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 | ||
153 | I 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 | ||
155 | Either 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) | 192 | I'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) |
170 | I 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 | 229 | I 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 | ||
320 | This 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 | ||
333 | I 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 '("^$")) | 296 | See [[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)) |
349 | I'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 |
374 | These 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 | ||
411 | I 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 | |||
604 | I'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 | |||
720 | from [[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 | |||
765 | from [[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/")) |