diff options
author | Case Duckworth | 2020-10-25 12:11:41 -0500 |
---|---|---|
committer | Case Duckworth | 2020-10-25 12:11:41 -0500 |
commit | 1a29e22362bc64dc1e9e0cb23cd81e1edd4ecc76 (patch) | |
tree | af88043a2f6ab9d153283aef5e411cdd247c74ca | |
parent | End sentences with 2 spaces (diff) | |
download | emacs-1a29e22362bc64dc1e9e0cb23cd81e1edd4ecc76.tar.gz emacs-1a29e22362bc64dc1e9e0cb23cd81e1edd4ecc76.zip |
Convert to Literate Config
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | init.el | 262 | ||||
-rw-r--r-- | init.org | 587 |
3 files changed, 599 insertions, 252 deletions
diff --git a/.gitignore b/.gitignore index 993a79e..cd10faf 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -1,5 +1,5 @@ | |||
1 | * | 1 | * |
2 | !early-init.el | 2 | !init.org |
3 | !init.el | 3 | !init.el |
4 | !.gitignore | 4 | !.gitignore |
5 | !README.org | 5 | !README.org |
diff --git a/init.el b/init.el index ab596b6..52fc593 100644 --- a/init.el +++ b/init.el | |||
@@ -1,251 +1,11 @@ | |||
1 | ;;; init.el -*- lexical-binding: t; coding: utf-8; -*- | 1 | ;; This file replaces itself with the actual configuration when first run. To keep only this version in git, run this command: |
2 | 2 | ;; git update-index --assume-unchanged init.el | |
3 | ;;; Commentary: | 3 | ;; |
4 | ;; BANKRUPT_SCORE: 1 | 4 | ;; If it needs to be changed, start tracking it again thusly: |
5 | ;; ^ the number of times I've declared Emacs bankruptcy. | 5 | ;; git update-index --no-assume-unchanged init.el |
6 | ;; Does this mean I'm part of the cool kids now? | 6 | |
7 | 7 | (require 'org) | |
8 | ;;; Macros | 8 | (find-file (concat user-emacs-directory "init.org")) |
9 | (defmacro cuss (var val) | 9 | (org-babel-tangle) |
10 | "Basically `use-package' `:custom' but without either." | 10 | (load-file (concat user-emacs-directory "init.el")) |
11 | `(progn | 11 | (byte-compile-file (concat user-emacs-directory "init.el")) |
12 | (funcall (or (get ',var 'custom-set) #'set-default) | ||
13 | ',var ,val))) | ||
14 | |||
15 | ;;; Files | ||
16 | ;; keep `emacs-user-directory' tidy | ||
17 | (use-package no-littering) | ||
18 | |||
19 | ;; don't clutter `init.el' with customize crap | ||
20 | (cuss custom-file (no-littering-expand-etc-file-name "custom.el")) | ||
21 | |||
22 | ;; backups | ||
23 | (cuss backup-directory-alist | ||
24 | `((".*" . ,(no-littering-expand-var-file-name "backup/")))) | ||
25 | |||
26 | ;; recent files | ||
27 | (use-package recentf | ||
28 | :config | ||
29 | (add-to-list 'recentf-exclude no-littering-var-directory) | ||
30 | (add-to-list 'recentf-exclude no-littering-etc-directory) | ||
31 | :custom | ||
32 | (recentf-max-menu-items 100) | ||
33 | (recentf-max-saved-items 100) | ||
34 | :config | ||
35 | (recentf-mode +1)) | ||
36 | |||
37 | ;; encoding | ||
38 | (set-charset-priority 'unicode) | ||
39 | (set-language-environment "UTF-8") | ||
40 | (set-default-coding-systems 'utf-8) | ||
41 | (set-terminal-coding-system 'utf-8) | ||
42 | (set-keyboard-coding-system 'utf-8) | ||
43 | (set-selection-coding-system 'utf-8) | ||
44 | (prefer-coding-system 'utf-8) | ||
45 | |||
46 | ;;; Save/Restore | ||
47 | ;; autosave, but like, better | ||
48 | (use-package super-save | ||
49 | :custom | ||
50 | (auto-save-default nil) | ||
51 | (super-save-auto-save-when-idle t) | ||
52 | (super-save-exclude '(".gpg")) | ||
53 | :config | ||
54 | (super-save-mode +1)) | ||
55 | |||
56 | ;; save places in files | ||
57 | (use-package saveplace | ||
58 | :custom | ||
59 | (save-place-file (no-littering-expand-var-file-name "places")) | ||
60 | :config | ||
61 | (save-place-mode +1)) | ||
62 | |||
63 | ;; save history of variables | ||
64 | (use-package savehist | ||
65 | :custom | ||
66 | (savehist-additional-variables | ||
67 | '(kill-ring | ||
68 | search-ring | ||
69 | regexp-search-ring)) | ||
70 | :config | ||
71 | (savehist-mode +1)) | ||
72 | |||
73 | ;;; Buffers | ||
74 | ;; uniquely name buffers | ||
75 | (cuss uniquify-buffer-name-style 'forward) | ||
76 | |||
77 | ;;; UI | ||
78 | ;; frame defaults | ||
79 | (cuss default-frame-alist '((tool-bar-lines . 0) | ||
80 | (menu-bar-lines . 0) | ||
81 | (vertical-scroll-bars . nil) | ||
82 | (horizontal-scroll-bars . nil) | ||
83 | (right-divider-width . 2) | ||
84 | (bottom-divider-width . 2) | ||
85 | (left-fringe-width . 2) | ||
86 | (right-fringe-width . 2))) | ||
87 | |||
88 | ;; also disable these with modes, so I can re-enable them more easily | ||
89 | (menu-bar-mode -1) | ||
90 | (tool-bar-mode -1) | ||
91 | (scroll-bar-mode -1) | ||
92 | |||
93 | ;; cursor | ||
94 | (cuss cursor-type 'bar) | ||
95 | (cuss cursor-in-non-selected-windows 'hollow) | ||
96 | (blink-cursor-mode 0) | ||
97 | |||
98 | ;; mouse | ||
99 | (cuss mouse-yank-at-point t) ; yank at the point instead of where clicked | ||
100 | |||
101 | ;; startup screen | ||
102 | (cuss inhibit-startup-buffer-menu t) | ||
103 | (cuss inhibit-startup-screen t) | ||
104 | (cuss initial-buffer-choice t) ; start in *scratch* | ||
105 | (cuss initial-scratch-message nil) | ||
106 | |||
107 | ;; interactivity | ||
108 | (fset 'yes-or-no-p #'y-or-n-p) | ||
109 | |||
110 | (cuss use-dialog-box nil) | ||
111 | (cuss disabled-command-function nil) | ||
112 | |||
113 | ;; themes | ||
114 | (use-package modus-operandi-theme | ||
115 | :config | ||
116 | (load-theme 'modus-operandi t)) | ||
117 | |||
118 | (use-package modus-vivendi-theme) | ||
119 | |||
120 | ;; fonts | ||
121 | (set-face-attribute 'default nil | ||
122 | :family "DejaVu Sans Mono" | ||
123 | :height 110) | ||
124 | |||
125 | (set-face-attribute 'fixed-pitch nil | ||
126 | :family "DejaVu Sans Mono" | ||
127 | :height 110) | ||
128 | |||
129 | (set-face-attribute 'variable-pitch nil | ||
130 | :family "DejaVu Serif" | ||
131 | :height 120) | ||
132 | |||
133 | ;; unicode | ||
134 | (use-package unicode-fonts | ||
135 | :config | ||
136 | (unicode-fonts-setup)) | ||
137 | |||
138 | ;;; Selecting / Minibuffer | ||
139 | ;; ignore case | ||
140 | (cuss completion-ignore-case t) | ||
141 | (cuss read-buffer-completion-ignore-case t) | ||
142 | (cuss read-file-name-completion-ignore-case t) | ||
143 | |||
144 | (use-package selectrum | ||
145 | :config | ||
146 | (selectrum-mode +1)) | ||
147 | |||
148 | (use-package prescient | ||
149 | :config | ||
150 | (prescient-persist-mode +1)) | ||
151 | |||
152 | (use-package selectrum-prescient | ||
153 | :after (selectrum prescient) | ||
154 | :config | ||
155 | (selectrum-prescient-mode +1)) | ||
156 | |||
157 | ;; searching | ||
158 | (use-package ctrlf | ||
159 | :custom | ||
160 | (ctrlf-show-match-count-at-eol nil) | ||
161 | :config | ||
162 | (ctrlf-mode +1)) | ||
163 | |||
164 | ;;; Undo | ||
165 | (use-package undo-fu | ||
166 | :bind | ||
167 | ("C-/" . undo-fu-only-undo) | ||
168 | ("C-?" . undo-fu-only-redo)) | ||
169 | |||
170 | (use-package undo-fu-session | ||
171 | :after no-littering | ||
172 | :custom | ||
173 | (undo-fu-session-incompatible-files | ||
174 | '("/COMMIT_EDITMSG\\'" | ||
175 | "/git-rebase-todo\\'")) | ||
176 | (undo-fu-session-directory | ||
177 | (no-littering-expand-var-file-name "undos/")) | ||
178 | :config | ||
179 | (global-undo-fu-session-mode +1)) | ||
180 | |||
181 | ;;; Text editing | ||
182 | ;; visual line mode | ||
183 | (global-visual-line-mode +1) | ||
184 | |||
185 | (use-package whole-line-or-region | ||
186 | :config | ||
187 | (whole-line-or-region-global-mode +1)) | ||
188 | |||
189 | (use-package expand-region | ||
190 | :bind | ||
191 | ("C-=" . er/expand-region)) | ||
192 | |||
193 | ;; delete the selection when typing | ||
194 | (delete-selection-mode +1) | ||
195 | |||
196 | ;; clipboard | ||
197 | (cuss save-interprogram-paste-before-kill t) ; save existing clipboard text to kill ring before replacing it | ||
198 | |||
199 | ;; don't insert tabs. | ||
200 | (cuss indent-tabs-mode nil) | ||
201 | |||
202 | ;;; Programming | ||
203 | ;; Git | ||
204 | (use-package magit | ||
205 | :bind | ||
206 | ("C-x g" . magit-status) | ||
207 | :config | ||
208 | (add-to-list 'magit-no-confirm 'stage-all-changes)) | ||
209 | |||
210 | (when (executable-find "cmake") | ||
211 | (use-package libgit) | ||
212 | (use-package magit-libgit)) | ||
213 | |||
214 | (use-package forge | ||
215 | :after magit | ||
216 | :custom | ||
217 | (forge-owned-accounts '(("duckwork")))) | ||
218 | |||
219 | ;; Code formatting | ||
220 | (use-package format-all | ||
221 | :hook | ||
222 | (prog-mode . format-all-mode)) | ||
223 | |||
224 | ;; display | ||
225 | (add-hook 'prog-mode-hook #'prettify-symbols-mode) | ||
226 | |||
227 | ;; parentheses | ||
228 | (cuss show-paren-style 'mixed) | ||
229 | (show-paren-mode +1) | ||
230 | |||
231 | (use-package smartparens | ||
232 | :init | ||
233 | (defun acdw/setup-smartparens () | ||
234 | (require 'smartparens-config) | ||
235 | (smartparens-mode +1)) | ||
236 | :hook | ||
237 | (prog-mode . acdw/setup-smartparens)) | ||
238 | |||
239 | (use-package rainbow-delimiters | ||
240 | :hook | ||
241 | (prog-mode . rainbow-delimiters-mode)) | ||
242 | |||
243 | ;; line numbers | ||
244 | (add-hook 'prog-mode-hook | ||
245 | (if (and (fboundp 'display-line-numbers-mode) | ||
246 | (display-graphic-p)) | ||
247 | #'display-line-numbers-mode | ||
248 | #'linum-mode)) | ||
249 | |||
250 | ;;; Writing | ||
251 | (cuss sentence-end-double-space t) | ||
diff --git a/init.org b/init.org new file mode 100644 index 0000000..98e081d --- /dev/null +++ b/init.org | |||
@@ -0,0 +1,587 @@ | |||
1 | #+TITLE: Emacs config | ||
2 | #+AUTHOR: Case Duckworth | ||
3 | #+BABEL: :cache yes | ||
4 | #+PROPERTY: header-args :tangle init.el | ||
5 | #+BANKRUPTCY_COUNT: 1 | ||
6 | |||
7 | * Preamble | ||
8 | |||
9 | 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. | ||
10 | |||
11 | * Bootstrap | ||
12 | |||
13 | /Check out Lars's config for the reasoning behind this./ | ||
14 | |||
15 | When this configuration is loaded for the first time, this ~init.el~ is loaded: | ||
16 | |||
17 | #+BEGIN_SRC emacs-lisp :tangle no | ||
18 | ;; This file replaces itself with the actual configuration when first run. To keep only this version in git, run this command: | ||
19 | ;; git update-index --assume-unchanged init.el | ||
20 | ;; | ||
21 | ;; If it needs to be changed, start tracking it again thusly: | ||
22 | ;; git update-index --no-assume-unchanged init.el | ||
23 | |||
24 | (require 'org) | ||
25 | (find-file (concat user-emacs-directory "init.org")) | ||
26 | (org-babel-tangle) | ||
27 | (load-file (concat user-emacs-directory "init.el")) | ||
28 | (byte-compile-file (concat user-emacs-directory "init.el")) | ||
29 | #+END_SRC | ||
30 | |||
31 | ** Tangling | ||
32 | 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. | ||
33 | |||
34 | #+NAME: tangle-on-save | ||
35 | #+BEGIN_SRC emacs-lisp | ||
36 | (defun acdw/tangle-init () | ||
37 | "If the current buffer is `init.org', the code blocks are tangled, | ||
38 | and the tangled file is compiled." | ||
39 | (when (equal (buffer-file-name) | ||
40 | (expand-file-name (concat user-emacs-directory "init.org"))) | ||
41 | ;; Avoid running hooks when tangling. | ||
42 | (let ((prog-mode-hook nil)) | ||
43 | (org-babel-tangle) | ||
44 | (byte-compile-file (concat user-emacs-directory "init.el"))))) | ||
45 | |||
46 | (add-hook 'after-save-hook #'acdw/tangle-init) | ||
47 | #+END_SRC | ||
48 | |||
49 | * Early initiation | ||
50 | 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. | ||
51 | |||
52 | ** Preamble | ||
53 | Of course, first thing is the modeline. After that, I set ~load-prefer-newer~ because, well, it /should/. | ||
54 | #+BEGIN_SRC emacs-lisp :tangle early-init.el | ||
55 | ;;; early-init.el -*- lexical-binding: t; no-byte-compile: t -*- | ||
56 | |||
57 | (setq load-prefer-newer t) | ||
58 | #+END_SRC | ||
59 | |||
60 | ** Computers | ||
61 | 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. | ||
62 | |||
63 | #+BEGIN_SRC emacs-lisp :tangle early-init.el | ||
64 | (defconst *acdw/at-work* (eq system-type 'windows-nt)) | ||
65 | (defconst *acdw/at-larry* (string= (system-name) "larry")) | ||
66 | (defconst *acdw/at-bax* (string= (system-name) "bax")) | ||
67 | (defconst *acdw/at-home* (or *acdw/at-larry* *acdw/at-bax*)) | ||
68 | #+END_SRC | ||
69 | |||
70 | ** Package management | ||
71 | 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. | ||
72 | |||
73 | *** At work, Git's in a weird place | ||
74 | #+BEGIN_SRC emacs-lisp :tangle early-init.el | ||
75 | (when *acdw/at-work* | ||
76 | (add-to-list 'exec-path "~/bin") | ||
77 | (add-to-list 'exec-path "C:/Users/aduckworth/Downloads/PortableGit/bin")) | ||
78 | #+END_SRC | ||
79 | |||
80 | *** [[https://github.com/raxod502/straight.el][straight.el]] | ||
81 | 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/=). | ||
82 | |||
83 | #+BEGIN_SRC emacs-lisp :tangle early-init.el | ||
84 | (defvar bootstrap-version) | ||
85 | (let ((bootstrap-file | ||
86 | (expand-file-name "straight/repos/straight.el/bootstrap.el" | ||
87 | user-emacs-directory)) | ||
88 | (bootstrap-version 5)) | ||
89 | (unless (file-exists-p bootstrap-file) | ||
90 | (with-current-buffer | ||
91 | (url-retrieve-synchronously | ||
92 | "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" | ||
93 | 'silent 'inhibit-cookies) | ||
94 | (goto-char (point-max)) | ||
95 | (eval-print-last-sexp))) | ||
96 | (load bootstrap-file nil 'nomessage)) | ||
97 | #+END_SRC | ||
98 | |||
99 | *** [[https://github.com/jwiegley/use-package][use-package]] | ||
100 | Yeah, you know it, I know it, we all love it. It's use-package. | ||
101 | #+BEGIN_SRC emacs-lisp :tangle early-init.el | ||
102 | (setq straight-use-package-by-default t) | ||
103 | (straight-use-package 'use-package) | ||
104 | #+END_SRC | ||
105 | * Begin init.el | ||
106 | #+BEGIN_SRC emacs-lisp | ||
107 | ;;; init.el -*- lexical-binding: t; coding: utf-8 -*- | ||
108 | #+END_SRC | ||
109 | * Macros | ||
110 | ** cuss | ||
111 | 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? | ||
112 | |||
113 | 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~! | ||
114 | #+BEGIN_SRC emacs-lisp | ||
115 | (defmacro cuss (var val) | ||
116 | "Basically `use-package''s `:custom', but without either." | ||
117 | `(progn | ||
118 | (funcall (or (get ',var 'custom-set) #'set-default) | ||
119 | ',var ,val))) | ||
120 | #+END_SRC | ||
121 | * Files | ||
122 | ** [[https://github.com/emacscollective/no-littering][Keep .emacs.d tidy]] | ||
123 | #+BEGIN_SRC emacs-lisp | ||
124 | (use-package no-littering) | ||
125 | #+END_SRC | ||
126 | ** Customize | ||
127 | 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. | ||
128 | #+BEGIN_SRC emacs-lisp | ||
129 | (cuss custom-file (no-littering-expand-etc-file-name "custom.el")) | ||
130 | #+END_SRC | ||
131 | ** Encoding | ||
132 | #+BEGIN_SRC emacs-lisp | ||
133 | (set-charset-priority 'unicode) | ||
134 | (set-language-environment "UTF-8") | ||
135 | (set-default-coding-systems 'utf-8) | ||
136 | (set-terminal-coding-system 'utf-8) | ||
137 | (set-keyboard-coding-system 'utf-8) | ||
138 | (set-selection-coding-system 'utf-8) | ||
139 | (prefer-coding-system 'utf-8) | ||
140 | #+END_SRC | ||
141 | ** Recent files | ||
142 | #+BEGIN_SRC emacs-lisp | ||
143 | (use-package recentf | ||
144 | :config | ||
145 | (add-to-list 'recentf-exclude no-littering-var-directory) | ||
146 | (add-to-list 'recentf-exclude no-littering-etc-directory) | ||
147 | :custom | ||
148 | (recentf-max-menu-items 100) | ||
149 | (recentf-max-saved-items 100) | ||
150 | :config | ||
151 | (recentf-mode 1)) | ||
152 | #+END_SRC | ||
153 | ** Backups | ||
154 | #+BEGIN_SRC emacs-lisp | ||
155 | (cuss backup-directory-alist | ||
156 | `((".*" . ,(no-littering-expand-var-file-name "backup/")))) | ||
157 | #+END_SRC | ||
158 | ** [[https://github.com/bbatsov/super-save][Autosave]] | ||
159 | #+BEGIN_SRC emacs-lisp | ||
160 | (use-package super-save | ||
161 | :custom | ||
162 | (auto-save-default nil) | ||
163 | (super-save-auto-save-when-idle t) | ||
164 | (super-save-exclude '(".gpg")) | ||
165 | :config | ||
166 | (super-save-mode 1)) | ||
167 | #+END_SRC | ||
168 | ** Save places | ||
169 | #+BEGIN_SRC emacs-lisp | ||
170 | (use-package saveplace | ||
171 | :custom | ||
172 | (save-place-file (no-littering-expand-var-file-name "places")) | ||
173 | :config | ||
174 | (save-place-mode 1)) | ||
175 | #+END_SRC | ||
176 | ** Save history | ||
177 | #+BEGIN_SRC emacs-lisp | ||
178 | (use-package savehist | ||
179 | :custom | ||
180 | (savehist-addtional-variables | ||
181 | '(kill-ring | ||
182 | search-ring | ||
183 | regexp-search-ring)) | ||
184 | (savehist-save-minibuffer-history t) | ||
185 | :config | ||
186 | (savehist-mode 1)) | ||
187 | #+END_SRC | ||
188 | * User interface | ||
189 | ** Look | ||
190 | *** Frames and windows | ||
191 | **** Frame defaults | ||
192 | #+BEGIN_SRC emacs-lisp | ||
193 | (cuss default-frame-alist '((tool-bar-lines . 0) | ||
194 | (menu-bar-lines . 0) | ||
195 | (vertical-scroll-bars . nil) | ||
196 | (horizontal-scroll-bars . nil) | ||
197 | (right-divider-width . 2) | ||
198 | (bottom-divider-width . 2) | ||
199 | (left-fringe-width . 2) | ||
200 | (right-fringe-width . 2))) | ||
201 | |||
202 | ;; also disable these with modes, so I can re-enable them more easily | ||
203 | (menu-bar-mode -1) | ||
204 | (tool-bar-mode -1) | ||
205 | (scroll-bar-mode -1) | ||
206 | #+END_SRC | ||
207 | **** Resizing | ||
208 | #+BEGIN_SRC emacs-lisp | ||
209 | (cuss frame-resize-pixelwise t) | ||
210 | (cuss window-combination-resize t) | ||
211 | #+END_SRC | ||
212 | *** Buffers | ||
213 | #+BEGIN_SRC emacs-lisp | ||
214 | (cuss uniquify-buffer-name-style 'forward) | ||
215 | |||
216 | (cuss indicate-buffer-boundaries | ||
217 | '((top . right) | ||
218 | (bottom . right) | ||
219 | (t . nil))) | ||
220 | #+END_SRC | ||
221 | **** Startup buffer | ||
222 | #+BEGIN_SRC emacs-lisp | ||
223 | (cuss inhibit-startup-buffer-menu t) | ||
224 | (cuss inhibit-startup-screen t) | ||
225 | (cuss initial-buffer-choice t) ; start in *scratch* | ||
226 | (cuss initial-scratch-message nil) | ||
227 | #+END_SRC | ||
228 | *** Cursor | ||
229 | #+BEGIN_SRC emacs-lisp | ||
230 | (cuss cursor-type 'bar) | ||
231 | (cuss cursor-in-non-selected-windows 'hollow) | ||
232 | (blink-cursor-mode 0) | ||
233 | #+END_SRC | ||
234 | *** Interactivity | ||
235 | **** Mouse | ||
236 | #+BEGIN_SRC emacs-lisp | ||
237 | (cuss mouse-yank-at-point t) | ||
238 | #+END_SRC | ||
239 | **** Dialogs | ||
240 | #+BEGIN_SRC emacs-lisp | ||
241 | (cuss use-dialog-box nil) | ||
242 | #+END_SRC | ||
243 | **** Disabled functions | ||
244 | #+BEGIN_SRC emacs-lisp | ||
245 | (cuss disabled-command-function nil) | ||
246 | #+END_SRC | ||
247 | ** Themes: [[https://github.com/protesilaos/modus-themes][Modus]] | ||
248 | #+BEGIN_SRC emacs-lisp | ||
249 | (use-package modus-operandi-theme) | ||
250 | (use-package modus-vivendi-theme) | ||
251 | #+END_SRC | ||
252 | *** [[https://github.com/hadronzoo/theme-changer][Change themes]] based on time of day | ||
253 | #+BEGIN_SRC emacs-lisp | ||
254 | (use-package theme-changer | ||
255 | :init | ||
256 | (setq calendar-location-name "Baton Rouge, LA" | ||
257 | calendar-latitude 30.39 | ||
258 | calendar-longitude -91.83) | ||
259 | :config | ||
260 | (change-theme 'modus-operandi 'modus-vivendi)) | ||
261 | #+END_SRC | ||
262 | ** Modeline: [[https://github.com/Malabarba/smart-mode-line][smart-mode-line]] | ||
263 | #+BEGIN_SRC emacs-lisp | ||
264 | (use-package smart-mode-line | ||
265 | :config | ||
266 | (sml/setup)) | ||
267 | #+END_SRC | ||
268 | |||
269 | 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")~. | ||
270 | #+BEGIN_SRC emacs-lisp | ||
271 | (use-package rich-minority | ||
272 | :custom | ||
273 | (rm-whitelist '("^$")) ; show no minor modes | ||
274 | :config | ||
275 | (rich-minority-mode 1)) | ||
276 | #+END_SRC | ||
277 | ** Fonts | ||
278 | 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. | ||
279 | #+BEGIN_SRC emacs-lisp | ||
280 | (cuss face-font-family-alternatives | ||
281 | '(("Monospace" "courier" "fixed") | ||
282 | ("Monospace Serif" "Courier 10 Pitch" "Consolas" "Courier Std" "FreeMono" "Nimbus Mono L" "courier" "fixed") | ||
283 | ("courier" "CMU Typewriter Text" "fixed") | ||
284 | ("Sans Serif" "helv" "helvetica" "arial" "fixed") | ||
285 | ("helv" "helvetica" "arial" "fixed") | ||
286 | ;; now mine | ||
287 | ("FixedPitch" "DejaVu Sans Mono" "Consolas" "fixed") | ||
288 | ("VariablePitch" "DejaVu Serif" "Georgia" "fixed"))) | ||
289 | |||
290 | (set-face-attribute 'default nil | ||
291 | :family "FixedPitch" | ||
292 | :height 110) | ||
293 | |||
294 | (set-face-attribute 'fixed-pitch nil | ||
295 | :family "FixedPitch" | ||
296 | :height 110) | ||
297 | |||
298 | (set-face-attribute 'variable-pitch nil | ||
299 | :family "VariablePitch" | ||
300 | :height 110) | ||
301 | #+END_SRC | ||
302 | |||
303 | *** [[https://github.com/rolandwalker/unicode-fonts][Unicode fonts]] | ||
304 | #+BEGIN_SRC emacs-lisp | ||
305 | (use-package unicode-fonts | ||
306 | :config | ||
307 | (unicode-fonts-setup)) | ||
308 | #+END_SRC | ||
309 | * Editing | ||
310 | ** Completion | ||
311 | 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. | ||
312 | #+BEGIN_SRC emacs-lisp | ||
313 | (bind-key "M-/" #'hippie-expand) | ||
314 | #+END_SRC | ||
315 | ** Ignore case | ||
316 | #+BEGIN_SRC emacs-lisp | ||
317 | (cuss completion-ignore-case t) | ||
318 | (cuss read-buffer-completion-ignore-case t) | ||
319 | (cuss read-file-name-completion-ignore-case t) | ||
320 | #+END_SRC | ||
321 | ** Selection & Minibuffer | ||
322 | *** Selectrum and Prescient for narrowing selection | ||
323 | #+BEGIN_SRC emacs-lisp | ||
324 | (use-package selectrum | ||
325 | :config | ||
326 | (selectrum-mode +1)) | ||
327 | |||
328 | (use-package prescient | ||
329 | :config | ||
330 | (prescient-persist-mode +1)) | ||
331 | |||
332 | (use-package selectrum-prescient | ||
333 | :after (selectrum prescient) | ||
334 | :config | ||
335 | (selectrum-prescient-mode +1)) | ||
336 | #+END_SRC | ||
337 | *** CtrlF for searching | ||
338 | #+BEGIN_SRC emacs-lisp | ||
339 | (use-package ctrlf | ||
340 | :custom | ||
341 | (ctrlf-show-match-count-at-eol nil) | ||
342 | :config | ||
343 | (ctrlf-mode +1)) | ||
344 | #+END_SRC | ||
345 | ** Undo | ||
346 | #+BEGIN_SRC emacs-lisp | ||
347 | (use-package undo-fu | ||
348 | :bind | ||
349 | ("C-/" . undo-fu-only-undo) | ||
350 | ("C-?" . undo-fu-only-redo)) | ||
351 | |||
352 | (use-package undo-fu-session | ||
353 | :after no-littering | ||
354 | :custom | ||
355 | (undo-fu-session-incompatible-files | ||
356 | '("/COMMIT_EDITMSG\\'" | ||
357 | "/git-rebase-todo\\'")) | ||
358 | (undo-fu-session-directory | ||
359 | (no-littering-expand-var-file-name "undos/")) | ||
360 | :config | ||
361 | (global-undo-fu-session-mode +1)) | ||
362 | #+END_SRC | ||
363 | ** Visual editing | ||
364 | *** ~zap-to-char~ replacement | ||
365 | #+BEGIN_SRC emacs-lisp | ||
366 | (use-package zop-to-char | ||
367 | :bind | ||
368 | ([remap zap-to-char] . zop-to-char) | ||
369 | ([remap zap-up-to-char] . zop-up-to-char)) | ||
370 | #+END_SRC | ||
371 | *** Operate on a line if there's no current region | ||
372 | #+BEGIN_SRC emacs-lisp | ||
373 | (use-package whole-line-or-region | ||
374 | :config | ||
375 | (whole-line-or-region-global-mode +1)) | ||
376 | #+END_SRC | ||
377 | *** Expand-region | ||
378 | #+BEGIN_SRC emacs-lisp | ||
379 | (use-package expand-region | ||
380 | :bind | ||
381 | ("C-=" . er/expand-region) | ||
382 | ("C-+" . er/contract-region)) | ||
383 | #+END_SRC | ||
384 | *** Volatile highlights | ||
385 | #+BEGIN_SRC emacs-lisp | ||
386 | (use-package volatile-highlights | ||
387 | :config | ||
388 | (volatile-highlights-mode 1)) | ||
389 | #+END_SRC | ||
390 | *** Visual line mode | ||
391 | #+BEGIN_SRC emacs-lisp | ||
392 | (global-visual-line-mode 1) | ||
393 | #+END_SRC | ||
394 | *** A better ~move-beginning-of-line~ | ||
395 | #+BEGIN_SRC emacs-lisp | ||
396 | (defun my/smarter-move-beginning-of-line (arg) | ||
397 | "Move point back to indentation of beginning of line. | ||
398 | |||
399 | Move point to the first non-whitespace character on this line. | ||
400 | If point is already there, move to the beginning of the line. | ||
401 | Effectively toggle between the first non-whitespace character and | ||
402 | the beginning of the line. | ||
403 | |||
404 | If ARG is not nil or 1, move forward ARG - 1 lines first. If | ||
405 | point reaches the beginning or end of the buffer, stop there." | ||
406 | (interactive "^p") | ||
407 | (setq arg (or arg 1)) | ||
408 | |||
409 | ;; Move lines first | ||
410 | (when (/= arg 1) | ||
411 | (let ((line-move-visual nil)) | ||
412 | (forward-line (1- arg)))) | ||
413 | |||
414 | (let ((orig-point (point))) | ||
415 | (back-to-indentation) | ||
416 | (when (= orig-point (point)) | ||
417 | (move-beginning-of-line 1)))) | ||
418 | |||
419 | (bind-key "C-a" ; can't do [remap], don't know why | ||
420 | #'my/smarter-move-beginning-of-line) | ||
421 | #+END_SRC | ||
422 | ** Delete the selection when typing | ||
423 | #+BEGIN_SRC emacs-lisp | ||
424 | (delete-selection-mode 1) | ||
425 | #+END_SRC | ||
426 | ** Clipboard | ||
427 | #+BEGIN_SRC emacs-lisp | ||
428 | (cuss save-interprogram-paste-before-kill t) | ||
429 | #+END_SRC | ||
430 | ** Tabs & Spaces | ||
431 | #+BEGIN_SRC emacs-lisp | ||
432 | (cuss indent-tabs-mode nil) | ||
433 | (cuss sentence-end-double-space t) | ||
434 | #+END_SRC | ||
435 | * Programming | ||
436 | ** Git | ||
437 | #+BEGIN_SRC emacs-lisp | ||
438 | (use-package magit | ||
439 | :bind | ||
440 | ("C-x g" . magit-status) | ||
441 | :config | ||
442 | (add-to-list 'magit-no-confirm 'stage-all-changes)) | ||
443 | |||
444 | ;; hook into `prescient' | ||
445 | (define-advice magit-list-refs | ||
446 | (:around (orig &optional namespaces format sortby) | ||
447 | prescient-sort) | ||
448 | "Apply prescient sorting when listing refs." | ||
449 | (let ((res (funcall orig namespaces format sortby))) | ||
450 | (if (or sortby | ||
451 | magit-list-refs-sortby | ||
452 | (not selectrum-should-sort-p)) | ||
453 | res | ||
454 | (prescient-sort res)))) | ||
455 | |||
456 | (when (executable-find "cmake") | ||
457 | (use-package libgit) | ||
458 | (use-package magit-libgit)) | ||
459 | |||
460 | (use-package forge | ||
461 | :after magit | ||
462 | :custom | ||
463 | (forge-owned-accounts '(("duckwork")))) | ||
464 | #+END_SRC | ||
465 | ** Code formatting and display | ||
466 | #+BEGIN_SRC emacs-lisp | ||
467 | (use-package format-all | ||
468 | :hook | ||
469 | (prog-mode . format-all-mode)) | ||
470 | |||
471 | (add-hook 'prog-mode-hook #'prettify-symbols-mode) | ||
472 | |||
473 | #+END_SRC | ||
474 | *** Parentheses | ||
475 | #+BEGIN_SRC emacs-lisp | ||
476 | (cuss show-paren-style 'mixed) | ||
477 | (show-paren-mode +1) | ||
478 | |||
479 | (use-package smartparens | ||
480 | :init | ||
481 | (defun acdw/setup-smartparens () | ||
482 | (require 'smartparens-config) | ||
483 | (smartparens-mode +1)) | ||
484 | :hook | ||
485 | (prog-mode . acdw/setup-smartparens)) | ||
486 | |||
487 | (use-package rainbow-delimiters | ||
488 | :hook | ||
489 | (prog-mode . rainbow-delimiters-mode)) | ||
490 | #+END_SRC | ||
491 | ** Line numbers | ||
492 | #+BEGIN_SRC emacs-lisp | ||
493 | (add-hook 'prog-mode-hook | ||
494 | (if (and (fboundp 'display-line-numbers-mode) | ||
495 | (display-graphic-p)) | ||
496 | #'display-line-numbers-mode | ||
497 | #'linum-mode)) | ||
498 | #+END_SRC | ||
499 | ** Languages | ||
500 | *** Lua | ||
501 | #+BEGIN_SRC emacs-lisp | ||
502 | (use-package lua-mode | ||
503 | :mode "\\.lua\\'" | ||
504 | :interpreter "lua") | ||
505 | #+END_SRC | ||
506 | *** Fennel | ||
507 | #+BEGIN_SRC emacs-lisp | ||
508 | (use-package fennel-mode | ||
509 | :mode "\\.fnl\\'") | ||
510 | #+END_SRC | ||
511 | *** Web | ||
512 | #+BEGIN_SRC emacs-lisp | ||
513 | (use-package web-mode | ||
514 | :custom | ||
515 | (web-mode-markup-indent-offset 2) | ||
516 | (web-mode-code-indent-offset 2) | ||
517 | (web-mode-css-indent-offset 2) | ||
518 | :mode (("\\.ts\\'" . web-mode) | ||
519 | ("\\.html?\\'" . web-mode) | ||
520 | ("\\.css?\\'" . web-mode) | ||
521 | ("\\.js\\'" . web-mode))) | ||
522 | #+END_SRC | ||
523 | * Writing | ||
524 | * Applications | ||
525 | ** Gemini & Gopher | ||
526 | #+BEGIN_SRC emacs-lisp | ||
527 | (use-package elpher | ||
528 | :straight (elpher | ||
529 | :repo "git://thelambdalab.xyz/elpher.git") | ||
530 | :bind (:map elpher-mode-map | ||
531 | ("n" . elpher-next-link) | ||
532 | ("p" . elpher-prev-link) | ||
533 | ("o" . elpher-follow-current-link) | ||
534 | ("G" . elpher-go-current))) | ||
535 | |||
536 | (use-package gemini-mode | ||
537 | :straight (gemini-mode | ||
538 | :repo "https://git.carcosa.net/jmcbray/gemini.el.git") | ||
539 | :mode "\\.\\(gemini|gmi\\)\\'") | ||
540 | |||
541 | (use-package gemini-write | ||
542 | :straight (gemini-write | ||
543 | :repo "https://alexschroeder.ch/cgit/gemini-write")) | ||
544 | |||
545 | |||
546 | (defun post-to-gemlog-blue (post-title user pass) | ||
547 | "Post current buffer to gemlog.blue." | ||
548 | (interactive | ||
549 | (let* ((title-maybe (progn ;; TODO this is ... clunky | ||
550 | (goto-char (point-min)) | ||
551 | (if (re-search-forward "^# \\(.*\\)" nil t) | ||
552 | (buffer-substring-no-properties | ||
553 | (match-beginning 1) | ||
554 | (match-end 1)) | ||
555 | ""))) | ||
556 | (title (read-string | ||
557 | (format "Title%s: " | ||
558 | (if (string= "" title-maybe) | ||
559 | "" | ||
560 | (concat " (" title-maybe ")"))) | ||
561 | nil nil title-maybe)) | ||
562 | (user (read-string "User: " nil)) | ||
563 | (pass (read-passwd "Pass: " nil))) | ||
564 | (list title user pass))) | ||
565 | |||
566 | (require 'mm-url) | ||
567 | (let ((url-request-method "POST") | ||
568 | (url-request-extra-headers | ||
569 | '(("Content-Type" . "application/x-www-form-urlencoded"))) | ||
570 | (url-request-data | ||
571 | (mm-url-encode-www-form-urlencoded | ||
572 | `(("title" . ,post-title) | ||
573 | ("gemloguser" . ,user) | ||
574 | ("pw" . ,pass) | ||
575 | ("post" . ,(buffer-string)))))) | ||
576 | (with-current-buffer | ||
577 | (url-retrieve-synchronously "https://gemlog.blue/post.php") | ||
578 | (goto-char (point-min)) | ||
579 | (re-search-forward "\\(gemini://.*\\.gmi\\)") | ||
580 | (elpher-go (match-string 1))))) | ||
581 | #+END_SRC | ||
582 | ** Pastebin | ||
583 | #+BEGIN_SRC emacs-lisp | ||
584 | (use-package 0x0 | ||
585 | :custom | ||
586 | (0x0-default-service 'ttm)) | ||
587 | #+END_SRC | ||