diff options
-rw-r--r-- | emacs | 406 | ||||
-rw-r--r-- | emacs.d/early-init.el | 30 |
2 files changed, 169 insertions, 267 deletions
diff --git a/emacs b/emacs index 7b3d9ea..a54028e 100644 --- a/emacs +++ b/emacs | |||
@@ -1,4 +1,4 @@ | |||
1 | ;;; ~/.emacs -*- lexical-binding: t; -*- | 1 | ;;; ~/.emacs -*- mode: emacs-lisp; lexical-binding: t; -*- |
2 | ;; Author Case Duckworth <acdw@acdw.net> | 2 | ;; Author Case Duckworth <acdw@acdw.net> |
3 | ;; Bankruptcy: 12 | 3 | ;; Bankruptcy: 12 |
4 | 4 | ||
@@ -7,179 +7,34 @@ | |||
7 | (setopt custom-file (locate-user-emacs-file "custom.el")) | 7 | (setopt custom-file (locate-user-emacs-file "custom.el")) |
8 | (load custom-file :no-error) | 8 | (load custom-file :no-error) |
9 | 9 | ||
10 | (defvar private-file (locate-user-emacs-file "private.el") | 10 | (defvar user-private-file (locate-user-emacs-file "private.el") |
11 | "Private customizations") | 11 | "Private customizations") |
12 | (load private-file :no-error) ; might as well do this now | 12 | ;; make sure it's really private! |
13 | (and (= (file-attribute-user-id (file-attributes user-private-file)) | ||
14 | (user-uid)) ; is it owned by this me? | ||
15 | (set-file-modes user-private-file #o600)) | ||
16 | (load user-private-file :no-error) | ||
13 | 17 | ||
14 | ;; (load-theme 'modus-operandi :no-confirm) | 18 | (load-theme 'brianna :no-confirm) ; see ~/.emacs.d/brianna-theme.el |
15 | 19 | (add-hook 'after-init-hook #'setup-faces) | |
16 | ;;; Custom functions | ||
17 | 20 | ||
18 | (define-advice startup-echo-area-message (:override ()) | 21 | (define-advice startup-echo-area-message (:override ()) |
19 | (if (get-buffer "*Warnings*") | 22 | (if (get-buffer "*Warnings*") |
20 | ";_;" | 23 | ";_;" |
21 | "^_^")) | 24 | "^_^")) |
22 | 25 | ||
23 | (defun create-missing-directories () | ||
24 | "Automatically create missing directories." | ||
25 | (let ((target-dir (file-name-directory buffer-file-name))) | ||
26 | (unless (file-exists-p target-dir) | ||
27 | (make-directory target-dir :parents)))) | ||
28 | |||
29 | (defun delete-trailing-whitespace-except-current-line () | ||
30 | (save-excursion | ||
31 | (delete-trailing-whitespace (point-min) | ||
32 | (line-beginning-position)) | ||
33 | (delete-trailing-whitespace (line-end-position) | ||
34 | (point-max)))) | ||
35 | |||
36 | (defun run-after-frame-init (func) | ||
37 | "Run FUNC after the first frame is initialized. | ||
38 | If already so, run FUNC immediately." | ||
39 | (cond | ||
40 | ((daemonp) | ||
41 | (add-hook 'server-after-make-frame-hook func) | ||
42 | (advice-add func :after (lambda () | ||
43 | (remove-hook 'server-after-make-frame-hook | ||
44 | func) | ||
45 | (advice-remove func | ||
46 | 'after-frame-init-removing-advice)) | ||
47 | |||
48 | |||
49 | '((name . after-frame-init-removing-advice)))) | ||
50 | ((not after-init-time) | ||
51 | (add-hook 'after-init-hook func)) | ||
52 | (:else (funcall func)))) | ||
53 | |||
54 | (defun first-found-font (&rest cands) | ||
55 | "Return the first font of CANDS that is installed, or nil." | ||
56 | (cl-loop with ffl = (font-family-list) | ||
57 | for font in cands | ||
58 | if (member font ffl) | ||
59 | return font)) | ||
60 | |||
61 | (defun setup-faces () | ||
62 | "Setup Emacs faces." | ||
63 | (set-face-attribute 'variable-pitch nil | ||
64 | :family (first-found-font "Public Sans") | ||
65 | :height 1.0) | ||
66 | (set-face-attribute 'fixed-pitch nil | ||
67 | :family (first-found-font "Recursive Mono Linear Static")) | ||
68 | (set-face-attribute 'fixed-pitch-serif nil | ||
69 | :family (first-found-font "Go Mono" | ||
70 | "DejaVu Sans Mono")) | ||
71 | |||
72 | ;; Emojis | ||
73 | (cl-loop with ffl = (font-family-list) | ||
74 | for font in '("Noto Emoji" "Noto Color Emoji" | ||
75 | "Segoe UI Emoji" "Apple Color Emoji" | ||
76 | "FreeSans" "FreeMono" "FreeSerif" | ||
77 | "Unifont" "Symbola") | ||
78 | if (member font ffl) | ||
79 | do (set-fontset-font t 'symbol font)) | ||
80 | |||
81 | ;; International fonts | ||
82 | (cl-loop with ffl = (font-family-list) | ||
83 | for (charset . font) | ||
84 | in '((latin . "Noto Sans") | ||
85 | (han . "Noto Sans CJK SC Regular") | ||
86 | (kana . "Noto Sans CJK JP Regular") | ||
87 | (hangul . "Noto Sans CJK KR Regular") | ||
88 | (cjk-misc . "Noto Sans CJK KR Regular") | ||
89 | (khmer . "Noto Sans Khmer") | ||
90 | (lao . "Noto Sans Lao") | ||
91 | (burmese . "Noto Sans Myanmar") | ||
92 | (thai . "Noto Sans Thai") | ||
93 | (ethiopic . "Noto Sans Ethiopic") | ||
94 | (hebrew . "Noto Sans Hebrew") | ||
95 | (arabic . "Noto Sans Arabic") | ||
96 | (gujarati . "Noto Sans Gujarati") | ||
97 | (devanagari . "Noto Sans Devanagari") | ||
98 | (kannada . "Noto Sans Kannada") | ||
99 | (malayalam . "Noto Sans Malayalam") | ||
100 | (oriya . "Noto Sans Oriya") | ||
101 | (sinhala . "Noto Sans Sinhala") | ||
102 | (tamil . "Noto Sans Tamil") | ||
103 | (telugu . "Noto Sans Telugu") | ||
104 | (tibetan . "Noto Sans Tibetan")) | ||
105 | if (member font ffl) | ||
106 | do (set-fontset-font t charset font))) | ||
107 | |||
108 | (defmacro inhibit-messages (&rest body) | ||
109 | "Inhibit all messages in BODY." | ||
110 | (declare (indent defun)) | ||
111 | `(cl-letf (((symbol-function 'message) #'ignore)) | ||
112 | ,@body)) | ||
113 | |||
114 | (defun kill-buffer-dwim (&optional buffer-or-name) | ||
115 | "Kill BUFFER-OR-NAME or the current buffer." | ||
116 | (interactive "P") | ||
117 | (cond | ||
118 | ((bufferp buffer-or-name) | ||
119 | (kill-buffer buffer-or-name)) | ||
120 | ((null buffer-or-name) | ||
121 | (kill-current-buffer)) | ||
122 | (:else | ||
123 | (kill-buffer (read-buffer "Kill: " nil :require-match))))) | ||
124 | |||
125 | (defun other-window-dwim (&optional arg) | ||
126 | "Switch to another window/buffer. | ||
127 | Calls `other-window', which see, unless | ||
128 | - the current window is alone on its frame | ||
129 | - `other-window-dwim' is called with \\[universal-argument] | ||
130 | In these cases, switch to the last-used buffer." | ||
131 | (interactive "P") | ||
132 | (if (or arg (one-window-p)) | ||
133 | (switch-to-buffer (other-buffer) nil t) | ||
134 | (other-window 1))) | ||
135 | |||
136 | (defun delete-window-dwim () | ||
137 | "Delete the current window or bury its buffer. | ||
138 | If the current window is alone in its frame, bury the buffer | ||
139 | instead." | ||
140 | (interactive) | ||
141 | (unless (ignore-errors (delete-window) t) | ||
142 | (bury-buffer))) | ||
143 | |||
144 | (defun cycle-spacing* (&optional n) | ||
145 | "Negate N argument on `cycle-spacing'." | ||
146 | (interactive "*p") | ||
147 | (cycle-spacing (- n))) | ||
148 | |||
149 | (defun find-user-init-file (&optional arg) | ||
150 | "Edit `user-init-file' in current window. | ||
151 | With ARG, edit in other window." | ||
152 | (interactive "P") | ||
153 | (funcall (if arg #'find-file-other-window #'find-file) | ||
154 | user-init-file)) | ||
155 | |||
156 | (defun find-user-private-file (&optional arg) | ||
157 | "Edit `private-file'. | ||
158 | With ARG, edit in other window." | ||
159 | (interactive "P") | ||
160 | (funcall (if arg #'find-file-other-window #'find-file) | ||
161 | private-file)) | ||
162 | |||
163 | (defun package-ensure (pkg) | ||
164 | "Install PKG if it's not already installed." | ||
165 | (unless (package-installed-p pkg) | ||
166 | (package-install pkg))) | ||
167 | |||
168 | (defun minibuffer-delete-directory () | ||
169 | (interactive) | ||
170 | (let ((here (point)) | ||
171 | (meta (completion-metadata | ||
172 | "" minibuffer-completion-table | ||
173 | minibuffer-completion-predicate))) | ||
174 | (if (eq (completion-metadata-get meta 'category) 'file) | ||
175 | (when (search-backward "/" (minibuffer-prompt-end) t) | ||
176 | (delete-region (point) here)) | ||
177 | (backward-kill-word 1)))) | ||
178 | |||
179 | ;;; Basic settings | 26 | ;;; Basic settings |
180 | 27 | ||
181 | (recancel-colors) | 28 | ;; Environment |
182 | (tooltip-mode -1) | 29 | (setenv "PAGER" "cat") ; emacs is a pager |
30 | (setenv "TERM" "dumb") ; no fancy graphics! | ||
31 | (setenv "NO_COLOR" "1") ; no color! | ||
32 | |||
33 | ;; Startup | ||
34 | (setopt inhibit-startup-screen t) | ||
35 | (setopt initial-buffer-choice #'eshell) | ||
36 | (setopt initial-scratch-message ";; *scratch*") | ||
37 | (setopt initial-major-mode #'emacs-lisp-mode) | ||
183 | 38 | ||
184 | ;; Dialogs | 39 | ;; Dialogs |
185 | (setopt use-dialog-box nil) | 40 | (setopt use-dialog-box nil) |
@@ -191,21 +46,28 @@ With ARG, edit in other window." | |||
191 | ;; Cursor | 46 | ;; Cursor |
192 | (blink-cursor-mode -1) | 47 | (blink-cursor-mode -1) |
193 | 48 | ||
194 | ;; Fonts | ||
195 | (setopt x-underline-at-descent-line t) | ||
196 | (run-after-frame-init #'setup-faces) | ||
197 | |||
198 | ;;; Look and feel | ||
199 | |||
200 | ;; Whitespace | 49 | ;; Whitespace |
201 | (setopt whitespace-style '(face trailing tabs tab-mark)) | 50 | (setopt whitespace-style '(face trailing tabs tab-mark)) |
202 | (setopt whitespace-global-modes '(not rcirc-mode)) | 51 | (setopt whitespace-global-modes '(not rcirc-mode jabber-chat-mode)) |
203 | (global-whitespace-mode) | 52 | (global-whitespace-mode) |
204 | (add-hook 'before-save-hook #'delete-trailing-whitespace-except-current-line) | 53 | (add-hook 'before-save-hook #'delete-trailing-whitespace-except-current-line) |
54 | (add-hook 'after-init-hook | ||
55 | (lambda () (add-hook 'before-save-hook #'indent-buffer+))) | ||
205 | (set-face-attribute 'whitespace-tab nil :background nil :foreground "#888") | 56 | (set-face-attribute 'whitespace-tab nil :background nil :foreground "#888") |
206 | (setf (alist-get 'tab-mark whitespace-display-mappings) | 57 | (setf (alist-get 'tab-mark whitespace-display-mappings) |
207 | '(9 [?· 9] [?» 9] [?\\ 9])) | 58 | '(9 [?· 9] [?» 9] [?\\ 9])) |
208 | 59 | ||
60 | ;;; UI stuff | ||
61 | |||
62 | (setopt tab-bar-show 1) | ||
63 | |||
64 | ;; Fixed-pitch | ||
65 | (package-ensure '(fixed-pitch-mode | ||
66 | :url "https://github.com/cstby/fixed-pitch-mode.git")) | ||
67 | (setopt cursor-type 'bar) | ||
68 | (require 'fixed-pitch) | ||
69 | (add-to-list 'fixed-pitch-whitelist-hooks 'vc-dir-mode-hook) | ||
70 | |||
209 | ;;; Completions | 71 | ;;; Completions |
210 | 72 | ||
211 | (setopt tab-always-indent 'complete) | 73 | (setopt tab-always-indent 'complete) |
@@ -251,6 +113,14 @@ With ARG, edit in other window." | |||
251 | (add-hook 'completion-list-mode-hook #'truncate-lines-local-mode) | 113 | (add-hook 'completion-list-mode-hook #'truncate-lines-local-mode) |
252 | (add-hook 'minibuffer-setup-hook #'truncate-lines-local-mode) | 114 | (add-hook 'minibuffer-setup-hook #'truncate-lines-local-mode) |
253 | 115 | ||
116 | (package-ensure 'visual-fill-column) | ||
117 | (setopt visual-fill-column-enable-sensible-window-split t) | ||
118 | (add-hook 'visual-line-mode-hook #'visual-fill-column-mode) | ||
119 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust) | ||
120 | |||
121 | (package-ensure 'adaptive-wrap) | ||
122 | (add-hook 'visual-fill-column-mode #'adaptive-wrap-prefix-mode) | ||
123 | |||
254 | ;; Consult/Marginalia | 124 | ;; Consult/Marginalia |
255 | 125 | ||
256 | (package-ensure 'consult) | 126 | (package-ensure 'consult) |
@@ -275,8 +145,7 @@ With ARG, edit in other window." | |||
275 | (keymap-set isearch-mode-map "M-s e" #'consult-isearch-history) | 145 | (keymap-set isearch-mode-map "M-s e" #'consult-isearch-history) |
276 | (keymap-set isearch-mode-map "M-s l" #'consult-line) | 146 | (keymap-set isearch-mode-map "M-s l" #'consult-line) |
277 | (setopt xref-show-xrefs-function #'consult-xref) | 147 | (setopt xref-show-xrefs-function #'consult-xref) |
278 | (setopt xref-show-definitions-function | 148 | (setopt xref-show-definitions-function #'xref-show-definitions-completing-read) |
279 | #'xref-show-definitions-completing-read) | ||
280 | (setopt consult-preview-key "M-.") | 149 | (setopt consult-preview-key "M-.") |
281 | 150 | ||
282 | (package-ensure 'marginalia) | 151 | (package-ensure 'marginalia) |
@@ -375,7 +244,7 @@ With ARG, edit in other window." | |||
375 | (setopt isearch-lazy-count t) | 244 | (setopt isearch-lazy-count t) |
376 | (setopt isearch-regexp-lax-whitespace t) | 245 | (setopt isearch-regexp-lax-whitespace t) |
377 | (setopt isearch-wrap-pause 'no) | 246 | (setopt isearch-wrap-pause 'no) |
378 | (setopt search-whitespace-regexp ".*?") ; swiper-style | 247 | (setopt search-whitespace-regexp "[ ]+") |
379 | (setopt search-ring-max 256) | 248 | (setopt search-ring-max 256) |
380 | (setopt regexp-search-ring-max 256) | 249 | (setopt regexp-search-ring-max 256) |
381 | 250 | ||
@@ -400,18 +269,18 @@ With ARG, edit in other window." | |||
400 | 269 | ||
401 | ;;; Keybinds | 270 | ;;; Keybinds |
402 | 271 | ||
403 | (keymap-global-set "C-x C-c" #'save-buffers-kill-terminal) | ||
404 | (keymap-global-set "C-x C-k" #'kill-buffer-dwim) | 272 | (keymap-global-set "C-x C-k" #'kill-buffer-dwim) |
405 | (keymap-global-set "M-o" #'other-window-dwim) | 273 | (keymap-global-set "M-o" #'other-window-dwim) |
406 | (keymap-global-set "C-x o" #'other-window-dwim) | 274 | (keymap-global-set "C-x o" #'other-window-dwim) |
407 | (keymap-global-set "C-x 0" #'delete-window-dwim) | 275 | (keymap-global-set "C-x 0" #'delete-window-dwim) |
408 | (keymap-global-set "M-SPC" #'cycle-spacing*) | 276 | (keymap-global-set "M-SPC" #'cycle-spacing*) |
277 | (keymap-global-set "C-M-\\" #'indent-buffer+) | ||
278 | |||
279 | (keymap-global-set "C-x C-c" #'save-buffers-kill*) | ||
409 | (keymap-global-set "C-x C-b" #'ibuffer) | 280 | (keymap-global-set "C-x C-b" #'ibuffer) |
410 | (keymap-global-set "M-/" #'hippie-expand) | 281 | (keymap-global-set "M-/" #'hippie-expand) |
411 | (keymap-global-set "M-u" #'universal-argument) | 282 | (keymap-global-set "M-u" #'universal-argument) |
412 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) | 283 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) |
413 | (keymap-global-set "C-c i" #'find-user-init-file) | ||
414 | (keymap-global-set "C-c p" #'find-user-private-file) | ||
415 | (keymap-global-set "C-c s" #'eshell) | 284 | (keymap-global-set "C-c s" #'eshell) |
416 | 285 | ||
417 | (keymap-global-set "C-c d" | 286 | (keymap-global-set "C-c d" |
@@ -419,14 +288,17 @@ With ARG, edit in other window." | |||
419 | (interactive) | 288 | (interactive) |
420 | (insert (format-time-string "%FT%TZ" (current-time) t)))) | 289 | (insert (format-time-string "%FT%TZ" (current-time) t)))) |
421 | 290 | ||
422 | (keymap-global-set "C-M-\\" | 291 | (keymap-global-set "C-c i" |
423 | (defun indent-buffer () | 292 | (define-keymap |
424 | (interactive) | 293 | :prefix 'find-init-map |
425 | (save-mark-and-excursion | 294 | "i" (find-user-file init) |
426 | (indent-region (point-min) (point-max)) | 295 | "e" (find-user-file early-init |
427 | (if (apply #'derived-mode-p space-indent-modes) | 296 | (locate-user-emacs-file "early-init.el")) |
428 | (untabify (point-min) (point-max)) | 297 | "c" (find-user-file custom custom-file) |
429 | (tabify (point-min) (point-max)))))) | 298 | "p" (find-user-file private) |
299 | "t" (find-user-file brianna | ||
300 | (locate-user-emacs-file "brianna-theme.el")) | ||
301 | "s" #'scratch-buffer)) | ||
430 | 302 | ||
431 | (keymap-global-set "C-c t" | 303 | (keymap-global-set "C-c t" |
432 | (define-keymap | 304 | (define-keymap |
@@ -448,47 +320,19 @@ With ARG, edit in other window." | |||
448 | ;; Key settings | 320 | ;; Key settings |
449 | (setopt set-mark-command-repeat-pop t) | 321 | (setopt set-mark-command-repeat-pop t) |
450 | 322 | ||
451 | ;;; Writing | 323 | ;;; Text-editing packages |
452 | |||
453 | (add-hook 'text-mode-hook #'visual-line-mode) | ||
454 | (add-hook 'text-mode-hook #'auto-fill-mode) | ||
455 | |||
456 | ;;; Hungry delete | ||
457 | ;; I was using the hungry-delete package, but it turns out I can get *most* of | ||
458 | ;; the features with just these functions. | ||
459 | |||
460 | (defun %hungry-delete (skip-fn del-key) | ||
461 | (let ((here (point))) | ||
462 | (funcall skip-fn " \t") | ||
463 | (if (or (= (point) here) | ||
464 | (apply 'derived-mode-p | ||
465 | '(eshell-mode ; add other modes to skip here. | ||
466 | nim-mode | ||
467 | pyton-mode))) | ||
468 | (call-interactively (keymap-lookup (list (current-local-map) | ||
469 | (current-global-map)) | ||
470 | del-key)) | ||
471 | (delete-region (point) here)))) | ||
472 | |||
473 | (defun hungry-delete-forward () | ||
474 | "Delete forward, hungrily." | ||
475 | (interactive) | ||
476 | (%hungry-delete #'skip-chars-forward "C-d")) | ||
477 | 324 | ||
478 | (defun hungry-delete-backward () | 325 | ;; Hungry delete |
479 | "Delete backward, hungrily." | 326 | (package-ensure 'hungry-delete) |
480 | (interactive) | 327 | (setopt hungry-delete-chars-to-skip " \t") |
481 | (%hungry-delete #'skip-chars-backward "DEL")) | 328 | (with-eval-after-load 'hungry-delete |
329 | (add-to-list 'hungry-delete-except-modes 'eshell-mode) | ||
330 | (add-to-list 'hungry-delete-except-modes 'eww-mode)) | ||
331 | (global-hungry-delete-mode) | ||
482 | 332 | ||
483 | (define-minor-mode hungry-delete-mode | 333 | ;;; Writing |
484 | "Hungrily delete stuff." | ||
485 | :global t | ||
486 | :lighter " h" | ||
487 | :keymap (define-keymap | ||
488 | "DEL" #'hungry-delete-backward | ||
489 | "C-d" #'hungry-delete-forward)) | ||
490 | 334 | ||
491 | (hungry-delete-mode) | 335 | (add-hook 'text-mode-hook #'visual-line-mode) |
492 | 336 | ||
493 | ;;; Programming | 337 | ;;; Programming |
494 | 338 | ||
@@ -498,17 +342,6 @@ With ARG, edit in other window." | |||
498 | (setopt perl-indent-level tab-width) | 342 | (setopt perl-indent-level tab-width) |
499 | (setopt c-basic-offset tab-width) | 343 | (setopt c-basic-offset tab-width) |
500 | 344 | ||
501 | ;; Elisp | ||
502 | (defun pulse@eval (start end &rest _) | ||
503 | (pulse-momentary-highlight-region start end)) | ||
504 | |||
505 | (keymap-set emacs-lisp-mode-map "C-c C-c" #'eval-defun) | ||
506 | (keymap-set emacs-lisp-mode-map "C-c C-b" | ||
507 | (defun eval-buffer@pulse () (interactive) | ||
508 | (eval-buffer) | ||
509 | (pulse@eval (point-min) (point-max)))) | ||
510 | (advice-add 'eval-region :after #'pulse@eval) | ||
511 | |||
512 | (defvar space-indent-modes '(emacs-lisp-mode | 345 | (defvar space-indent-modes '(emacs-lisp-mode |
513 | lisp-interaction-mode | 346 | lisp-interaction-mode |
514 | lisp-mode | 347 | lisp-mode |
@@ -520,10 +353,19 @@ With ARG, edit in other window." | |||
520 | css-mode) | 353 | css-mode) |
521 | "Modes to indent with spaces, not tabs.") | 354 | "Modes to indent with spaces, not tabs.") |
522 | 355 | ||
523 | (defun indent-tabs-mode-maybe () | 356 | (add-hook 'prog-mode-hook |
524 | (setq indent-tabs-mode | 357 | (defun indent-tabs-mode-maybe () |
525 | (if (apply #'derived-mode-p space-indent-modes) nil t))) | 358 | (setq indent-tabs-mode |
526 | (add-hook 'prog-mode-hook #'indent-tabs-mode-maybe) | 359 | (if (apply #'derived-mode-p space-indent-modes) nil t)))) |
360 | |||
361 | ;; Elisp | ||
362 | (keymap-set emacs-lisp-mode-map "C-c C-c" #'eval-defun) | ||
363 | (keymap-set emacs-lisp-mode-map "C-c C-b" | ||
364 | (defun eval-buffer@pulse () (interactive) | ||
365 | (eval-buffer) | ||
366 | (pulse-momentary-highlight-region (point-min) (point-max)))) | ||
367 | (advice-add 'eval-region :after #'pulse@eval) | ||
368 | (add-hook 'emacs-lisp-mode-hook #'elisp-enable-lexical-binding) | ||
527 | 369 | ||
528 | ;; Makefile | 370 | ;; Makefile |
529 | (setopt makefile-backslash-align nil) | 371 | (setopt makefile-backslash-align nil) |
@@ -561,11 +403,10 @@ With ARG, edit in other window." | |||
561 | (advice-add 'geiser-eval-region :after #'pulse@eval) | 403 | (advice-add 'geiser-eval-region :after #'pulse@eval) |
562 | 404 | ||
563 | ;; VC | 405 | ;; VC |
564 | (add-hook 'vc-dir-mode-hook #'hl-line-mode) | 406 | (keymap-global-set "C-x v j" |
565 | (defun vc-jump () | 407 | (defun vc-jump () |
566 | (interactive) | 408 | (interactive) |
567 | (vc-dir default-directory)) | 409 | (vc-dir default-directory))) |
568 | (keymap-global-set "C-x v j" #'vc-jump) | ||
569 | 410 | ||
570 | ;;; Compilation | 411 | ;;; Compilation |
571 | 412 | ||
@@ -582,15 +423,13 @@ With ARG, edit in other window." | |||
582 | (add-hook 'prog-mode-hook #'auto-fill-mode) | 423 | (add-hook 'prog-mode-hook #'auto-fill-mode) |
583 | (add-hook 'prog-mode-hook #'electric-pair-local-mode) | 424 | (add-hook 'prog-mode-hook #'electric-pair-local-mode) |
584 | (global-display-fill-column-indicator-mode) | 425 | (global-display-fill-column-indicator-mode) |
585 | (delete-selection-mode) | 426 | (setopt x-underline-at-descent-line t) |
586 | (global-so-long-mode) | ||
587 | (global-goto-address-mode) | ||
588 | (context-menu-mode) | ||
589 | (setopt scroll-conservatively 101) | 427 | (setopt scroll-conservatively 101) |
590 | (setopt display-fill-column-indicator-character ?·) | 428 | (setopt display-fill-column-indicator-character ?·) |
591 | (setopt disabled-command-function nil) | 429 | (setopt disabled-command-function nil) |
592 | (setopt electric-pair-skip-whitespace 'chomp) | 430 | (setopt electric-pair-skip-whitespace 'chomp) |
593 | (setopt fill-column 80) | 431 | (setopt fill-column 80) |
432 | (setopt finger-X.500-host-regexps '(".*tilde.*")) | ||
594 | (setopt recenter-positions '(top middle bottom)) | 433 | (setopt recenter-positions '(top middle bottom)) |
595 | (setopt eval-expression-print-level nil) | 434 | (setopt eval-expression-print-level nil) |
596 | (setopt eval-expression-print-length nil) | 435 | (setopt eval-expression-print-length nil) |
@@ -599,12 +438,19 @@ With ARG, edit in other window." | |||
599 | (setopt show-paren-when-point-in-periphery t) | 438 | (setopt show-paren-when-point-in-periphery t) |
600 | (setopt show-paren-when-point-inside-paren t) | 439 | (setopt show-paren-when-point-inside-paren t) |
601 | (show-paren-mode) | 440 | (show-paren-mode) |
441 | (delete-selection-mode) | ||
442 | (global-so-long-mode) | ||
443 | (global-goto-address-mode) | ||
444 | (context-menu-mode) | ||
445 | (tooltip-mode -1) | ||
602 | 446 | ||
603 | (with-eval-after-load 'ibuffer | 447 | (add-hook 'special-mode-hook |
604 | (add-hook 'ibuffer-mode-hook #'hl-line-mode)) | 448 | (defun hl-line@special-mode () |
605 | 449 | (unless (derived-mode-p 'help-mode ; add other modes here | |
606 | (with-eval-after-load 'proced | 450 | 'Info-mode |
607 | (add-hook 'proced-mode-hook #'hl-line-mode)) | 451 | 'eww-mode) |
452 | (hl-line-mode)))) | ||
453 | (add-hook 'dired-mode-hook #'hl-line-mode) | ||
608 | 454 | ||
609 | ;;; RCIRC | 455 | ;;; RCIRC |
610 | 456 | ||
@@ -623,6 +469,33 @@ With ARG, edit in other window." | |||
623 | (visual-line-mode) | 469 | (visual-line-mode) |
624 | (setq default-directory (expand-file-name "~")))) | 470 | (setq default-directory (expand-file-name "~")))) |
625 | 471 | ||
472 | ;;; Jabber | ||
473 | |||
474 | (package-ensure 'jabber) | ||
475 | (with-eval-after-load 'jabber | ||
476 | (require 'jabber-httpupload nil t) | ||
477 | ;; I wish jabber.el didn't clobber C-x C-j ... | ||
478 | (keymap-global-set "C-x C-j" #'dired-jump) | ||
479 | (keymap-global-set "C-c j" jabber-global-keymap) | ||
480 | (map-keymap (lambda (key cmd) | ||
481 | (define-key jabber-global-keymap (vector (+ key #x60)) cmd)) | ||
482 | jabber-global-keymap) | ||
483 | ;; This is just a dang good idea | ||
484 | (keymap-global-set "C-c C-SPC" #'jabber-activity-switch-to)) | ||
485 | |||
486 | (setopt jabber-activity-make-strings #'jabber-activity-make-strings-shorten) | ||
487 | (setopt jabber-activity-query-unread nil) | ||
488 | (setopt jabber-auto-reconnect t) | ||
489 | (setopt jabber-browse-buffer-format "%n<browse>") | ||
490 | (setopt jabber-chat-buffer-format "%n") | ||
491 | (setopt jabber-groupchat-buffer-format "%b") | ||
492 | (setopt jabber-muc-private-buffer-format "%n<%g>") | ||
493 | |||
494 | (add-hook 'jabber-post-connect-hooks #'jabber-enable-carbons) | ||
495 | (add-hook 'jabber-chat-mode-hook #'visual-line-mode) | ||
496 | (remove-hook 'jabber-alert-muc-hooks #'jabber-muc-echo) | ||
497 | (remove-hook 'jabber-alert-presence-hooks #'jabber-presence-echo) | ||
498 | |||
626 | ;;; Eshell | 499 | ;;; Eshell |
627 | 500 | ||
628 | (setopt eshell-banner-message | 501 | (setopt eshell-banner-message |
@@ -632,12 +505,10 @@ With ARG, edit in other window." | |||
632 | (setopt eshell-prompt-function | 505 | (setopt eshell-prompt-function |
633 | (defun @eshell-prompt () | 506 | (defun @eshell-prompt () |
634 | (let ((rootp (zerop (user-uid)))) | 507 | (let ((rootp (zerop (user-uid)))) |
635 | (propertize | 508 | (concat "( " |
636 | (concat "( " | ||
637 | (abbreviate-file-name (eshell/pwd)) | 509 | (abbreviate-file-name (eshell/pwd)) |
638 | (if rootp ":root" "") | 510 | (if rootp ":root" "") |
639 | " ) ") | 511 | " ) ")))) |
640 | 'face 'bold)))) | ||
641 | (setopt eshell-prompt-regexp "^(.*) ") | 512 | (setopt eshell-prompt-regexp "^(.*) ") |
642 | 513 | ||
643 | ;;; Browsing | 514 | ;;; Browsing |
@@ -650,17 +521,30 @@ With ARG, edit in other window." | |||
650 | (setopt dired-recursive-deletes 'always) | 521 | (setopt dired-recursive-deletes 'always) |
651 | (setopt dired-auto-revert-buffer t) | 522 | (setopt dired-auto-revert-buffer t) |
652 | (setopt dired-hide-details-hide-symlink-targets nil) | 523 | (setopt dired-hide-details-hide-symlink-targets nil) |
524 | (add-hook 'dired-mode-hook #'dired-hide-details-mode) | ||
525 | (add-hook 'dired-mode-hook #'truncate-lines-local-mode) | ||
653 | (with-eval-after-load 'dired | 526 | (with-eval-after-load 'dired |
654 | (require 'dired-x) | 527 | (require 'dired-x) |
655 | (add-hook 'dired-mode-hook #'dired-hide-details-mode) | 528 | (keymap-set dired-mode-map "C-j" #'dired-up-directory) |
656 | (add-hook 'dired-mode-hook #'hl-line-mode) | 529 | (setopt dired-omit-files (regexp-concat dired-omit-files |
657 | (add-hook 'dired-mode-hook #'truncate-lines-local-mode) | 530 | "^\\..+$" |
658 | (keymap-set dired-mode-map "C-j" #'dired-up-directory)) | 531 | ;; CHICKEN ... this may be overkill |
532 | "\\.s?o$" | ||
533 | "\\.import\\.scm$" | ||
534 | "\\.\\(build\\|install\\)\\.sh$" | ||
535 | "\\.link$")) | ||
536 | (add-hook 'dired-mode-hook #'dired-omit-mode) | ||
537 | (keymap-set dired-mode-map ")" #'dired-omit-mode)) | ||
659 | 538 | ||
660 | ;; Elpher (gemini/gopher) | 539 | ;; Elpher (gemini/gopher) |
661 | (package-ensure 'elpher) | 540 | (package-ensure 'elpher) |
662 | 541 | ||
663 | ;; Browse-url (http) | 542 | ;;; HTTP browsing |
543 | |||
544 | ;; SHR | ||
545 | (setopt shr-max-width (+ fill-column 10)) | ||
546 | |||
547 | ;; Browse-url | ||
664 | (setopt browse-url-new-window-flag t) | 548 | (setopt browse-url-new-window-flag t) |
665 | (setopt browse-url-firefox-arguments '("--new-tab")) | 549 | (setopt browse-url-firefox-arguments '("--new-tab")) |
666 | (setopt browse-url-firefox-new-window-is-tab t) | 550 | (setopt browse-url-firefox-new-window-is-tab t) |
diff --git a/emacs.d/early-init.el b/emacs.d/early-init.el index 2a4f2b5..7374bd1 100644 --- a/emacs.d/early-init.el +++ b/emacs.d/early-init.el | |||
@@ -1,4 +1,4 @@ | |||
1 | ;;; ~/.emacs.d/early-init.el -*- lexical-binding: t -*- | 1 | ;;; ~/.emacs.d/early-init.el -*- lexical-binding: t; -*- |
2 | ;; Author: Case Duckworth <acdw@acdw.net> | 2 | ;; Author: Case Duckworth <acdw@acdw.net> |
3 | 3 | ||
4 | (setopt frame-inhibit-implied-resize t) | 4 | (setopt frame-inhibit-implied-resize t) |
@@ -12,18 +12,19 @@ | |||
12 | 12 | ||
13 | (defvar *fonts* | 13 | (defvar *fonts* |
14 | '((default | 14 | '((default |
15 | :family ("Recursive Mono Casual Static" "DejaVu Sans Mono") | 15 | :family ;;("Recursive Mono Casual Static" "DejaVu Sans Mono") |
16 | ("Public Sans" "DejaVu Sans") | ||
16 | :height 100) | 17 | :height 100) |
17 | (variable-pitch | 18 | (variable-pitch |
18 | :family ("Public Sans" "DejaVu Sans") | 19 | :family ("Public Sans" "DejaVu Sans") |
19 | :height 1.0) | 20 | :height 1.0) |
20 | (fixed-pitch | 21 | (fixed-pitch |
21 | :family ("Recursive Mono Linear Static" "DejaVu Sans Mono")) | 22 | :family ("Recursive Mono Casual Static" "DejaVu Sans Mono")) |
22 | (fixed-pitch-serif | 23 | (fixed-pitch-serif |
23 | :family ("Recursive Mono Linear Static" "DejaVu Sans Mono")))) | 24 | :family ("Recursive Mono Linear Static" "DejaVu Sans Mono")))) |
24 | 25 | ||
25 | (require 'package) | 26 | (require 'package) |
26 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) | 27 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) |
27 | (package-initialize) | 28 | (package-initialize) |
28 | 29 | ||
29 | ;;; Custom functions | 30 | ;;; Custom functions |
@@ -81,7 +82,7 @@ If already so, run FUNC immediately." | |||
81 | :height (or (plist-get spec :height) | 82 | :height (or (plist-get spec :height) |
82 | 'unspecified))) | 83 | 'unspecified))) |
83 | ;; Specialized fonts | 84 | ;; Specialized fonts |
84 | (cl-loop with ffl = (font-family-alist) | 85 | (cl-loop with ffl = (font-family-list) |
85 | for (charset . font) | 86 | for (charset . font) |
86 | in '((latin . "Noto Sans") | 87 | in '((latin . "Noto Sans") |
87 | (han . "Noto Sans CJK SC Regular") | 88 | (han . "Noto Sans CJK SC Regular") |
@@ -183,7 +184,7 @@ Whether it tabifies or untabifies depends on `space-indent-modes'." | |||
183 | (defun package-ensure (pkg) | 184 | (defun package-ensure (pkg) |
184 | "Install PKG if it's not already installed." | 185 | "Install PKG if it's not already installed." |
185 | (unless (package-installed-p pkg) | 186 | (unless (package-installed-p pkg) |
186 | (package-install pkg))) | 187 | (package-vc-install pkg))) |
187 | 188 | ||
188 | (defun minibuffer-delete-directory () | 189 | (defun minibuffer-delete-directory () |
189 | "Delete the last directory in a file-completing minibuffer." | 190 | "Delete the last directory in a file-completing minibuffer." |
@@ -196,3 +197,20 @@ Whether it tabifies or untabifies depends on `space-indent-modes'." | |||
196 | (when (search-backward "/" (minibuffer-prompt-end) t) | 197 | (when (search-backward "/" (minibuffer-prompt-end) t) |
197 | (delete-region (point) here)) | 198 | (delete-region (point) here)) |
198 | (backward-kill-word 1)))) | 199 | (backward-kill-word 1)))) |
200 | |||
201 | (defun save-buffers-kill* (arg) | ||
202 | "Save all the buffers and kill ... something. | ||
203 | If ARG is 1 (called normally), kill the current terminal. | ||
204 | If ARG is 4 (with C-u), kill emacs but ask if there are processes running. | ||
205 | If ARG is 16, kill emacs without asking about processes." | ||
206 | (interactive "p") | ||
207 | (pcase arg | ||
208 | (1 (save-buffers-kill-terminal)) | ||
209 | (4 (save-buffers-kill-emacs t)) | ||
210 | (16 (let ((confirm-kill-processes nil) | ||
211 | (kill-emacs-query-functions nil) | ||
212 | (confirm-kill-emacs nil)) | ||
213 | (save-buffers-kill-emacs t))))) | ||
214 | |||
215 | (defun regexp-concat (&rest regexps) | ||
216 | (string-join regexps "\\|")) | ||