diff options
author | Case Duckworth | 2022-10-17 21:41:28 -0500 |
---|---|---|
committer | Case Duckworth | 2022-10-17 21:41:28 -0500 |
commit | aab5bfd074e57d06a79e39d7c7c4760e1f385a06 (patch) | |
tree | 7b111190a44458a970355f7a327cc5278c850293 /lisp/+emacs.el | |
parent | asoi (diff) | |
download | emacs-aab5bfd074e57d06a79e39d7c7c4760e1f385a06.tar.gz emacs-aab5bfd074e57d06a79e39d7c7c4760e1f385a06.zip |
Bankruptcy 9
Diffstat (limited to 'lisp/+emacs.el')
-rw-r--r-- | lisp/+emacs.el | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/lisp/+emacs.el b/lisp/+emacs.el deleted file mode 100644 index 9158b62..0000000 --- a/lisp/+emacs.el +++ /dev/null | |||
@@ -1,434 +0,0 @@ | |||
1 | ;;; +emacs.el --- measured defaults for Emacs -*- lexical-binding: t -*- | ||
2 | |||
3 | ;;; Commentary: | ||
4 | |||
5 | ;; I find myself copy-pasting a lot of "boilerplate" type code when | ||
6 | ;; bankrupting my Emacs config and starting afresh. Instead of doing | ||
7 | ;; that, I'm putting it here, where it'll be easier to include in my | ||
8 | ;; config. | ||
9 | |||
10 | ;; Of course, some might say I could just ... stop bankrupting my | ||
11 | ;; Emacs. But like, why would I want to? | ||
12 | |||
13 | ;; Other notable packages include | ||
14 | ;; - https://git.sr.ht/~technomancy/better-defaults/ | ||
15 | ;; - https://github.com/susam/emfy | ||
16 | |||
17 | ;;; Code: | ||
18 | |||
19 | (require 'early-init (locate-user-emacs-file "early-init.el")) | ||
20 | |||
21 | (defun +set-major-mode-from-buffer-name (&optional buf) | ||
22 | "Set the major mode for BUF from the buffer's name. | ||
23 | Do this only if the buffer is not visiting a file." | ||
24 | (unless buffer-file-name | ||
25 | (let ((buffer-file-name (buffer-name buf))) | ||
26 | (set-auto-mode)))) | ||
27 | |||
28 | |||
29 | ;;; General settings | ||
30 | |||
31 | (setq-default | ||
32 | apropos-do-all t | ||
33 | async-shell-command-buffer 'new-buffer | ||
34 | async-shell-command-display-buffer nil | ||
35 | auto-hscroll-mode 'current-line | ||
36 | auto-revert-verbose t | ||
37 | auto-save-default nil | ||
38 | auto-save-file-name-transforms `((".*" ,(.etc "auto-save/") ,(car (secure-hash-algorithms))) | ||
39 | (".*" ,(.etc "auto-save/") t)) | ||
40 | auto-save-interval 30 | ||
41 | auto-save-list-file-prefix (.etc "auto-save/.saves-" t) | ||
42 | auto-save-timeout 30 | ||
43 | auto-save-visited-interval 5 | ||
44 | auto-window-vscroll nil | ||
45 | backup-by-copying t | ||
46 | backup-directory-alist `((".*" . ,(.etc "backup/" t))) | ||
47 | blink-cursor-blinks 1 | ||
48 | comp-deferred-compilation nil | ||
49 | completion-category-defaults nil | ||
50 | completion-category-overrides '((file (styles . (partial-completion)))) | ||
51 | completion-ignore-case t | ||
52 | completion-styles '(substring partial-completion) | ||
53 | create-lockfiles nil | ||
54 | cursor-in-non-selected-windows 'hollow | ||
55 | cursor-type 'bar | ||
56 | custom-file (.etc "custom.el") | ||
57 | delete-old-versions t | ||
58 | echo-keystrokes 0.1 | ||
59 | ediff-window-setup-function 'ediff-setup-windows-plain | ||
60 | eldoc-echo-area-use-multiline-p nil | ||
61 | eldoc-idle-delay 0.1 | ||
62 | enable-recursive-minibuffers t | ||
63 | executable-prefix-env t | ||
64 | fast-but-imprecise-scrolling t | ||
65 | file-name-shadow-properties '(invisible t intangible t) | ||
66 | fill-column 80 | ||
67 | find-file-visit-truename t | ||
68 | frame-resize-pixelwise t | ||
69 | global-auto-revert-non-file-buffers t | ||
70 | global-mark-ring-max 100 | ||
71 | hscroll-margin 1 | ||
72 | hscroll-step 1 | ||
73 | imenu-auto-rescan t | ||
74 | image-use-external-converter (or (executable-find "convert") | ||
75 | (executable-find "gm") | ||
76 | (executable-find "ffmpeg")) | ||
77 | indent-tabs-mode nil | ||
78 | inhibit-startup-screen t | ||
79 | initial-buffer-choice t | ||
80 | kept-new-versions 6 | ||
81 | kept-old-versions 2 | ||
82 | kill-do-not-save-duplicates t | ||
83 | kill-read-only-ok t | ||
84 | kill-ring-max 500 | ||
85 | kmacro-ring-max 20 | ||
86 | load-prefer-newer noninteractive | ||
87 | major-mode '+set-major-mode-from-buffer-name | ||
88 | mark-ring-max 50 | ||
89 | minibuffer-eldef-shorten-default t | ||
90 | minibuffer-prompt-properties (list 'read-only t | ||
91 | 'cursor-intangible t | ||
92 | 'face 'minibuffer-prompt) | ||
93 | mode-require-final-newline 'visit-save | ||
94 | mouse-drag-copy-region t | ||
95 | mouse-wheel-progressive-speed nil | ||
96 | mouse-yank-at-point t | ||
97 | native-comp-async-report-warnings-errors 'silent | ||
98 | native-comp-deferred-compilation nil | ||
99 | read-answer-short t | ||
100 | read-buffer-completion-ignore-case t | ||
101 | ;; read-extended-command-predicate | ||
102 | ;; (when (fboundp | ||
103 | ;; 'command-completion-default-include-p) | ||
104 | ;; 'command-completion-default-include-p) | ||
105 | read-process-output-max (+bytes 1 :mib) ; We’re in the future man. Set that to at least a megabyte | ||
106 | recenter-positions '(top middle bottom) | ||
107 | regexp-search-ring-max 100 | ||
108 | regexp-search-ring-max 200 | ||
109 | save-interprogram-paste-before-kill t | ||
110 | save-some-buffers-default-predicate #'+save-some-buffers-p | ||
111 | scroll-conservatively 101 | ||
112 | scroll-down-aggressively 0.01 | ||
113 | scroll-margin 2 | ||
114 | scroll-preserve-screen-position 1 | ||
115 | scroll-step 1 | ||
116 | scroll-up-aggressively 0.01 | ||
117 | search-ring-max 200 | ||
118 | search-ring-max 200 | ||
119 | sentence-end-double-space t | ||
120 | set-mark-command-repeat-pop t | ||
121 | show-paren-delay 0 | ||
122 | show-paren-style 'parenthesis | ||
123 | show-paren-when-point-in-periphery t | ||
124 | show-paren-when-point-inside-paren t | ||
125 | ;;show-trailing-whitespace t | ||
126 | tab-bar-show 1 | ||
127 | tab-width 8 ; so alignment expecting the default looks right | ||
128 | tramp-backup-directory-alist backup-directory-alist | ||
129 | undo-limit 100000000 ; 10 MB | ||
130 | use-dialog-box nil | ||
131 | use-file-dialog nil | ||
132 | use-short-answers t | ||
133 | vc-follow-symlinks t | ||
134 | vc-make-backup-files t | ||
135 | version-control t | ||
136 | view-read-only t | ||
137 | visible-bell nil | ||
138 | window-resize-pixelwise t | ||
139 | x-select-enable-clipboard t | ||
140 | x-select-enable-primary t | ||
141 | yank-pop-change-selection t | ||
142 | ) | ||
143 | |||
144 | ;; Programming language offsets. | ||
145 | ;; Set these after the initial block so I can use `tab-width' | ||
146 | (setq-default | ||
147 | c-basic-offset tab-width) | ||
148 | |||
149 | ;; Emacs 28 ships with an option, `use-short-answers', that makes this form | ||
150 | ;; obsolete, but I still use 27 at work. | ||
151 | (when (version< emacs-version "28") | ||
152 | (fset 'yes-or-no-p 'y-or-n-p)) | ||
153 | |||
154 | |||
155 | ;;; Encodings | ||
156 | |||
157 | ;; Allegedly, this is the only one you need... | ||
158 | (set-language-environment "UTF-8") | ||
159 | ;; But I still set all of these, for fun. | ||
160 | (setq-default locale-coding-system 'utf-8-unix | ||
161 | coding-system-for-read 'utf-8-unix | ||
162 | coding-system-for-write 'utf-8-unix | ||
163 | buffer-file-coding-system 'utf-8-unix | ||
164 | default-process-coding-system '(utf-8-unix . utf-8-unix) | ||
165 | x-select-request-type '(UTF8_STRING | ||
166 | COMPOUND_TEXT | ||
167 | TEXT | ||
168 | STRING)) | ||
169 | |||
170 | (set-charset-priority 'unicode) | ||
171 | (prefer-coding-system 'utf-8-unix) | ||
172 | (set-default-coding-systems 'utf-8-unix) | ||
173 | (set-terminal-coding-system 'utf-8-unix) | ||
174 | (set-keyboard-coding-system 'utf-8-unix) | ||
175 | |||
176 | (pcase system-type | ||
177 | ((or 'ms-dos 'windows-nt) | ||
178 | (set-clipboard-coding-system 'utf-16-le) | ||
179 | (set-selection-coding-system 'utf-16-le)) | ||
180 | (_ | ||
181 | (set-selection-coding-system 'utf-8) | ||
182 | (set-clipboard-coding-system 'utf-8))) | ||
183 | |||
184 | |||
185 | ;;; Modes | ||
186 | |||
187 | (dolist (enable-mode '(global-auto-revert-mode | ||
188 | blink-cursor-mode | ||
189 | electric-pair-mode | ||
190 | show-paren-mode | ||
191 | global-so-long-mode | ||
192 | minibuffer-depth-indicate-mode | ||
193 | file-name-shadow-mode | ||
194 | minibuffer-electric-default-mode | ||
195 | delete-selection-mode | ||
196 | auto-save-visited-mode | ||
197 | ;; column-number-mode | ||
198 | )) | ||
199 | (when (fboundp enable-mode) | ||
200 | (funcall enable-mode +1))) | ||
201 | |||
202 | (dolist (disable-mode '(tooltip-mode | ||
203 | tool-bar-mode | ||
204 | menu-bar-mode | ||
205 | scroll-bar-mode | ||
206 | horizontal-scroll-bar-mode)) | ||
207 | (when (fboundp disable-mode) | ||
208 | (funcall disable-mode -1))) | ||
209 | |||
210 | |||
211 | ;;; Hooks | ||
212 | |||
213 | (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) | ||
214 | (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) | ||
215 | |||
216 | (defun +auto-create-missing-dirs () | ||
217 | "Automatically create missing directories when finding a file." | ||
218 | ;; https://emacsredux.com/blog/2022/06/12/auto-create-missing-directories/ | ||
219 | (let ((target-dir (file-name-directory buffer-file-name))) | ||
220 | (unless (file-exists-p target-dir) | ||
221 | (make-directory target-dir t)))) | ||
222 | |||
223 | (add-hook 'find-file-not-found-functions #'+auto-create-missing-dirs) | ||
224 | |||
225 | (defvar +save-some-buffers-debounce-time nil | ||
226 | "Last time `+save-some-buffers-debounce' was run.") | ||
227 | |||
228 | (defcustom +save-some-buffers-debounce-timeout 5 | ||
229 | "Number of seconds to wait before saving buffers again.") | ||
230 | |||
231 | (defun +save-some-buffers-debounce (&rest _) | ||
232 | "Run `save-some-buffers', but only if it's been a while." | ||
233 | (unless (and +save-some-buffers-debounce-time | ||
234 | (< (- (time-convert nil 'integer) +save-some-buffers-debounce-time) | ||
235 | +save-some-buffers-debounce-timeout)) | ||
236 | (save-some-buffers t) | ||
237 | (setq +save-some-buffers-debounce-time (time-convert nil 'integer)))) | ||
238 | |||
239 | (add-function :after after-focus-change-function #'+save-some-buffers-debounce) | ||
240 | |||
241 | |||
242 | ;;; Better-default functions ... | ||
243 | |||
244 | (defun +cycle-spacing (&optional n preserve-nl-back mode) | ||
245 | "Negate N argument on `cycle-spacing'. | ||
246 | That is, with a positive N, deletes newlines as well, leaving -N | ||
247 | spaces. If N is negative, it will not delete newlines and leave | ||
248 | N spaces. See docstring of `cycle-spacing' for the meaning of | ||
249 | PRESERVE-NL-BACK and MODE." | ||
250 | (interactive "*p") | ||
251 | (cycle-spacing (- n) preserve-nl-back mode)) | ||
252 | |||
253 | (defun +save-buffers-quit (&optional arg) | ||
254 | "Silently save each buffer, then kill the current connection. | ||
255 | If the current frame has no client, kill Emacs itself using | ||
256 | `save-buffers-kill-emacs' after confirming with the user. | ||
257 | |||
258 | With prefix ARG, silently save all file-visiting buffers, then | ||
259 | kill without asking." | ||
260 | (interactive "P") | ||
261 | (save-some-buffers t) | ||
262 | (if (and (not (frame-parameter nil 'client)) | ||
263 | (and (not arg))) | ||
264 | (when (yes-or-no-p "Sure you want to quit? ") | ||
265 | (save-buffers-kill-emacs)) | ||
266 | (delete-frame nil :force))) | ||
267 | |||
268 | (defun +kill-word-backward-or-region (&optional arg backward-kill-word-fn) | ||
269 | "Kill active region or ARG words backward. | ||
270 | BACKWARD-KILL-WORD-FN is the function to call to kill a word | ||
271 | backward. It defaults to `backward-kill-word'." | ||
272 | (interactive "P") | ||
273 | (call-interactively (if (region-active-p) | ||
274 | #'kill-region | ||
275 | (or backward-kill-word-fn #'backward-kill-word)))) | ||
276 | |||
277 | (defun +backward-kill-word-wrapper (fn &optional arg) | ||
278 | "Kill backward using FN until the beginning of a word, smartly. | ||
279 | If point is on at the beginning of a line, kill the previous new | ||
280 | line. If the only thing before point on the current line is | ||
281 | whitespace, kill that whitespace. | ||
282 | |||
283 | With argument ARG: if ARG is a number, just call FN | ||
284 | ARG times. Otherwise, just call FN." | ||
285 | ;; I want this to be a wrapper so that I can call other word-killing functions | ||
286 | ;; with it. It's *NOT* advice because those functions probably use | ||
287 | ;; `backward-kill-word' under the hood (looking at you, paredit), so advice | ||
288 | ;; will make things weird. | ||
289 | (if (null arg) | ||
290 | (cond | ||
291 | ((looking-back "^" 1) | ||
292 | (let ((delete-active-region nil)) | ||
293 | (delete-backward-char 1))) | ||
294 | ((looking-back "^[ ]*") | ||
295 | (delete-horizontal-space :backward-only)) | ||
296 | (t (call-interactively fn))) | ||
297 | (funcall fn (if (listp arg) 1 arg)))) | ||
298 | |||
299 | (defun +backward-kill-word (&optional arg) | ||
300 | "Kill word backward using `backward-kill-word'. | ||
301 | ARG is passed to `backward-kill-word'." | ||
302 | (interactive "P") | ||
303 | (+backward-kill-word-wrapper #'backward-kill-word arg)) | ||
304 | |||
305 | ;;; ... and advice | ||
306 | |||
307 | ;; Indent the region after a yank. | ||
308 | (defun +yank@indent (&rest _) | ||
309 | "Indent the current region." | ||
310 | (indent-region (min (point) (mark)) (max (point) (mark)))) | ||
311 | (advice-add #'yank :after #'+yank@indent) | ||
312 | (advice-add #'yank-pop :after #'+yank@indent) | ||
313 | |||
314 | |||
315 | ;;; Extra functions | ||
316 | |||
317 | (defun +save-some-buffers-p () | ||
318 | "Predicate for `save-some-buffers-default-predicate'. | ||
319 | It returns nil with remote files and those without attached files." | ||
320 | (and (buffer-file-name) | ||
321 | (not (file-remote-p (buffer-file-name))))) | ||
322 | |||
323 | ;; https://www.wwwtech.de/articles/2013/may/emacs:-jump-to-matching-paren-beginning-of-block | ||
324 | (defun +goto-matching-paren (&optional arg) | ||
325 | "Go to the matching paren, similar to vi's %." | ||
326 | (interactive "p") | ||
327 | (or arg (setq arg 1)) | ||
328 | (cond | ||
329 | ;; Check for "outside of bracket" positions | ||
330 | ((looking-at "[\[\(\{]") (forward-sexp arg)) | ||
331 | ((looking-back "[\]\)\}]" 1) (backward-sexp arg)) | ||
332 | ;; Otherwise, move from inside the bracket | ||
333 | ((looking-at "[\]\)\}]") (forward-char) (backward-sexp arg)) | ||
334 | ((looking-back "[\[\(\{]" 1) (backward-char) (forward-sexp arg)) | ||
335 | (t (up-list arg t t)))) | ||
336 | |||
337 | (defun +delete-window-or-bury-buffer () | ||
338 | "Delete the current window, or bury the current buffer. | ||
339 | If the current window is the only window, bury the buffer." | ||
340 | (interactive) | ||
341 | (condition-case e | ||
342 | (delete-window) | ||
343 | (t (bury-buffer)))) | ||
344 | |||
345 | |||
346 | ;;; Bindings | ||
347 | |||
348 | (global-set-key (kbd "C-x C-c") #'+save-buffers-quit) | ||
349 | (global-set-key (kbd "M-SPC") #'+cycle-spacing) | ||
350 | (global-set-key (kbd "M-/") #'hippie-expand) | ||
351 | (global-set-key (kbd "M-=") #'count-words) | ||
352 | (global-set-key (kbd "C-x C-b") #'ibuffer) | ||
353 | (global-set-key (kbd "C-s") #'isearch-forward-regexp) | ||
354 | (global-set-key (kbd "C-r") #'isearch-backward-regexp) | ||
355 | (global-set-key (kbd "C-M-s") #'isearch-forward) | ||
356 | (global-set-key (kbd "C-M-r") #'isearch-backward) | ||
357 | (global-set-key (kbd "C-x 4 n") #'clone-buffer) | ||
358 | ;; https://christiantietze.de/posts/2022/07/shift-click-in-emacs-to-select/ | ||
359 | (global-set-key (kbd "S-<down-mouse-1>") #'mouse-set-mark) | ||
360 | (global-set-key (kbd "C-x 0") #'+delete-window-or-bury-buffer) | ||
361 | |||
362 | |||
363 | ;;; Required libraries | ||
364 | |||
365 | (when (require 'uniquify nil :noerror) | ||
366 | (setq-default uniquify-buffer-name-style 'forward | ||
367 | uniquify-separator path-separator | ||
368 | uniquify-after-kill-buffer-p t | ||
369 | uniquify-ignore-buffers-re "^\\*")) | ||
370 | |||
371 | (when (require 'goto-addr) | ||
372 | (if (fboundp 'global-goto-address-mode) | ||
373 | (global-goto-address-mode +1) | ||
374 | (add-hook 'after-change-major-mode-hook 'goto-address-mode))) | ||
375 | |||
376 | (when (require 'recentf nil :noerror) | ||
377 | (setq-default recentf-save-file (.etc "recentf.el") | ||
378 | recentf-max-menu-items 100 | ||
379 | recentf-max-saved-items nil | ||
380 | recentf-auto-cleanup 'mode) | ||
381 | (add-to-list 'recentf-exclude .etc) | ||
382 | (recentf-mode +1)) | ||
383 | |||
384 | (when (require 'savehist nil :noerror) | ||
385 | (setq-default history-length t | ||
386 | history-delete-duplicates t | ||
387 | history-autosave-interval 60 | ||
388 | savehist-file (.etc "savehist.el") | ||
389 | ;; Other variables --- don't truncate any of these. | ||
390 | ;; `add-to-history' uses the values of these variables unless | ||
391 | ;; they're nil, in which case it falls back to `history-length'. | ||
392 | kill-ring-max 100 | ||
393 | mark-ring-max 100 | ||
394 | global-mark-ring-max 100 | ||
395 | regexp-search-ring-max 100 | ||
396 | search-ring-max 100 | ||
397 | kmacro-ring-max 100 | ||
398 | eww-history-limit 100) | ||
399 | (dolist (var '(extended-command-history | ||
400 | global-mark-ring | ||
401 | mark-ring | ||
402 | kill-ring | ||
403 | kmacro-ring | ||
404 | regexp-search-ring | ||
405 | search-ring)) | ||
406 | (add-to-list 'savehist-additional-variables var)) | ||
407 | (savehist-mode +1)) | ||
408 | |||
409 | (when (require 'saveplace nil :noerror) | ||
410 | (setq-default save-place-file (.etc "places.el") | ||
411 | save-place-forget-unreadable-files (eq system-type 'gnu/linux)) | ||
412 | (save-place-mode +1)) | ||
413 | |||
414 | ;; (when (require 'tramp) | ||
415 | ;; ;; thanks Irreal! https://irreal.org/blog/?p=895 | ||
416 | ;; (add-to-list 'tramp-default-proxies-alist | ||
417 | ;; '(nil "\\`root\\'" "/ssh:%h:")) | ||
418 | ;; (add-to-list 'tramp-default-proxies-alist | ||
419 | ;; '((regexp-quote (system-name)) nil nil))) | ||
420 | |||
421 | |||
422 | ;;; Newer features | ||
423 | ;; These aren't in older version of Emacs, but they're so nice. | ||
424 | |||
425 | (when (fboundp 'repeat-mode) | ||
426 | (setq-default repeat-exit-key "g" | ||
427 | repeat-exit-timeout 5) | ||
428 | (repeat-mode +1)) | ||
429 | |||
430 | (when (fboundp 'pixel-scroll-precision-mode) | ||
431 | (pixel-scroll-precision-mode +1)) | ||
432 | |||
433 | (provide '+emacs) | ||
434 | ;;; +emacs.el ends here | ||