diff options
-rw-r--r-- | emacs | 515 | ||||
-rw-r--r-- | emacs.d/bookmarks | 33 | ||||
-rw-r--r-- | emacs.d/brianna-theme.el | 7 | ||||
-rw-r--r-- | emacs.d/early-init.el | 282 |
4 files changed, 690 insertions, 147 deletions
diff --git a/emacs b/emacs index f0f0eb9..5066268 100644 --- a/emacs +++ b/emacs | |||
@@ -1,21 +1,25 @@ | |||
1 | ;;; ~/.emacs -*- mode: emacs-lisp; 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 | ||
5 | ;;; Initialization -- see also ~/.emacs.d/early-init.el | 5 | ;;; Initialization -- see also ~/.emacs.d/early-init.el |
6 | 6 | ||
7 | (setq load-prefer-newer t) | ||
8 | |||
7 | (setopt custom-file (locate-user-emacs-file "custom.el")) | 9 | (setopt custom-file (locate-user-emacs-file "custom.el")) |
8 | (load custom-file :no-error) | 10 | (load custom-file :no-error) |
11 | (add-hook 'Custom-mode-hook | ||
12 | (lambda () (run-with-idle-timer 0.25 nil #'custom-show-all-widgets))) | ||
9 | 13 | ||
10 | (defvar user-private-file (locate-user-emacs-file "private.el") | 14 | (defvar user-private-file (locate-user-emacs-file "private.el") |
11 | "Private customizations") | 15 | "Private customizations") |
12 | ;; make sure it's really private! | 16 | ;; make sure it's really private! |
13 | (and (= (file-attribute-user-id (file-attributes user-private-file)) | 17 | (and (= (file-attribute-user-id (file-attributes user-private-file)) |
14 | (user-uid)) ; is it owned by this me? | 18 | (user-uid)) ; is it owned by this me? |
15 | (set-file-modes user-private-file #o600)) | 19 | (set-file-modes user-private-file #o600)) |
16 | (load user-private-file :no-error) | 20 | (load user-private-file :no-error) |
17 | 21 | ||
18 | (load-theme 'brianna :no-confirm) ; see ~/.emacs.d/brianna-theme.el | 22 | (load-theme 'brianna :no-confirm) ; see ~/.emacs.d/brianna-theme.el |
19 | (add-hook 'after-init-hook #'setup-faces) | 23 | (add-hook 'after-init-hook #'setup-faces) |
20 | 24 | ||
21 | (define-advice startup-echo-area-message (:override ()) | 25 | (define-advice startup-echo-area-message (:override ()) |
@@ -25,16 +29,22 @@ | |||
25 | 29 | ||
26 | ;;; Basic settings | 30 | ;;; Basic settings |
27 | 31 | ||
32 | ;; Auth | ||
33 | (package-ensure '(keepassxc-shim | ||
34 | :url "https://codeberg.org/acdw/keepassxc-shim.el")) | ||
35 | (keepassxc-shim-activate) | ||
36 | (setopt auth-sources '("secrets:default")) | ||
37 | (add-hook 'auth-info-hook #'truncate-lines-local-mode) | ||
38 | |||
28 | ;; Environment | 39 | ;; Environment |
29 | (setenv "PAGER" "cat") ; emacs is a pager | 40 | (setenv "PAGER" "cat") ; emacs is a pager |
30 | (setenv "TERM" "dumb") ; no fancy graphics! | 41 | (setenv "TERM" "dumb") ; no fancy graphics! |
31 | (setenv "NO_COLOR" "1") ; no color! | 42 | (setenv "NO_COLOR" "1") ; no color! |
32 | 43 | ||
33 | ;; Startup | 44 | ;; Startup |
34 | (setopt inhibit-startup-screen t) | 45 | (setopt inhibit-startup-screen t) |
35 | (setopt initial-buffer-choice #'eshell) | 46 | (setopt initial-buffer-choice #'eshell) |
36 | (setopt initial-scratch-message ";; *scratch*") | 47 | (setopt initial-scratch-message nil) |
37 | (setopt initial-major-mode #'emacs-lisp-mode) | ||
38 | 48 | ||
39 | ;; Dialogs | 49 | ;; Dialogs |
40 | (setopt use-dialog-box nil) | 50 | (setopt use-dialog-box nil) |
@@ -47,38 +57,138 @@ | |||
47 | (blink-cursor-mode -1) | 57 | (blink-cursor-mode -1) |
48 | 58 | ||
49 | ;; Whitespace | 59 | ;; Whitespace |
50 | (setopt whitespace-style '(face trailing tabs tab-mark)) | ||
51 | (setopt whitespace-global-modes '(not rcirc-mode jabber-chat-mode)) | ||
52 | ;; (global-whitespace-mode) | ||
53 | (add-hook 'before-save-hook #'delete-trailing-whitespace-except-current-line) | 60 | (add-hook 'before-save-hook #'delete-trailing-whitespace-except-current-line) |
54 | (set-face-attribute 'whitespace-tab nil :background nil :foreground "#888") | ||
55 | (setf (alist-get 'tab-mark whitespace-display-mappings) | ||
56 | '(9 [?· 9] [?» 9] [?\\ 9])) | ||
57 | 61 | ||
58 | (add-hook 'after-init-hook | 62 | (setopt whitespace-style '(face trailing tabs tab-mark)) |
59 | (lambda () (add-hook 'before-save-hook #'indent-buffer+))) | 63 | (setopt whitespace-global-modes '(not rcirc-mode jabber-chat-mode)) |
64 | (global-whitespace-mode) | ||
65 | (hide-minor-mode 'global-whitespace-mode) | ||
66 | (with-eval-after-load 'whitespace | ||
67 | (setf/alist whitespace-display-mappings 'tab-mark | ||
68 | '(9 [?· 9] [?» 9] [?\\ 9]))) | ||
69 | |||
70 | ;; Automatically indent buffer when saving | ||
71 | (define-minor-mode indent-on-save-mode | ||
72 | "Automatically re-indent the buffer on save." | ||
73 | :lighter " >" | ||
74 | (if indent-on-save-mode | ||
75 | (add-hook 'before-save-hook #'fixup-whitespace nil t) | ||
76 | (remove-hook 'before-save-hook #'fixup-whitespace t))) | ||
77 | |||
78 | (add-hook 'prog-mode-hook #'indent-on-save-mode) | ||
79 | |||
80 | ;; Comments | ||
81 | (setopt comment-column 0) | ||
82 | (setopt comment-indent-offset 1) | ||
60 | 83 | ||
61 | ;;; UI stuff | 84 | ;;; UI stuff |
62 | 85 | ||
63 | (setopt tab-bar-show 1) | ||
64 | |||
65 | ;; Elastic-modes | ||
66 | (package-ensure 'dash) ; requirement for `elastic-modes' | ||
67 | (package-ensure '(elastic-modes | ||
68 | :url "https://github.com/jyp/elastic-modes" | ||
69 | :main-file "elastic-pkg.el")) | ||
70 | (require 'elastic-indent) | ||
71 | (add-hook 'prog-mode-hook #'elastic-indent-mode) | ||
72 | 86 | ||
73 | ;; Fixed-pitch | 87 | ;; Fixed-pitch |
74 | (package-ensure '(fixed-pitch-mode | 88 | (define-minor-mode fixed-pitch-mode |
75 | :url "https://github.com/cstby/fixed-pitch-mode.git")) | 89 | "Use a monospace typeface." |
76 | ;; (require 'fixed-pitch) | 90 | :lighter " f" |
91 | (setq cursor-type (if fixed-pitch-mode 'box 'bar)) | ||
92 | (buffer-face-set (and fixed-pitch-mode 'fixed-pitch))) | ||
93 | (define-globalized-minor-mode auto-fixed-pitch-mode | ||
94 | fixed-pitch-mode fixed-pitch-mode | ||
95 | :predicate '(special-mode | ||
96 | prog-mode)) | ||
97 | |||
77 | (setopt cursor-type 'bar) | 98 | (setopt cursor-type 'bar) |
78 | ;; (setopt fixed-pitch-use-extended-default t) | 99 | (hide-minor-mode 'buffer-face-mode) |
79 | ;; (add-to-list 'fixed-pitch-whitelist-hooks 'vc-dir-mode-hook) | 100 | (add-hook 'fixed-pitch-mode-hook #'display-fill-column-indicator-mode) |
80 | ;; (hide-minor-mode 'buffer-face-mode) | 101 | (auto-fixed-pitch-mode) |
81 | ;; (add-hook 'fixed-pitch-mode-hook #'display-fill-column-indicator-mode) | 102 | |
103 | (package-ensure 'valign) ; needed for variable-pitch org-mode | ||
104 | (add-hook 'org-mode-hook #'valign-mode) | ||
105 | (setopt valign-fancy-bar t) | ||
106 | |||
107 | ;;; Mode line | ||
108 | |||
109 | (setopt mode-line-position-line-format '("%l")) | ||
110 | (setopt mode-line-position-column-line-format '("%l:%c")) | ||
111 | |||
112 | (package-ensure 'minions) | ||
113 | |||
114 | (defvar mode-line-major-mode-keymap* | ||
115 | (let ((map (make-sparse-keymap))) | ||
116 | (bindings--define-key map [mode-line down-mouse-1] | ||
117 | `(menu-item "Menu Bar" ignore | ||
118 | :filter ,(lambda (_) (mouse-menu-major-mode-map)))) | ||
119 | (define-key map [mode-line mouse-2] #'describe-mode) | ||
120 | (define-key map [mode-line mouse-3] #'minions-minor-modes-menu) | ||
121 | map) | ||
122 | "Keymap to display on major mode.") | ||
123 | |||
124 | (defun make-mode-line-mode-disabler (lighter help mode) | ||
125 | (propertize lighter | ||
126 | 'help-echo (concat help "\n1:cancel") | ||
127 | 'face 'italic | ||
128 | 'mouse-face 'mode-line-highlight | ||
129 | 'local-map | ||
130 | (make-mode-line-mouse-map | ||
131 | 'mouse-1 (lambda (ev) (interactive "e") | ||
132 | (with-selected-window | ||
133 | (posn-window (event-start ev)) | ||
134 | (funcall mode -1) | ||
135 | (force-mode-line-update)))))) | ||
136 | |||
137 | (setopt mode-line-format | ||
138 | `("%e" | ||
139 | mode-line-front-space | ||
140 | (:propertize ("" mode-line-modified mode-line-remote) | ||
141 | display (min-width (5.0))) | ||
142 | " %[" mode-line-buffer-identification " %]" | ||
143 | (vc-mode (" [" vc-mode "]")) | ||
144 | " ( " | ||
145 | (:propertize ("" mode-name) | ||
146 | help-echo "Major mode\n1:menu\n2:help\n3:minor" | ||
147 | mouse-face mode-line-highlight | ||
148 | local-map ,mode-line-major-mode-keymap*) | ||
149 | (auto-fill-function | ||
150 | ,(make-mode-line-mode-disabler "-f" "Auto-filling" | ||
151 | #'auto-fill-mode)) | ||
152 | (visual-line-mode | ||
153 | ,(make-mode-line-mode-disabler "-v" "Visual lines" | ||
154 | #'visual-line-mode)) | ||
155 | (truncate-lines-local-mode | ||
156 | ,(make-mode-line-mode-disabler "-t" "Truncating lines" | ||
157 | #'truncate-lines-local-mode)) | ||
158 | " " | ||
159 | (defining-kbd-macro (:propertize "🔴" help-echo "Defining kbd macro")) | ||
160 | (isearch-mode (:propertize "🔍" help-echo "Searching")) | ||
161 | (overwrite-mode | ||
162 | ,(make-mode-line-mode-disabler "✒️" "Overwriting" | ||
163 | #'overwrite-mode)) | ||
164 | (debug-on-error | ||
165 | ,(make-mode-line-mode-disabler "‼️" "Debug on error" | ||
166 | (lambda (_) | ||
167 | (setq debug-on-error nil)))) | ||
168 | (debug-on-quit | ||
169 | ,(make-mode-line-mode-disabler "🚫" "Debug on quit" | ||
170 | (lambda (_) | ||
171 | (setq debug-on-quit nil)))) | ||
172 | ") " | ||
173 | (mode-line-process (" " mode-line-process " ")) | ||
174 | " " (:propertize (line-number-mode | ||
175 | (column-number-mode | ||
176 | (:propertize "%l/%c" help-echo "Line/column") | ||
177 | (:propertize "%l" help-echo "Line")) | ||
178 | (column-number-mode | ||
179 | (:propertize "/%c" help-echo "Column") | ||
180 | "")) | ||
181 | display (min-width (5.0))) | ||
182 | (:propertize (" [" (-3 "%o") "]") | ||
183 | help-echo "Position in buffer" | ||
184 | display (min-width (6.0))) | ||
185 | ,(propertize "%n" | ||
186 | 'help-echo "Narrowed\n1:widen" | ||
187 | 'mouse-face 'mode-line-highlight | ||
188 | 'local-map (make-mode-line-mouse-map | ||
189 | 'mouse-1 #'mode-line-widen)) | ||
190 | (so-long-mode-line-info | ||
191 | (" -- " so-long-mode-line-info)))) | ||
82 | 192 | ||
83 | ;;; Completions | 193 | ;;; Completions |
84 | 194 | ||
@@ -99,15 +209,35 @@ | |||
99 | (setopt completions-format 'one-column) | 209 | (setopt completions-format 'one-column) |
100 | (setopt completions-max-height 10) | 210 | (setopt completions-max-height 10) |
101 | 211 | ||
212 | (setf/alist display-buffer-alist "\\`\\*Completions\\*\\'" | ||
213 | '(nil (window-parameters (mode-line-format . " --- %b")))) | ||
214 | |||
102 | (keymap-set minibuffer-local-map "C-p" #'minibuffer-previous-completion) | 215 | (keymap-set minibuffer-local-map "C-p" #'minibuffer-previous-completion) |
103 | (keymap-set minibuffer-local-map "C-n" #'minibuffer-next-completion) | 216 | (keymap-set minibuffer-local-map "C-n" #'minibuffer-next-completion) |
104 | (keymap-set minibuffer-local-map "M-DEL" #'minibuffer-delete-directory) | 217 | (keymap-set minibuffer-local-map "M-DEL" #'minibuffer-delete-directory) |
218 | (keymap-set completion-list-mode-map "C-g" #'quit-window) ; is this a good idea? | ||
219 | |||
220 | ;; Corfu --- tryin this out | ||
221 | |||
222 | (package-ensure 'corfu t) | ||
223 | (keymap-set corfu-map "TAB" #'corfu-next) | ||
224 | (keymap-set corfu-map "<tab>" #'corfu-next) | ||
225 | (keymap-set corfu-map "S-TAB" #'corfu-previous) | ||
226 | (keymap-set corfu-map "<backtab>" #'corfu-previous) | ||
227 | (global-corfu-mode) | ||
228 | |||
229 | ;;; Minibuffer | ||
105 | 230 | ||
106 | (setopt enable-recursive-minibuffers t) | 231 | (setopt enable-recursive-minibuffers t) |
107 | (setopt minibuffer-default-prompt-format " [%s]") | 232 | (setopt minibuffer-default-prompt-format " [%s]") |
108 | (minibuffer-depth-indicate-mode) | 233 | (minibuffer-depth-indicate-mode) |
109 | (minibuffer-electric-default-mode) | 234 | (minibuffer-electric-default-mode) |
110 | 235 | ||
236 | (setopt minibuffer-prompt-properties '( read-only t | ||
237 | cursor-intangible t | ||
238 | face minibuffer-prompt)) | ||
239 | (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) | ||
240 | |||
111 | (setopt file-name-shadow-properties '(invisible t intangible t)) | 241 | (setopt file-name-shadow-properties '(invisible t intangible t)) |
112 | (file-name-shadow-mode) | 242 | (file-name-shadow-mode) |
113 | 243 | ||
@@ -115,6 +245,18 @@ | |||
115 | (setopt history-delete-duplicates t) | 245 | (setopt history-delete-duplicates t) |
116 | (setopt savehist-save-minibuffer-history t) | 246 | (setopt savehist-save-minibuffer-history t) |
117 | (setopt savehist-autosave-interval 5) | 247 | (setopt savehist-autosave-interval 5) |
248 | (setopt savehist-additional-variables | ||
249 | '(kill-ring | ||
250 | command-history | ||
251 | set-variable-value-history | ||
252 | custom-variable-history | ||
253 | query-replace-history | ||
254 | read-expression-history | ||
255 | minibuffer-history | ||
256 | read-char-history | ||
257 | face-name-history | ||
258 | bookmark-history | ||
259 | file-name-history)) | ||
118 | (savehist-mode) | 260 | (savehist-mode) |
119 | 261 | ||
120 | (define-minor-mode truncate-lines-local-mode | 262 | (define-minor-mode truncate-lines-local-mode |
@@ -131,12 +273,12 @@ | |||
131 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust) | 273 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust) |
132 | 274 | ||
133 | (package-ensure 'adaptive-wrap) | 275 | (package-ensure 'adaptive-wrap) |
134 | (add-hook 'visual-fill-column-mode #'adaptive-wrap-prefix-mode) | 276 | (add-hook 'visual-line-mode #'adaptive-wrap-prefix-mode) |
135 | 277 | ||
136 | ;; Consult/Marginalia | 278 | ;;; Completing-read and friends |
137 | 279 | ||
138 | (package-ensure 'consult) | 280 | ;; Consult |
139 | (require 'consult) | 281 | (package-ensure 'consult t) |
140 | (keymap-global-set "C-x b" #'consult-buffer) | 282 | (keymap-global-set "C-x b" #'consult-buffer) |
141 | (keymap-global-set "C-x 4 b" #'consult-buffer-other-window) | 283 | (keymap-global-set "C-x 4 b" #'consult-buffer-other-window) |
142 | (keymap-global-set "C-x 5 b" #'consult-buffer-other-frame) | 284 | (keymap-global-set "C-x 5 b" #'consult-buffer-other-frame) |
@@ -160,9 +302,32 @@ | |||
160 | (setopt xref-show-definitions-function #'xref-show-definitions-completing-read) | 302 | (setopt xref-show-definitions-function #'xref-show-definitions-completing-read) |
161 | (setopt consult-preview-key "M-.") | 303 | (setopt consult-preview-key "M-.") |
162 | 304 | ||
305 | (define-advice completing-read-multiple (:filter-args (args) indicator) | ||
306 | (cons (format "[CRM%s] %s" | ||
307 | (replace-regexp-in-string | ||
308 | "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" | ||
309 | crm-separator) | ||
310 | (car args)) | ||
311 | (cdr args))) | ||
312 | |||
313 | ;; Marginalia | ||
163 | (package-ensure 'marginalia) | 314 | (package-ensure 'marginalia) |
164 | (marginalia-mode) | 315 | (marginalia-mode) |
165 | 316 | ||
317 | ;; Embark | ||
318 | (package-ensure 'embark) | ||
319 | (package-ensure 'embark-consult) | ||
320 | (keymap-global-set "M-." #'embark-dwim) | ||
321 | (keymap-global-set "C-." #'embark-act) | ||
322 | (keymap-global-set "C-h B" #'embark-bindings) | ||
323 | (add-to-list 'display-buffer-alist | ||
324 | '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil | ||
325 | (window-parameters (mode-line-format . none)))) | ||
326 | (add-hook 'embark-collect-mode #'consult-preview-at-point-mode) | ||
327 | (setopt embark-indicators '(embark-mixed-indicator | ||
328 | embark-highlight-indicator | ||
329 | embark-isearch-highlight-indicator)) | ||
330 | |||
166 | ;;; Frames / Windows | 331 | ;;; Frames / Windows |
167 | 332 | ||
168 | (winner-mode) | 333 | (winner-mode) |
@@ -174,14 +339,14 @@ | |||
174 | (global-auto-revert-mode) | 339 | (global-auto-revert-mode) |
175 | 340 | ||
176 | (setopt create-lockfiles nil) | 341 | (setopt create-lockfiles nil) |
177 | (setopt mode-require-final-newline t) | 342 | (setopt require-final-newline t) |
178 | (setopt view-read-only t) | 343 | (setopt view-read-only t) |
179 | (setopt save-silently t) | 344 | (setopt save-silently t) |
180 | (setopt delete-by-moving-to-trash t) | 345 | (setopt delete-by-moving-to-trash t) |
181 | (setopt auto-save-default nil) | 346 | (setopt auto-save-default t) |
182 | (setopt auto-save-no-message t) | 347 | (setopt auto-save-no-message t) |
183 | (setopt auto-save-interval 2) | 348 | (setopt auto-save-interval 30) |
184 | (setopt auto-save-timeout 2) | 349 | (setopt auto-save-timeout 5) |
185 | (setopt auto-save-visited-interval 5) | 350 | (setopt auto-save-visited-interval 5) |
186 | (setopt remote-file-name-inhibit-auto-save t) | 351 | (setopt remote-file-name-inhibit-auto-save t) |
187 | (setopt remote-file-name-inhibit-auto-save-visited t) | 352 | (setopt remote-file-name-inhibit-auto-save-visited t) |
@@ -189,6 +354,19 @@ | |||
189 | `(".*" ,(locate-user-emacs-file "auto-save/") t)) | 354 | `(".*" ,(locate-user-emacs-file "auto-save/") t)) |
190 | (auto-save-visited-mode) | 355 | (auto-save-visited-mode) |
191 | 356 | ||
357 | (add-hook 'window-selection-change-functions | ||
358 | (defun save-old-selected-window-buffer (frame) | ||
359 | (with-current-buffer | ||
360 | (window-buffer (frame-old-selected-window)) | ||
361 | (when (and (buffer-file-name) (buffer-modified-p)) | ||
362 | (save-buffer))))) | ||
363 | |||
364 | (add-hook 'buffer-list-update-hook | ||
365 | (defun save-other-buffer () | ||
366 | (with-current-buffer (other-buffer) | ||
367 | (when (and (buffer-file-name) (buffer-modified-p)) | ||
368 | (save-buffer))))) | ||
369 | |||
192 | (add-function :after after-focus-change-function | 370 | (add-function :after after-focus-change-function |
193 | (defun focus-out-save () | 371 | (defun focus-out-save () |
194 | (save-some-buffers t))) | 372 | (save-some-buffers t))) |
@@ -224,6 +402,8 @@ | |||
224 | 402 | ||
225 | ;; Unique names | 403 | ;; Unique names |
226 | (setopt uniquify-buffer-name-style 'forward) | 404 | (setopt uniquify-buffer-name-style 'forward) |
405 | (setopt uniquify-after-kill-buffer-p t) | ||
406 | (setopt uniquify-ignore-buffers-re "^\\*") | ||
227 | 407 | ||
228 | ;; Persistent undo | 408 | ;; Persistent undo |
229 | (package-ensure 'undo-fu-session) | 409 | (package-ensure 'undo-fu-session) |
@@ -256,7 +436,7 @@ | |||
256 | (setopt isearch-lazy-count nil) | 436 | (setopt isearch-lazy-count nil) |
257 | (setopt isearch-regexp-lax-whitespace t) | 437 | (setopt isearch-regexp-lax-whitespace t) |
258 | (setopt isearch-wrap-pause 'no) | 438 | (setopt isearch-wrap-pause 'no) |
259 | (setopt search-whitespace-regexp "[ ]+") | 439 | (setopt search-whitespace-regexp "[ ]+") |
260 | (setopt search-ring-max 256) | 440 | (setopt search-ring-max 256) |
261 | (setopt regexp-search-ring-max 256) | 441 | (setopt regexp-search-ring-max 256) |
262 | 442 | ||
@@ -265,35 +445,43 @@ | |||
265 | (unless (string-equal "" isearch-string) | 445 | (unless (string-equal "" isearch-string) |
266 | (isearch-update-ring isearch-string isearch-regexp))) | 446 | (isearch-update-ring isearch-string isearch-regexp))) |
267 | 447 | ||
268 | (package-ensure 'isearch-mb) | 448 | (package-ensure 'isearch-mb t) |
269 | (with-eval-after-load 'isearch-mb | 449 | (add-to-list 'isearch-mb--with-buffer #'consult-isearch-history) |
270 | (with-eval-after-load 'consult | 450 | (keymap-set isearch-mb-minibuffer-map "M-r" #'consult-isearch-history) |
271 | (add-to-list 'isearch-mb--with-buffer #'consult-isearch-history) | 451 | (add-to-list 'isearch-mb--after-exit #'consult-line) |
272 | (keymap-set isearch-mb-minibuffer-map "M-r" #'consult-isearch-history) | 452 | (keymap-set isearch-mb-minibuffer-map "M-s l" #'consult-line) |
273 | (add-to-list 'isearch-mb--after-exit #'consult-line) | ||
274 | (keymap-set isearch-mb-minibuffer-map "M-s l" #'consult-line))) | ||
275 | (isearch-mb-mode) | 453 | (isearch-mb-mode) |
276 | 454 | ||
277 | ;; Default to regexen | 455 | ;; Default to regexen |
278 | (setopt search-default-mode t) ; Isearch | 456 | (setopt search-default-mode t) ; Isearch |
279 | (keymap-global-set "M-%" #'query-replace-regexp) | 457 | (keymap-global-set "M-%" #'query-replace-regexp) |
280 | (keymap-global-set "C-M-%" #'query-replace) | 458 | (keymap-global-set "C-M-%" #'query-replace) |
281 | 459 | ||
282 | ;;; Keybinds | 460 | ;;; Keybindings |
283 | 461 | ||
462 | (repeat-mode) | ||
463 | |||
464 | ;; Separate C-<key> and control keys from halcyon ascii days | ||
465 | ;; (define-key input-decode-map [?\C-i] [C-i]) | ||
466 | ;; (define-key input-decode-map [?\C-m] [C-m]) | ||
467 | |||
468 | ;; Modified default keybindings | ||
284 | (keymap-global-set "C-x C-k" #'kill-buffer-dwim) | 469 | (keymap-global-set "C-x C-k" #'kill-buffer-dwim) |
285 | (keymap-global-set "M-o" #'other-window-dwim) | 470 | (keymap-global-set "M-o" #'other-window-dwim) |
286 | (keymap-global-set "C-x o" #'other-window-dwim) | 471 | (keymap-global-set "C-x o" #'other-window-dwim) |
287 | (keymap-global-set "C-x 0" #'delete-window-dwim) | 472 | (keymap-global-set "C-x 0" #'delete-window-dwim) |
288 | (keymap-global-set "M-SPC" #'cycle-spacing*) | 473 | (keymap-global-set "M-SPC" #'cycle-spacing*) |
289 | (keymap-global-set "C-M-\\" #'indent-buffer+) | ||
290 | |||
291 | (keymap-global-set "C-x C-c" #'save-buffers-kill*) | 474 | (keymap-global-set "C-x C-c" #'save-buffers-kill*) |
475 | (keymap-global-set "C-g" #'keyboard-quit*) | ||
476 | (keymap-global-set "C-M-\\" #'fixup-whitespace) | ||
477 | |||
478 | ;; New bindings for existing stuff | ||
292 | (keymap-global-set "C-x C-b" #'ibuffer) | 479 | (keymap-global-set "C-x C-b" #'ibuffer) |
293 | (keymap-global-set "M-/" #'hippie-expand) | 480 | (keymap-global-set "M-/" #'hippie-expand) |
294 | (keymap-global-set "M-u" #'universal-argument) | 481 | (keymap-global-set "M-u" #'universal-argument) |
295 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) | 482 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) |
296 | 483 | ||
484 | ;; Prefix maps | ||
297 | (keymap-global-set "C-c d" | 485 | (keymap-global-set "C-c d" |
298 | (defun insert-current-iso8601 () | 486 | (defun insert-current-iso8601 () |
299 | (interactive) | 487 | (interactive) |
@@ -309,6 +497,8 @@ | |||
309 | "p" (find-user-file private) | 497 | "p" (find-user-file private) |
310 | "t" (find-user-file brianna | 498 | "t" (find-user-file brianna |
311 | (locate-user-emacs-file "brianna-theme.el")) | 499 | (locate-user-emacs-file "brianna-theme.el")) |
500 | "x" (find-user-file exwm | ||
501 | (expand-file-name "~/.exwm")) | ||
312 | "s" #'scratch-buffer)) | 502 | "s" #'scratch-buffer)) |
313 | 503 | ||
314 | (keymap-global-set "C-c t" | 504 | (keymap-global-set "C-c t" |
@@ -319,14 +509,28 @@ | |||
319 | "c" #'column-number-mode | 509 | "c" #'column-number-mode |
320 | "l" #'line-number-mode | 510 | "l" #'line-number-mode |
321 | "L" #'display-line-numbers-mode | 511 | "L" #'display-line-numbers-mode |
322 | "t" #'truncate-lines-local-mode)) | 512 | "t" #'truncate-lines-local-mode |
513 | "o" #'overwrite-mode | ||
514 | "f" #'auto-fill-mode)) | ||
323 | 515 | ||
324 | ;; Un-keybinds | 516 | (keymap-global-set "M-c" |
517 | (define-keymap | ||
518 | :prefix 'case-map | ||
519 | "M-u" #'upcase-dwim "u" #'upcase-dwim | ||
520 | "M-c" #'capitalize-dwim "c" #'capitalize-dwim | ||
521 | "M-l" #'downcase-dwim "l" #'downcase-dwim)) | ||
522 | (put 'upcase-dwim 'repeat-map 'case-map) | ||
523 | (put 'capitalize-dwim 'repeat-map 'case-map) | ||
524 | (put 'downcase-dwim 'repeat-map 'case-map) | ||
525 | |||
526 | ;;; Un-keybinds | ||
527 | ;; Why do I want to zoom with the mouse? | ||
325 | (keymap-global-unset "C-<wheel-down>" t) | 528 | (keymap-global-unset "C-<wheel-down>" t) |
326 | (keymap-global-unset "C-<wheel-up>" t) | 529 | (keymap-global-unset "C-<wheel-up>" t) |
327 | ;; I only ever fat-finger this key and never want to change encoding | 530 | ;; These are ripe for re-binding |
328 | (keymap-global-unset "C-\\" t) | 531 | (keymap-global-unset "C-\\" t) |
329 | (keymap-global-unset "C-z" t) | 532 | (keymap-global-unset "M-l" t) |
533 | (keymap-global-unset "<f2>" t) | ||
330 | 534 | ||
331 | ;; Key settings | 535 | ;; Key settings |
332 | (setopt set-mark-command-repeat-pop t) | 536 | (setopt set-mark-command-repeat-pop t) |
@@ -337,8 +541,11 @@ | |||
337 | (package-ensure 'hungry-delete) | 541 | (package-ensure 'hungry-delete) |
338 | (setopt hungry-delete-chars-to-skip " \t") | 542 | (setopt hungry-delete-chars-to-skip " \t") |
339 | (with-eval-after-load 'hungry-delete | 543 | (with-eval-after-load 'hungry-delete |
340 | (add-to-list 'hungry-delete-except-modes 'eshell-mode) | 544 | (dolist (m '( eshell-mode |
341 | (add-to-list 'hungry-delete-except-modes 'eww-mode)) | 545 | eww-mode |
546 | special-mode | ||
547 | jabber-chat-mode)) | ||
548 | (add-to-list 'hungry-delete-except-modes m))) | ||
342 | (global-hungry-delete-mode) | 549 | (global-hungry-delete-mode) |
343 | 550 | ||
344 | ;;; Writing | 551 | ;;; Writing |
@@ -364,12 +571,13 @@ | |||
364 | css-mode) | 571 | css-mode) |
365 | "Modes to indent with spaces, not tabs.") | 572 | "Modes to indent with spaces, not tabs.") |
366 | 573 | ||
367 | ;; (add-hook 'prog-mode-hook | 574 | (add-hook 'prog-mode-hook |
368 | ;; (defun indent-tabs-mode-maybe () | 575 | (defun indent-tabs-mode-maybe () |
369 | ;; (setq indent-tabs-mode | 576 | (setq indent-tabs-mode |
370 | ;; (if (apply #'derived-mode-p space-indent-modes) nil t)))) | 577 | (if (apply #'derived-mode-p space-indent-modes) nil t)))) |
371 | 578 | ||
372 | (indent-tabs-mode -1) | 579 | ;; Eldoc |
580 | (setopt eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly) | ||
373 | 581 | ||
374 | ;; Elisp | 582 | ;; Elisp |
375 | (keymap-set emacs-lisp-mode-map "C-c C-c" #'eval-defun) | 583 | (keymap-set emacs-lisp-mode-map "C-c C-c" #'eval-defun) |
@@ -385,11 +593,9 @@ | |||
385 | (setopt makefile-cleanup-continuations t) | 593 | (setopt makefile-cleanup-continuations t) |
386 | 594 | ||
387 | (add-hook 'makefile-mode-hook | 595 | (add-hook 'makefile-mode-hook |
388 | (defun makefile-stop-complaining () | 596 | (^local-unhook 'write-file-functions 'makefile-warn-suspicious-lines)) |
389 | (remove-hook 'write-file-functions | 597 | (add-hook 'makefile-mode-hook |
390 | 'makefile-warn-suspicious-lines t) | 598 | (^local-unhook 'write-file-functions 'makefile-warn-continuations)) |
391 | (remove-hook 'write-file-functions | ||
392 | 'makefile-warn-continuations t))) | ||
393 | 599 | ||
394 | ;; Scheme -- CHICKEN | 600 | ;; Scheme -- CHICKEN |
395 | (setopt scheme-program-name (or (executable-find "csi"))) | 601 | (setopt scheme-program-name (or (executable-find "csi"))) |
@@ -416,10 +622,7 @@ | |||
416 | (advice-add 'geiser-eval-region :after #'pulse@eval) | 622 | (advice-add 'geiser-eval-region :after #'pulse@eval) |
417 | 623 | ||
418 | ;; VC | 624 | ;; VC |
419 | (keymap-global-set "C-x v j" | 625 | (keymap-global-set "C-x m" #'vc-jump) |
420 | (defun vc-jump () | ||
421 | (interactive) | ||
422 | (vc-dir default-directory))) | ||
423 | 626 | ||
424 | ;;; Compilation | 627 | ;;; Compilation |
425 | 628 | ||
@@ -430,37 +633,66 @@ | |||
430 | 633 | ||
431 | (package-ensure 'gemtext-mode) | 634 | (package-ensure 'gemtext-mode) |
432 | 635 | ||
433 | ;;; Miscellaneous settings | 636 | ;;; Miscellaneous |
434 | 637 | ||
638 | ;; Settings | ||
435 | (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) | 639 | (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) |
436 | ;; (add-hook 'prog-mode-hook #'auto-fill-mode) | 640 | (add-hook 'messages-buffer-mode-hook |
641 | (^turn-off 'display-fill-column-indicator-mode)) | ||
642 | (add-hook 'prog-mode-hook #'auto-fill-mode) | ||
437 | (add-hook 'prog-mode-hook #'electric-pair-local-mode) | 643 | (add-hook 'prog-mode-hook #'electric-pair-local-mode) |
438 | (setopt x-underline-at-descent-line t) | 644 | (add-to-list 'warning-suppress-types 'comp) |
439 | (setopt scroll-conservatively 101) | 645 | (context-menu-mode) |
440 | (setopt display-fill-column-indicator-character ?·) | 646 | (delete-selection-mode) |
647 | (global-goto-address-mode) | ||
648 | (global-so-long-mode) | ||
649 | (pixel-scroll-precision-mode) | ||
650 | (setopt bookmark-save-flag 1) | ||
441 | (setopt disabled-command-function nil) | 651 | (setopt disabled-command-function nil) |
652 | (setopt display-fill-column-indicator-character ?·) | ||
442 | (setopt electric-pair-skip-whitespace 'chomp) | 653 | (setopt electric-pair-skip-whitespace 'chomp) |
654 | (setopt eval-expression-print-length nil) | ||
655 | (setopt eval-expression-print-level nil) | ||
443 | (setopt fill-column 80) | 656 | (setopt fill-column 80) |
444 | (setopt finger-X.500-host-regexps '(".*tilde.*")) | 657 | (setopt finger-X.500-host-regexps '(".*tilde.*")) |
658 | (setopt help-window-keep-selected t) | ||
659 | (setopt help-window-select t) | ||
660 | (setopt read-extended-command-predicate #'command-completion-default-include-p) | ||
445 | (setopt recenter-positions '(top middle bottom)) | 661 | (setopt recenter-positions '(top middle bottom)) |
446 | (setopt eval-expression-print-level nil) | 662 | (setopt scroll-conservatively 101) |
447 | (setopt eval-expression-print-length nil) | ||
448 | (setopt show-paren-delay 0.01) | 663 | (setopt show-paren-delay 0.01) |
449 | (setopt show-paren-style 'parenthesis) | 664 | (setopt show-paren-style 'parenthesis) |
450 | (setopt show-paren-when-point-in-periphery t) | 665 | (setopt show-paren-when-point-in-periphery t) |
451 | (setopt show-paren-when-point-inside-paren t) | 666 | (setopt show-paren-when-point-inside-paren t) |
667 | (setopt switch-to-buffer-obey-display-actions t) | ||
668 | (setopt tmm-completion-prompt nil) | ||
669 | (setopt tmm-mid-prompt " -- ") | ||
670 | (setopt x-underline-at-descent-line t) | ||
452 | (show-paren-mode) | 671 | (show-paren-mode) |
453 | (delete-selection-mode) | ||
454 | (global-so-long-mode) | ||
455 | (global-goto-address-mode) | ||
456 | (context-menu-mode) | ||
457 | (tooltip-mode -1) | 672 | (tooltip-mode -1) |
458 | 673 | ||
674 | ;; Advice & Hooks | ||
675 | |||
676 | (define-advice canonically-space-region | ||
677 | (:around (orig &rest args) double-space-sentences) | ||
678 | "Always double-space sentences canonically." | ||
679 | (let ((sentence-end-double-space t)) | ||
680 | (apply orig args))) | ||
681 | |||
682 | (define-advice switch-to-buffer (:after (&rest _) normal-mode) | ||
683 | "Automatically determine the mode for non-file buffers." | ||
684 | (when-let ((_ (and (eq major-mode 'fundamental-mode) | ||
685 | (not buffer-file-name))) | ||
686 | (buffer-file-name (buffer-name))) | ||
687 | (normal-mode))) | ||
688 | |||
459 | (add-hook 'special-mode-hook | 689 | (add-hook 'special-mode-hook |
460 | (defun hl-line@special-mode () | 690 | (defun hl-line@special-mode () |
461 | (unless (derived-mode-p 'help-mode ; add other modes here | 691 | (unless (derived-mode-p 'help-mode ; add other modes here |
462 | 'Info-mode | 692 | 'Info-mode |
463 | 'eww-mode) | 693 | 'Man-mode |
694 | 'eww-mode | ||
695 | 'elpher-mode) | ||
464 | (hl-line-mode)))) | 696 | (hl-line-mode)))) |
465 | (add-hook 'dired-mode-hook #'hl-line-mode) | 697 | (add-hook 'dired-mode-hook #'hl-line-mode) |
466 | 698 | ||
@@ -486,6 +718,26 @@ | |||
486 | (setopt jabber-groupchat-buffer-format "%b") | 718 | (setopt jabber-groupchat-buffer-format "%b") |
487 | (setopt jabber-muc-private-buffer-format "%n<%g>") | 719 | (setopt jabber-muc-private-buffer-format "%n<%g>") |
488 | 720 | ||
721 | (defun esc/mls (str) ; escape-mode-line-string | ||
722 | (string-replace "%" "%%" str)) | ||
723 | |||
724 | (setopt jabber-chat-header-line-format | ||
725 | '(" " (:eval (esc/mls (jabber-jid-displayname jabber-chatting-with))) | ||
726 | " :: " (:eval (esc/mls (jabber-fix-status | ||
727 | (get (jabber-jid-symbol jabber-chatting-with) | ||
728 | 'status)))) | ||
729 | " :: " (:eval (esc/mls jabber-events-message)) ;see jabber-events.el | ||
730 | " :: " (:eval (esc/mls jabber-chatstates-message)))) | ||
731 | (setopt jabber-muc-header-line-format | ||
732 | '(" " (:eval (esc/mls (jabber-jid-displayname jabber-group))) | ||
733 | " :: " (:eval (esc/mls jabber-muc-topic)))) | ||
734 | (setopt jabber-muc-private-header-line-format | ||
735 | '(" " (:eval (esc/mls (jabber-jid-resource jabber-chatting-with))) | ||
736 | " in " (:eval (esc/mls (jabber-jid-displayname | ||
737 | (jabber-jid-user jabber-chatting-with)))) | ||
738 | " :: " (:eval (esc/mls jabber-events-message)) | ||
739 | " :: " (:eval (esc/mls jabber-chatstates-message)))) | ||
740 | |||
489 | (add-hook 'jabber-post-connect-hooks #'jabber-enable-carbons) | 741 | (add-hook 'jabber-post-connect-hooks #'jabber-enable-carbons) |
490 | (add-hook 'jabber-chat-mode-hook #'visual-line-mode) | 742 | (add-hook 'jabber-chat-mode-hook #'visual-line-mode) |
491 | (remove-hook 'jabber-alert-muc-hooks #'jabber-muc-echo) | 743 | (remove-hook 'jabber-alert-muc-hooks #'jabber-muc-echo) |
@@ -493,8 +745,8 @@ | |||
493 | 745 | ||
494 | ;;; Eshell | 746 | ;;; Eshell |
495 | 747 | ||
496 | (setopt eshell-banner-message | 748 | (setopt cookie-file (expand-file-name "~/cloud/oblique.txt")) |
497 | (format "%s\n\n" (string-join (process-lines "fortune" "-s") "\n"))) | 749 | (setopt eshell-banner-message (format "%s\n" (cookie cookie-file))) |
498 | (setopt eshell-prompt-function | 750 | (setopt eshell-prompt-function |
499 | (defun @eshell-prompt () | 751 | (defun @eshell-prompt () |
500 | (let ((rootp (zerop (user-uid)))) | 752 | (let ((rootp (zerop (user-uid)))) |
@@ -514,17 +766,7 @@ | |||
514 | (setopt eshell-scroll-to-bottom-on-input 'this) | 766 | (setopt eshell-scroll-to-bottom-on-input 'this) |
515 | (setopt eshell-history-size nil) | 767 | (setopt eshell-history-size nil) |
516 | 768 | ||
517 | (keymap-global-set "C-z" | 769 | (keymap-global-set "C-z" #'popup-eshell) |
518 | (lambda (arg) (interactive "P") | ||
519 | (let ((dd default-directory)) | ||
520 | (eshell arg) | ||
521 | (unless (equal dd default-directory) | ||
522 | (setq default-directory dd) | ||
523 | ;; Is this a good idea, really? | ||
524 | (eshell-bol) | ||
525 | (unless (eolp) | ||
526 | (insert "# ")) | ||
527 | (eshell-send-input))))) | ||
528 | (add-hook 'eshell-first-time-mode-hook | 770 | (add-hook 'eshell-first-time-mode-hook |
529 | (defun @eshell-once () | 771 | (defun @eshell-once () |
530 | (keymap-set eshell-mode-map "C-z" #'quit-window))) | 772 | (keymap-set eshell-mode-map "C-z" #'quit-window))) |
@@ -532,18 +774,22 @@ | |||
532 | ;;; Browsing | 774 | ;;; Browsing |
533 | 775 | ||
534 | ;; Dired (files) | 776 | ;; Dired (files) |
777 | (add-hook 'dired-mode-hook #'dired-hide-details-mode) | ||
778 | (add-hook 'dired-mode-hook #'truncate-lines-local-mode) | ||
779 | (setopt dired-auto-revert-buffer t) | ||
780 | (setopt dired-clean-confirm-killing-deleted-buffers nil) | ||
781 | (setopt dired-create-destination-dirs 'always) | ||
782 | (setopt dired-do-revert-buffer t) | ||
535 | (setopt dired-dwim-target t) | 783 | (setopt dired-dwim-target t) |
536 | (setopt dired-listing-switches "-AlF") | 784 | (setopt dired-hide-details-hide-symlink-targets nil) |
785 | (setopt dired-listing-switches "-AlFhv --group-directories-first") | ||
537 | (setopt dired-ls-F-marks-symlinks t) | 786 | (setopt dired-ls-F-marks-symlinks t) |
787 | (setopt dired-no-confirm '(byte-compile load chgrp chmod chown copy move | ||
788 | hardlink symlink shell touch)) | ||
538 | (setopt dired-recursive-copies 'always) | 789 | (setopt dired-recursive-copies 'always) |
539 | (setopt dired-recursive-deletes 'always) | 790 | (setopt dired-recursive-deletes 'always) |
540 | (setopt dired-auto-revert-buffer t) | ||
541 | (setopt dired-hide-details-hide-symlink-targets nil) | ||
542 | (add-hook 'dired-mode-hook #'dired-hide-details-mode) | ||
543 | (add-hook 'dired-mode-hook #'truncate-lines-local-mode) | ||
544 | (with-eval-after-load 'dired | 791 | (with-eval-after-load 'dired |
545 | (require 'dired-x) | 792 | (require 'dired-x) |
546 | (keymap-set dired-mode-map "C-j" #'dired-up-directory) | ||
547 | (setopt dired-omit-files (regexp-concat dired-omit-files | 793 | (setopt dired-omit-files (regexp-concat dired-omit-files |
548 | "^\\..+$" | 794 | "^\\..+$" |
549 | ;; CHICKEN ... this may be overkill | 795 | ;; CHICKEN ... this may be overkill |
@@ -551,18 +797,75 @@ | |||
551 | "\\.import\\.scm$" | 797 | "\\.import\\.scm$" |
552 | "\\.\\(build\\|install\\)\\.sh$" | 798 | "\\.\\(build\\|install\\)\\.sh$" |
553 | "\\.link$")) | 799 | "\\.link$")) |
800 | (keymap-set dired-mode-map "C-j" #'dired-up-directory) | ||
554 | (add-hook 'dired-mode-hook #'dired-omit-mode) | 801 | (add-hook 'dired-mode-hook #'dired-omit-mode) |
555 | (keymap-set dired-mode-map ")" #'dired-omit-mode)) | 802 | (keymap-set dired-mode-map ")" #'dired-omit-mode)) |
556 | 803 | ||
557 | ;; Elpher (gemini/gopher) | 804 | ;; Elpher (gemini/gopher) |
558 | (package-ensure 'elpher) | 805 | (package-ensure 'elpher) |
806 | (with-eval-after-load 'elpher | ||
807 | ;; Try to emulate eww bindings if possible | ||
808 | (keymap-set elpher-mode-map "l" #'elpher-back) | ||
809 | (keymap-set elpher-mode-map "g" #'elpher-reload) | ||
810 | (keymap-set elpher-mode-map "G" #'elpher-go) | ||
811 | (keymap-set elpher-mode-map "v" #'elpher-view-raw) | ||
812 | (keymap-set elpher-mode-map "E" #'elpher-set-gopher-coding-system)) | ||
559 | 813 | ||
560 | ;;; HTTP browsing | 814 | ;;; HTTP browsing |
561 | 815 | ||
562 | ;; SHR | 816 | ;; Eww / Shr |
563 | (setopt shr-max-width (+ fill-column 10)) | 817 | (setopt shr-max-width nil) ; covered in hook below |
818 | (setopt shr-max-image-proportion 0.9) | ||
819 | (setopt shr-discard-aria-hidden t) | ||
820 | (setopt eww-auto-rename-buffer | ||
821 | (defun title+url () | ||
822 | (when (eq major-mode 'eww-mode) | ||
823 | (let ((title (plist-get eww-data :title)) | ||
824 | (url (plist-get eww-data :url))) | ||
825 | (cond | ||
826 | ((and title url) (format "*eww: %s :: %s" title url)) | ||
827 | ((or title url) (format "*eww: %s") (or title url))))))) | ||
828 | (add-hook 'eww-after-render-hook | ||
829 | (defun eww@visual-line () | ||
830 | (visual-fill-column-mode) | ||
831 | (eww-reload t))) | ||
832 | (with-eval-after-load 'eww | ||
833 | (setopt eww-use-browse-url ".") | ||
834 | (keymap-set eww-mode-map "B" #'bookmark-jump) | ||
835 | (keymap-set eww-mode-map "b" #'bookmark-set) | ||
836 | (keymap-unset eww-mode-map "M-n" t) | ||
837 | (keymap-unset eww-mode-map "M-p" t)) | ||
564 | 838 | ||
565 | ;; Browse-url | 839 | ;; Browse-url |
566 | (setopt browse-url-new-window-flag t) | 840 | (setopt browse-url-browser-function #'eww-browse-url) |
567 | (setopt browse-url-firefox-arguments '("--new-tab")) | 841 | (setopt browse-url-firefox-arguments '("--new-tab")) |
568 | (setopt browse-url-firefox-new-window-is-tab t) | 842 | (setopt browse-url-firefox-new-window-is-tab t) |
843 | (setopt browse-url-generic-args browse-url-firefox-arguments) | ||
844 | (setopt browse-url-generic-program "firefox") | ||
845 | |||
846 | (setopt browse-url-secondary-browser-function #'browse-url-firefox) | ||
847 | |||
848 | (package-ensure 'link-hint) | ||
849 | (keymap-global-set "M-l" | ||
850 | (define-keymap | ||
851 | :prefix 'link-map | ||
852 | "M-l" #'link-hint-open-link "l" #'link-hint-open-link | ||
853 | "M-w" #'link-hint-copy-link "w" #'link-hint-copy-link)) | ||
854 | ;; With link-hint we get avy "for free" | ||
855 | (keymap-global-set "M-j" #'avy-goto-char-timer) | ||
856 | |||
857 | ;; PDFs | ||
858 | (package-ensure 'pdf-tools) | ||
859 | (pdf-loader-install) | ||
860 | |||
861 | ;;; EXWM | ||
862 | |||
863 | (setf/alist display-buffer-alist shell-command-buffer-name-async | ||
864 | '(display-buffer-no-window)) | ||
865 | |||
866 | (when (getenv "DISPLAY") | ||
867 | (package-ensure 'exwm t) | ||
868 | (load (expand-file-name "~/.exwm"))) | ||
869 | |||
870 | ;;; Mu4e | ||
871 | |||
diff --git a/emacs.d/bookmarks b/emacs.d/bookmarks new file mode 100644 index 0000000..05ee99e --- /dev/null +++ b/emacs.d/bookmarks | |||
@@ -0,0 +1,33 @@ | |||
1 | ;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8; mode: lisp-data -*- | ||
2 | ;;; This format is meant to be slightly human-readable; | ||
3 | ;;; nevertheless, you probably don't want to edit it. | ||
4 | ;;; -*- End Of Bookmark File Format Version Stamp -*- | ||
5 | (("~elly/pub" | ||
6 | (filename . "/sshx:town:/home/elly/pub/") | ||
7 | (front-context-string . " /sshx:town:/ho") | ||
8 | (rear-context-string) | ||
9 | (position . 1) | ||
10 | (last-modified 26236 19926 867955 868000)) | ||
11 | ("Planet ACDW" | ||
12 | (front-context-string . "mars, but with e") | ||
13 | (rear-context-string) | ||
14 | (position . 1) | ||
15 | (last-modified 26235 32833 754178 60000) | ||
16 | (location . "https://planet.acdw.net/") | ||
17 | (handler . eww-bookmark-jump)) | ||
18 | ("CHICKEN API" | ||
19 | (front-context-string . "chickadee\n\nIdent") | ||
20 | (rear-context-string) | ||
21 | (position . 1) | ||
22 | (last-modified 26219 43014 969496 46000) | ||
23 | (location . "http://api.call-cc.org/5/doc/") | ||
24 | (handler . eww-bookmark-jump)) | ||
25 | (#1="set-face-attribute" | ||
26 | (position . 1) | ||
27 | (last-modified 26219 41950 249141 418000) | ||
28 | (help-fn . describe-function--helper) | ||
29 | (help-args set-face-attribute "brianna-theme.el") | ||
30 | (position . 1) | ||
31 | (handler . help-bookmark-jump) | ||
32 | (defaults #1# "*Help*")) | ||
33 | ) | ||
diff --git a/emacs.d/brianna-theme.el b/emacs.d/brianna-theme.el index 0b16a41..43223f6 100644 --- a/emacs.d/brianna-theme.el +++ b/emacs.d/brianna-theme.el | |||
@@ -93,12 +93,12 @@ | |||
93 | '(header-line ((t (:background "lavender" :inherit variable-pitch)))) | 93 | '(header-line ((t (:background "lavender" :inherit variable-pitch)))) |
94 | '(minibuffer-prompt ((t (:inherit brianna-prompt)))) | 94 | '(minibuffer-prompt ((t (:inherit brianna-prompt)))) |
95 | '(mode-line ((t (:background "lavender" :inherit variable-pitch)))) | 95 | '(mode-line ((t (:background "lavender" :inherit variable-pitch)))) |
96 | '(mode-line-active ((t ( :box t :background "light goldenrod" | 96 | '(mode-line-active ((t ( :box "black" :background "light goldenrod" |
97 | :inherit mode-line)))) | 97 | :inherit mode-line)))) |
98 | '(mode-line-inactive ((t ( :box "pale goldenrod" :background "pale goldenrod" | 98 | '(mode-line-inactive ((t ( :box "pale goldenrod" :background "pale goldenrod" |
99 | :inherit mode-line)))) | 99 | :inherit mode-line)))) |
100 | '(tab-bar ((t (:inherit mode-line-inactive)))) | 100 | '(tab-bar ((t (:inherit mode-line-inactive)))) |
101 | '(tab-bar-tab ((t ( :background "light goldenrod" :box t | 101 | '(tab-bar-tab ((t ( :weight bold :underline t |
102 | :inherit variable-pitch)))) | 102 | :inherit variable-pitch)))) |
103 | '(tab-bar-tab-inactive ((t ( :background "pale goldenrod" | 103 | '(tab-bar-tab-inactive ((t ( :background "pale goldenrod" |
104 | :inherit variable-pitch)))) | 104 | :inherit variable-pitch)))) |
@@ -165,9 +165,12 @@ | |||
165 | ;; Sh | 165 | ;; Sh |
166 | '(sh-heredoc ((t ( :background "azure" :extend t | 166 | '(sh-heredoc ((t ( :background "azure" :extend t |
167 | :inherit font-lock-string-face)))) | 167 | :inherit font-lock-string-face)))) |
168 | '(sh-quoted-exec ((t ()))) | ||
168 | ;; Widgets | 169 | ;; Widgets |
169 | '(widget-field ((t (:inherit brianna-input-field)))) | 170 | '(widget-field ((t (:inherit brianna-input-field)))) |
170 | '(widget-single-line-field ((t (:inherit brianna-input-field)))) | 171 | '(widget-single-line-field ((t (:inherit brianna-input-field)))) |
172 | ;; Whitespace-mode | ||
173 | '(whitespace-tab ((t (:foreground "#888")))) | ||
171 | ) | 174 | ) |
172 | 175 | ||
173 | (provide-theme 'brianna) | 176 | (provide-theme 'brianna) |
diff --git a/emacs.d/early-init.el b/emacs.d/early-init.el index 7374bd1..b2de2f2 100644 --- a/emacs.d/early-init.el +++ b/emacs.d/early-init.el | |||
@@ -10,18 +10,21 @@ | |||
10 | (vertical-scroll-bars) | 10 | (vertical-scroll-bars) |
11 | (horizontal-scroll-bars))) | 11 | (horizontal-scroll-bars))) |
12 | 12 | ||
13 | (when (getenv "IN_EXWM") | ||
14 | (add-to-list 'default-frame-alist '(fullscreen . fullboth))) | ||
15 | |||
13 | (defvar *fonts* | 16 | (defvar *fonts* |
14 | '((default | 17 | (let ((fixed "Recursive Mono Casual Static") |
15 | :family ;;("Recursive Mono Casual Static" "DejaVu Sans Mono") | 18 | (variable "Recursive Sans Casual Static")) |
16 | ("Public Sans" "DejaVu Sans") | 19 | `((default |
17 | :height 100) | 20 | :family ,variable |
18 | (variable-pitch | 21 | :height 100) |
19 | :family ("Public Sans" "DejaVu Sans") | 22 | (variable-pitch |
20 | :height 1.0) | 23 | :family ,variable) |
21 | (fixed-pitch | 24 | (fixed-pitch |
22 | :family ("Recursive Mono Casual Static" "DejaVu Sans Mono")) | 25 | :family ,fixed) |
23 | (fixed-pitch-serif | 26 | (fixed-pitch-serif |
24 | :family ("Recursive Mono Linear Static" "DejaVu Sans Mono")))) | 27 | :family "Recursive Mono Linear Static")))) |
25 | 28 | ||
26 | (require 'package) | 29 | (require 'package) |
27 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) | 30 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) |
@@ -47,24 +50,6 @@ | |||
47 | (delete-trailing-whitespace (line-end-position) | 50 | (delete-trailing-whitespace (line-end-position) |
48 | (point-max)))) | 51 | (point-max)))) |
49 | 52 | ||
50 | (defun run-after-frame-init (func) | ||
51 | "Run FUNC after the first frame is initialized. | ||
52 | If already so, run FUNC immediately." | ||
53 | (cond | ||
54 | ((daemonp) | ||
55 | (add-hook 'server-after-make-frame-hook func) | ||
56 | (advice-add func :after (lambda () | ||
57 | (remove-hook 'server-after-make-frame-hook | ||
58 | func) | ||
59 | (advice-remove func | ||
60 | 'after-frame-init-removing-advice)) | ||
61 | |||
62 | |||
63 | '((name . after-frame-init-removing-advice)))) | ||
64 | ((not after-init-time) | ||
65 | (add-hook 'after-init-hook func)) | ||
66 | (:else (funcall func)))) | ||
67 | |||
68 | (defun first-found-font (&rest cands) | 53 | (defun first-found-font (&rest cands) |
69 | "Return the first font of CANDS that is installed, or nil." | 54 | "Return the first font of CANDS that is installed, or nil." |
70 | (cl-loop with ffl = (font-family-list) | 55 | (cl-loop with ffl = (font-family-list) |
@@ -77,8 +62,7 @@ If already so, run FUNC immediately." | |||
77 | ;; Default faces | 62 | ;; Default faces |
78 | (cl-loop for (face . spec) in *fonts* | 63 | (cl-loop for (face . spec) in *fonts* |
79 | do (set-face-attribute face nil | 64 | do (set-face-attribute face nil |
80 | :family (apply #'first-found-font | 65 | :family (plist-get spec :family) |
81 | (plist-get spec :family)) | ||
82 | :height (or (plist-get spec :height) | 66 | :height (or (plist-get spec :height) |
83 | 'unspecified))) | 67 | 'unspecified))) |
84 | ;; Specialized fonts | 68 | ;; Specialized fonts |
@@ -171,20 +155,40 @@ With ARG, edit in the other window." file-name) | |||
171 | (funcall (if arg #'find-file-other-window #'find-file) | 155 | (funcall (if arg #'find-file-other-window #'find-file) |
172 | ,file-name)))) | 156 | ,file-name)))) |
173 | 157 | ||
174 | (defun indent-buffer+ () | 158 | (defun fixup-whitespace () |
175 | "Indent the current buffer and (un)`tabify'. | 159 | "Indent the current buffer and (un)`tabify'. |
176 | Whether it tabifies or untabifies depends on `space-indent-modes'." | 160 | Whether it tabifies or untabifies depends on `space-indent-modes'." |
177 | (interactive) | 161 | (interactive) |
178 | (save-mark-and-excursion | 162 | (save-mark-and-excursion |
179 | (indent-region (point-min) (point-max)) | 163 | (indent-region (point-min) (point-max)) |
180 | (if (apply #'derived-mode-p space-indent-modes) | 164 | (if indent-tabs-mode |
181 | (untabify (point-min) (point-max)) | 165 | (tabify (point-min) (point-max)) |
182 | (tabify (point-min) (point-max))))) | 166 | (untabify (point-min) (point-max))) |
167 | (replace-regexp-in-region " $" "" (point-min) (point-max)))) | ||
183 | 168 | ||
184 | (defun package-ensure (pkg) | 169 | (defun package-ensure (pkgspec &optional require) |
185 | "Install PKG if it's not already installed." | 170 | "Install PKG if it's not already installed. |
186 | (unless (package-installed-p pkg) | 171 | REQUIRE means require it after ensuring it's installed." |
187 | (package-vc-install pkg))) | 172 | (let ((pkg (if (listp pkgspec) (car pkgspec) pkgspec))) |
173 | (unless (package-installed-p pkg) | ||
174 | (if (symbolp pkgspec) | ||
175 | (or (ignore-errors | ||
176 | (package-install pkg) | ||
177 | t) | ||
178 | (ignore-errors | ||
179 | (message "Package `%s' not found, refreshing packages" pkg) | ||
180 | (package-refresh-contents) | ||
181 | (package-install pkg) | ||
182 | t) | ||
183 | (ignore-errors | ||
184 | (message "Package `%s' still not found, trying `%s'" | ||
185 | pkg 'pkg-vc-install) | ||
186 | (package-vc-install pkgspec) | ||
187 | t) | ||
188 | (if no-error nil | ||
189 | (error "Can't find package: %s" pkg)))) | ||
190 | (package-vc-install pkgspec)) | ||
191 | (when require (require pkg)))) | ||
188 | 192 | ||
189 | (defun minibuffer-delete-directory () | 193 | (defun minibuffer-delete-directory () |
190 | "Delete the last directory in a file-completing minibuffer." | 194 | "Delete the last directory in a file-completing minibuffer." |
@@ -214,3 +218,203 @@ If ARG is 16, kill emacs without asking about processes." | |||
214 | 218 | ||
215 | (defun regexp-concat (&rest regexps) | 219 | (defun regexp-concat (&rest regexps) |
216 | (string-join regexps "\\|")) | 220 | (string-join regexps "\\|")) |
221 | |||
222 | ;; There is a bug in M-x finger | ||
223 | (defun acdw/finger (user host) | ||
224 | "Finger USER on HOST. | ||
225 | This command uses `finger-X.500-host-regexps' | ||
226 | and `network-connection-service-alist', which see." | ||
227 | ;; One of those great interactive statements that's actually | ||
228 | ;; longer than the function call! The idea is that if the user | ||
229 | ;; uses a string like "pbreton@cs.umb.edu", we won't ask for the | ||
230 | ;; host name. If we don't see an "@", we'll prompt for the host. | ||
231 | (interactive | ||
232 | (let* ((answer (let ((default (ffap-url-at-point))) | ||
233 | (read-string (format-prompt "Finger User" default) nil nil default))) | ||
234 | (index (string-match (regexp-quote "@") answer))) | ||
235 | (if index | ||
236 | (list (substring answer 0 index) | ||
237 | (substring answer (1+ index))) | ||
238 | (list answer | ||
239 | (let ((default (ffap-machine-at-point))) | ||
240 | (read-string (format-prompt "At Host" default) nil nil default)))))) | ||
241 | (let* ((user-and-host (concat user "@" host)) | ||
242 | (process-name (concat "Finger [" user-and-host "]")) | ||
243 | (regexps finger-X.500-host-regexps) | ||
244 | ) ;; found | ||
245 | (and regexps | ||
246 | (while (not (string-match (car regexps) host)) | ||
247 | (setq regexps (cdr regexps)))) | ||
248 | (when regexps | ||
249 | (setq user-and-host user)) | ||
250 | (run-network-program | ||
251 | process-name | ||
252 | host | ||
253 | (cdr (assoc 'finger network-connection-service-alist)) | ||
254 | user-and-host))) | ||
255 | |||
256 | (advice-add 'finger :override #'acdw-finger) | ||
257 | |||
258 | (defun hide-minor-mode (mode &optional hook) | ||
259 | "Hide MODE from the mode-line. | ||
260 | HOOK is used to trigger the action, and defaults to MODE-hook." | ||
261 | (setf (alist-get mode minor-mode-alist) (list "")) | ||
262 | (add-hook (intern (or hook (format "%s-hook" mode))) | ||
263 | (lambda () (hide-minor-mode mode)))) | ||
264 | |||
265 | (defun switch-to-other-buffer () | ||
266 | "Switch to the `other-buffer'." | ||
267 | (interactive) | ||
268 | (switch-to-buffer nil)) | ||
269 | |||
270 | (defun popup-eshell (arg) | ||
271 | "Popup an eshell buffer in the current window." | ||
272 | (interactive "P") | ||
273 | (let ((dd default-directory)) | ||
274 | (eshell arg) | ||
275 | (unless (equal dd default-directory) | ||
276 | (setq default-directory dd) | ||
277 | ;; Is this a good idea, really? | ||
278 | (eshell-bol) | ||
279 | (unless (eolp) | ||
280 | (insert "# ")) | ||
281 | (eshell-send-input)))) | ||
282 | |||
283 | (defun vc-jump (arg) | ||
284 | "Jump to the current project's VC buffer. | ||
285 | With ARG, prompt for the directory." | ||
286 | (interactive "P") | ||
287 | (if arg | ||
288 | (let ((current-prefix-arg nil)) | ||
289 | (call-interactively #'vc-dir)) | ||
290 | (project-vc-dir))) | ||
291 | |||
292 | (defun custom-show-all-widgets () | ||
293 | "toggle all \"More/Hide\" widgets in the current buffer." | ||
294 | ;; From unpackaged | ||
295 | (interactive) | ||
296 | (widget-map-buttons (lambda (widget _) | ||
297 | (pcase (widget-get widget :off) | ||
298 | ("More" (widget-apply-action widget))) | ||
299 | nil))) | ||
300 | |||
301 | (defun quit-minibuffer () | ||
302 | (interactive) | ||
303 | (switch-to-minibuffer) | ||
304 | (minibuffer-keyboard-quit)) | ||
305 | |||
306 | (defun keyboard-quit* (arg) | ||
307 | (interactive "P") | ||
308 | (if arg | ||
309 | (quit-minibuffer) | ||
310 | (keyboard-quit))) | ||
311 | |||
312 | (defun sort-sexps (beg end) | ||
313 | "Sort sexps in region. | ||
314 | Comments stay with the code below." | ||
315 | ;; From unpackaged | ||
316 | (interactive "r") | ||
317 | (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n")))) | ||
318 | (goto-char (match-end 0)))) | ||
319 | (skip-both () (while (cond ((or (nth 4 (syntax-ppss)) | ||
320 | (ignore-errors | ||
321 | (save-excursion | ||
322 | (forward-char 1) | ||
323 | (nth 4 (syntax-ppss))))) | ||
324 | (forward-line 1)) | ||
325 | ((looking-at (rx (1+ (or space "\n")))) | ||
326 | (goto-char (match-end 0))))))) | ||
327 | (save-excursion | ||
328 | (save-restriction | ||
329 | (narrow-to-region beg end) | ||
330 | (goto-char beg) | ||
331 | (skip-both) | ||
332 | (cl-destructuring-bind (sexps markers) | ||
333 | (cl-loop do (skip-whitespace) | ||
334 | for start = (point-marker) | ||
335 | for sexp = (ignore-errors | ||
336 | (read (current-buffer))) | ||
337 | for end = (point-marker) | ||
338 | while sexp | ||
339 | ;; Collect the real string, then one used for sorting. | ||
340 | collect (cons (buffer-substring (marker-position start) | ||
341 | (marker-position end)) | ||
342 | (save-excursion | ||
343 | (goto-char (marker-position start)) | ||
344 | (skip-both) | ||
345 | (buffer-substring (point) | ||
346 | (marker-position end)))) | ||
347 | into sexps | ||
348 | collect (cons start end) | ||
349 | into markers | ||
350 | finally return (list sexps markers)) | ||
351 | (setq sexps (sort sexps (lambda (a b) | ||
352 | (string< (cdr a) (cdr b))))) | ||
353 | (cl-loop for (real . sort) in sexps | ||
354 | for (start . end) in markers | ||
355 | do (progn | ||
356 | (goto-char (marker-position start)) | ||
357 | (insert-before-markers real) | ||
358 | (delete-region (point) (marker-position end))))))))) | ||
359 | |||
360 | (defun ^turn-off (mode) | ||
361 | "Higher-order function: returns a lambda to turn off MODE." | ||
362 | (lambda () | ||
363 | (funcall mode -1))) | ||
364 | |||
365 | (defun ^local-hook (hook fn) | ||
366 | "Hook FN to HOOK locally in a lambda. | ||
367 | Good for adding to an add-hook." | ||
368 | (lambda () (add-hook hook fn t))) | ||
369 | |||
370 | (defun ^local-unhook (hook fn) | ||
371 | "Remove FN from HOOK locally." | ||
372 | (lambda () (remove-hook hook fn t))) | ||
373 | |||
374 | ;; This needs to be a macro to take advantage of setf magic | ||
375 | (defmacro setf/alist (alist key val &optional testfn) | ||
376 | `(setf (alist-get ,key ,alist nil nil (or ,testfn #'equal)) | ||
377 | ,val)) | ||
378 | |||
379 | (defun unfill-region (beg end) | ||
380 | (interactive "*r") | ||
381 | (let ((fill-column most-positive-fixnum)) | ||
382 | (fill-region beg end))) | ||
383 | |||
384 | (defun unfill-paragraph () | ||
385 | (interactive) | ||
386 | (let ((fill-column most-positive-fixnum)) | ||
387 | (fill-paragraph beg end))) | ||
388 | |||
389 | (defun unfill-buffer () | ||
390 | (interactive) | ||
391 | (unfill-region (point-min) (point-max))) | ||
392 | |||
393 | (defun unfill-buffer/force () | ||
394 | (interactive) | ||
395 | (let ((buffer-read-only nil)) | ||
396 | (unfill-buffer) | ||
397 | (visual-line-mode t))) | ||
398 | |||
399 | (defmacro after (event &rest body) | ||
400 | "Do BODY after EVENT, which can be: | ||
401 | - A feature | ||
402 | - A hook -- if it requires arguments they'll be in the list `args' | ||
403 | - The symbol 'init, which runs on after-init-hook" | ||
404 | (declare (indent 1)) | ||
405 | (let ((lambda-form `(lambda (&rest args) ,@body))) | ||
406 | (pcase event | ||
407 | (`(timer ,ev) `(run-with-timer ,ev nil ,lambda-form)) | ||
408 | (`(idle ,ev) `(run-with-idle-timer ,ev nil ,lambda-form)) | ||
409 | (`(hook ,ev) `(add-hook ',ev ,lambda-form)) | ||
410 | (`init `(after (hook after-init-hook) ,@body)) | ||
411 | ((pred numberp) `(after (timer ,event) ,@body)) | ||
412 | ((pred (lambda (ev) | ||
413 | (and (symbolp ev) | ||
414 | (or (string-suffix-p "-hook" (symbol-name ev)) | ||
415 | (string-suffix-p "-function" (symbol-name ev)) | ||
416 | (string-suffix-p "-functions" (symbol-name ev)))))) | ||
417 | `(after (hook ,event) ,@body)) | ||
418 | ((pred symbolp) `(with-eval-after-load ',event ,@body)) | ||
419 | |||
420 | (_ (error "Can't determine event type" event))))) | ||