diff options
author | Case Duckworth | 2023-01-08 18:19:04 -0600 |
---|---|---|
committer | Case Duckworth | 2023-01-08 18:19:04 -0600 |
commit | 107eab7ef6311a5b5f9c85c179ae83b2e3204094 (patch) | |
tree | 08502e554b3a0cf70b6a4f7aa570aecf479d0229 /basics.el | |
parent | Restart ... again ... again (diff) | |
download | emacs-107eab7ef6311a5b5f9c85c179ae83b2e3204094.tar.gz emacs-107eab7ef6311a5b5f9c85c179ae83b2e3204094.zip |
myeahhhhhh
Diffstat (limited to 'basics.el')
-rw-r--r-- | basics.el | 315 |
1 files changed, 270 insertions, 45 deletions
diff --git a/basics.el b/basics.el index 06f5ece..4e9e0a9 100644 --- a/basics.el +++ b/basics.el | |||
@@ -8,41 +8,15 @@ | |||
8 | 8 | ||
9 | ;;; Code: | 9 | ;;; Code: |
10 | 10 | ||
11 | ;;; Directories | 11 | (push (locate-user-emacs-file "lisp/") load-path) |
12 | (require 'acdw) | ||
12 | 13 | ||
13 | (defmacro defdir (name directory &optional docstring makedir) | 14 | ;;; Directories |
14 | "Define a variable and a function NAME expanding to DIRECTORY. | ||
15 | DOCSTRING is applied to the variable; its default is DIRECTORY's | ||
16 | path. If MAKEDIR is non-nil, the directory and its parents will | ||
17 | be created." | ||
18 | (declare (indent 2) (doc-string 3)) | ||
19 | `(progn | ||
20 | (defvar ,name (expand-file-name ,directory) | ||
21 | ,(concat (or docstring (format "%s" directory)) "\n" | ||
22 | "Defined by `defdir'.")) | ||
23 | (defun ,name (file &optional mkdir) | ||
24 | ,(concat "Expand FILE relative to variable `" (symbol-name name) "'.\n" | ||
25 | "If MKDIR is non-nil, parent directories are created.\n" | ||
26 | "Defined by `defdir'.") | ||
27 | (let ((file-name (expand-file-name | ||
28 | (convert-standard-filename file) ,name))) | ||
29 | (when mkdir | ||
30 | (make-directory (file-name-directory file-name) :parents)) | ||
31 | file-name)) | ||
32 | ,(if makedir | ||
33 | `(make-directory ,directory :parents) | ||
34 | `(unless (file-exists-p ,directory) | ||
35 | (warn "Directory `%s' doesn't exist." ,directory))))) | ||
36 | 15 | ||
37 | (defdir etc/ (locate-user-emacs-file "etc/") | 16 | (defdir etc/ (locate-user-emacs-file "etc/") |
38 | "Where various Emacs files are placed." | 17 | "Where various Emacs files are placed." |
39 | :makedir) | 18 | :makedir) |
40 | 19 | ||
41 | (defdir lisp/ (locate-user-emacs-file "lisp/") | ||
42 | "My bespoke elisp files." | ||
43 | :makedir) | ||
44 | (push lisp/ load-path) | ||
45 | |||
46 | (defdir sync/ "~/Sync/" | 20 | (defdir sync/ "~/Sync/" |
47 | "My Syncthing directory." | 21 | "My Syncthing directory." |
48 | :makedir) | 22 | :makedir) |
@@ -50,7 +24,6 @@ be created." | |||
50 | (defdir private/ (sync/ "emacs/private/") | 24 | (defdir private/ (sync/ "emacs/private/") |
51 | "Private files and stuff." | 25 | "Private files and stuff." |
52 | :makedir) | 26 | :makedir) |
53 | (push private/ load-path) | ||
54 | 27 | ||
55 | (use-package no-littering | 28 | (use-package no-littering |
56 | :ensure t :demand t | 29 | :ensure t :demand t |
@@ -114,6 +87,15 @@ be created." | |||
114 | (file-name-shadow-mode) | 87 | (file-name-shadow-mode) |
115 | (minibuffer-electric-default-mode) | 88 | (minibuffer-electric-default-mode) |
116 | 89 | ||
90 | (define-minor-mode truncate-lines-local-mode | ||
91 | "Truncate lines locally in a buffer." | ||
92 | :lighter " ..." | ||
93 | :group 'display | ||
94 | (setq-local truncate-lines truncate-lines-local-mode)) | ||
95 | |||
96 | (add-hook 'minibuffer-setup-hook #'truncate-lines-local-mode) | ||
97 | |||
98 | |||
117 | (require 'savehist) | 99 | (require 'savehist) |
118 | (setq-default history-length 1024 | 100 | (setq-default history-length 1024 |
119 | history-delete-duplicates t | 101 | history-delete-duplicates t |
@@ -122,13 +104,16 @@ be created." | |||
122 | savehist-autosave-interval 30) | 104 | savehist-autosave-interval 30) |
123 | (savehist-mode) | 105 | (savehist-mode) |
124 | 106 | ||
125 | ;; Undo | ||
126 | (setq-default undo-limit (* 10 1024 1024)) | ||
127 | |||
128 | ;; Killing and yanking | 107 | ;; Killing and yanking |
129 | (setq-default kill-do-not-save-duplicates t | 108 | (setq-default kill-do-not-save-duplicates t |
130 | kill-read-only-ok t | 109 | kill-read-only-ok t |
131 | save-interprogram-paste-before-kill t | 110 | ;; XXX: This setting causes an error message the first time it's |
111 | ;; called: "Selection owner couldn't convert: TIMESTAMP". I have | ||
112 | ;; absolutely no idea why I get this error, but it's generated in | ||
113 | ;; `x_get_foreign_selection'. I also can't inhibit the message or | ||
114 | ;; do anything else with it, so for now, I'll just live with the | ||
115 | ;; message. | ||
116 | save-interprogram-paste-before-kill t | ||
132 | yank-pop-change-selection t) | 117 | yank-pop-change-selection t) |
133 | (delete-selection-mode) | 118 | (delete-selection-mode) |
134 | 119 | ||
@@ -147,14 +132,20 @@ be created." | |||
147 | initial-buffer-choice t | 132 | initial-buffer-choice t |
148 | initial-scratch-message nil) | 133 | initial-scratch-message nil) |
149 | 134 | ||
150 | ;; (menu-bar-mode -1) | 135 | (define-advice startup-echo-area-message (:override ()) |
136 | (if (get-buffer "*Warnings*") | ||
137 | ";_;" | ||
138 | "^_^")) | ||
139 | |||
140 | (menu-bar-mode -1) | ||
151 | (tool-bar-mode -1) | 141 | (tool-bar-mode -1) |
152 | (tooltip-mode -1) | 142 | (tooltip-mode -1) |
153 | 143 | ||
154 | ;; Text editing | 144 | ;; Text editing |
155 | (setq-default fill-column 80 | 145 | (setq-default fill-column 80 |
156 | sentence-end-double-space t | 146 | sentence-end-double-space t |
157 | tab-width 8) | 147 | tab-width 8 |
148 | tab-always-indent 'complete) | ||
158 | (global-so-long-mode) | 149 | (global-so-long-mode) |
159 | 150 | ||
160 | (setq-default show-paren-delay 0.01 | 151 | (setq-default show-paren-delay 0.01 |
@@ -202,7 +193,8 @@ be created." | |||
202 | auto-save-interval 1 | 193 | auto-save-interval 1 |
203 | auto-save-no-message t | 194 | auto-save-no-message t |
204 | auto-save-timeout 1 | 195 | auto-save-timeout 1 |
205 | auto-save-visited-interval 1) | 196 | auto-save-visited-interval 1 |
197 | remote-file-name-inhibit-auto-save-visited t) | ||
206 | (add-to-list 'auto-save-file-name-transforms | 198 | (add-to-list 'auto-save-file-name-transforms |
207 | `(".*" ,(etc/ "auto-save/" t) t)) | 199 | `(".*" ,(etc/ "auto-save/" t) t)) |
208 | (auto-save-visited-mode) | 200 | (auto-save-visited-mode) |
@@ -215,9 +207,9 @@ be created." | |||
215 | 207 | ||
216 | (require 'recentf) | 208 | (require 'recentf) |
217 | (setq-default ;; recentf-save-file (etc/ "recentf" t) | 209 | (setq-default ;; recentf-save-file (etc/ "recentf" t) |
218 | recentf-max-menu-items 500 | 210 | recentf-max-menu-items 500 |
219 | recentf-max-saved-items nil ; Save the whole list | 211 | recentf-max-saved-items nil ; Save the whole list |
220 | recentf-auto-cleanup 'mode) | 212 | recentf-auto-cleanup 'mode) |
221 | (add-to-list 'recentf-exclude etc/) | 213 | (add-to-list 'recentf-exclude etc/) |
222 | (add-to-list 'recentf-exclude "-autoloads.el\\'") | 214 | (add-to-list 'recentf-exclude "-autoloads.el\\'") |
223 | (add-hook 'buffer-list-update-hook #'recentf-track-opened-file) | 215 | (add-hook 'buffer-list-update-hook #'recentf-track-opened-file) |
@@ -225,8 +217,8 @@ be created." | |||
225 | 217 | ||
226 | (require 'saveplace) | 218 | (require 'saveplace) |
227 | (setq-default ;; save-place-file (etc/ "places.el") | 219 | (setq-default ;; save-place-file (etc/ "places.el") |
228 | save-place-forget-unreadable-files (eq system-type | 220 | save-place-forget-unreadable-files (eq system-type |
229 | 'gnu/linux)) | 221 | 'gnu/linux)) |
230 | (save-place-mode) | 222 | (save-place-mode) |
231 | 223 | ||
232 | (require 'uniquify) | 224 | (require 'uniquify) |
@@ -247,10 +239,12 @@ be created." | |||
247 | (startup-redirect-eln-cache native-compile-target-directory)) | 239 | (startup-redirect-eln-cache native-compile-target-directory)) |
248 | 240 | ||
249 | ;; Custom file | 241 | ;; Custom file |
250 | (setq-default custom-file (sync/ "emacs/custom.el")) | 242 | (setq-default custom-file (private/ "custom.el")) |
251 | (define-advice package--save-selected-packages (:around (orig &rest args) no-custom) | 243 | (define-advice package--save-selected-packages |
244 | (:around (orig &rest args) no-custom) | ||
252 | "Don't save `package-selected-packages' to `custom-file'." | 245 | "Don't save `package-selected-packages' to `custom-file'." |
253 | (let ((custom-file null-device)) | 246 | (let ((custom-file (expand-file-name "custom.el" |
247 | temporary-file-directory))) | ||
254 | (apply orig args))) | 248 | (apply orig args))) |
255 | 249 | ||
256 | ;; Goto Address | 250 | ;; Goto Address |
@@ -293,22 +287,56 @@ N spaces." | |||
293 | (global-set-key (kbd "C-x 0") #'delete-window|bury-buffer) | 287 | (global-set-key (kbd "C-x 0") #'delete-window|bury-buffer) |
294 | (global-set-key (kbd "M-SPC") #'+cycle-spacing) | 288 | (global-set-key (kbd "M-SPC") #'+cycle-spacing) |
295 | (global-set-key (kbd "C-x C-k") #'kill-this-buffer) | 289 | (global-set-key (kbd "C-x C-k") #'kill-this-buffer) |
290 | (global-set-key (kbd "C-/") #'undo-only) | ||
291 | (global-set-key (kbd "C-?") #'undo-redo) | ||
292 | |||
293 | (define-key emacs-lisp-mode-map (kbd "C-c C-c") | ||
294 | #'eval-defun) | ||
295 | (define-key emacs-lisp-mode-map (kbd "C-c C-k") | ||
296 | #'elisp-eval-region-or-buffer) | ||
297 | (define-key lisp-interaction-mode-map (kbd "C-c C-c") | ||
298 | #'eval-defun) | ||
299 | (define-key lisp-interaction-mode-map (kbd "C-c C-k") | ||
300 | #'elisp-eval-region-or-buffer) | ||
301 | (define-advice eval-region (:around (orig start end &rest args) pulse) | ||
302 | (apply orig start end args) | ||
303 | (pulse-momentary-highlight-region start end)) | ||
304 | |||
305 | (global-set-key (kbd "C-x C-b") #'ibuffer) | ||
296 | 306 | ||
297 | ;;; Hooks | 307 | ;;; Hooks |
298 | 308 | ||
299 | (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) | 309 | (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) |
310 | |||
300 | (add-hook 'find-file-not-found-functions | 311 | (add-hook 'find-file-not-found-functions |
301 | (defun create-missing-directories () | 312 | (defun create-missing-directories () |
302 | "Automatically create missing directories." | 313 | "Automatically create missing directories." |
303 | (let ((target-dir (file-name-directory buffer-file-name))) | 314 | (let ((target-dir (file-name-directory buffer-file-name))) |
304 | (unless (file-exists-p target-dir) | 315 | (unless (file-exists-p target-dir) |
305 | (make-directory target-dir :parents))))) | 316 | (make-directory target-dir :parents))))) |
317 | |||
306 | (add-hook 'find-file-hook | 318 | (add-hook 'find-file-hook |
307 | (defun vc-remote-off () | 319 | (defun vc-remote-off () |
308 | "Turn VC off when remote." | 320 | "Turn VC off when remote." |
309 | (when (file-remote-p (buffer-file-name)) | 321 | (when (file-remote-p (buffer-file-name)) |
310 | (setq-local vc-handled-backends nil)))) | 322 | (setq-local vc-handled-backends nil)))) |
311 | 323 | ||
324 | (add-hook 'after-init-hook | ||
325 | (defun after-init@emoji-font-setup () | ||
326 | "Set up emoji fonts after init." | ||
327 | (run-with-idle-timer | ||
328 | 1 nil (defun emoji-font-setup () | ||
329 | "Set up emoji fonts." | ||
330 | (let ((ffl (font-family-list))) | ||
331 | (dolist (font '("Noto Emoji" "Noto Color Emoji" | ||
332 | "Segoe UI Emoji" "Apple Color Emoji" | ||
333 | "FreeSans" "FreeMono" "FreeSerif" | ||
334 | "Unifont" "Symbola")) | ||
335 | (when (member font (font-family-list)) | ||
336 | (set-fontset-font t 'symbol | ||
337 | (font-spec :family font) | ||
338 | nil :add)))))))) | ||
339 | |||
312 | ;;; Advice | 340 | ;;; Advice |
313 | 341 | ||
314 | (define-advice switch-to-buffer (:after (&rest _) normal-mode) | 342 | (define-advice switch-to-buffer (:after (&rest _) normal-mode) |
@@ -373,4 +401,201 @@ See also `with-region-or-to-eol'." | |||
373 | (use-package _acdw | 401 | (use-package _acdw |
374 | :load-path private/) | 402 | :load-path private/) |
375 | 403 | ||
404 | (use-package custom-allowed | ||
405 | :load-path "/home/case/src/emacs/custom-allowed/" | ||
406 | :config | ||
407 | (add-to-list 'custom-allowed-variables 'safe-local-variable-values) | ||
408 | (add-to-list 'custom-allowed-variables 'ispell-buffer-session-localwords) | ||
409 | (add-to-list 'custom-allowed-variables 'warning-suppress-types) | ||
410 | (add-to-list 'custom-allowed-variables 'calendar-latitude) | ||
411 | (add-to-list 'custom-allowed-variables 'calendar-longitude) | ||
412 | (add-to-list 'custom-allowed-variables 'user-full-name) | ||
413 | (add-to-list 'custom-allowed-variables 'user-mail-address) | ||
414 | :hook | ||
415 | (after-init-hook . custom-allowed-load-custom-file)) | ||
416 | |||
417 | (use-package sophomore | ||
418 | :load-path "/home/case/src/emacs/sophomore/" | ||
419 | :config | ||
420 | (sophomore-enable-all) | ||
421 | (sophomore-disable 'view-hello-file | ||
422 | 'describe-gnu-project | ||
423 | 'suspend-frame) | ||
424 | (sophomore-mode)) | ||
425 | |||
426 | (use-package compat | ||
427 | ;; This shouldn't be necessary, but sadly I believe that it is. | ||
428 | :ensure t) | ||
429 | |||
430 | (use-package vertico | ||
431 | :ensure t :demand t | ||
432 | :config | ||
433 | (setq vertico-cycle t) | ||
434 | (vertico-mode)) | ||
435 | |||
436 | (use-package vertico-directory | ||
437 | :after vertico | ||
438 | :bind (:map vertico-map | ||
439 | ("RET" . vertico-directory-enter) | ||
440 | ("DEL" . vertico-directory-delete-char) | ||
441 | ("M-DEL" . vertico-directory-delete-word)) | ||
442 | :hook (rfn-shadow-update-overlay-hook . vertico-directory-tidy)) | ||
443 | |||
444 | (use-package vertico-mouse | ||
445 | :after vertico | ||
446 | :config (vertico-mouse-mode)) | ||
447 | |||
448 | ;; Example configuration for Consult | ||
449 | (use-package consult | ||
450 | :ensure t | ||
451 | ;; Replace bindings. Lazily loaded due by `use-package'. | ||
452 | :bind (;; C-c bindings (mode-specific-map) | ||
453 | ("C-c h" . consult-history) | ||
454 | ("C-c m" . consult-mode-command) | ||
455 | ("C-c k" . consult-kmacro) | ||
456 | ;; C-x bindings (ctl-x-map) | ||
457 | ("C-x M-:" . consult-complex-command) | ||
458 | ("C-x b" . consult-buffer) | ||
459 | ("C-x 4 b" . consult-buffer-other-window) | ||
460 | ("C-x 5 b" . consult-buffer-other-frame) | ||
461 | ("C-x r b" . consult-bookmark) | ||
462 | ("C-x p b" . consult-project-buffer) | ||
463 | ;; Custom M-# bindings for fast register access | ||
464 | ("M-#" . consult-register-load) | ||
465 | ("M-'" . consult-register-store) | ||
466 | ("C-M-#" . consult-register) | ||
467 | ;; Other custom bindings | ||
468 | ("M-y" . consult-yank-pop) | ||
469 | ;; M-g bindings (goto-map) | ||
470 | ("M-g e" . consult-compile-error) | ||
471 | ("M-g f" . consult-flymake) | ||
472 | ("M-g g" . consult-goto-line) | ||
473 | ("M-g M-g" . consult-goto-line) | ||
474 | ("M-g o" . consult-outline) | ||
475 | ("M-g m" . consult-mark) | ||
476 | ("M-g k" . consult-global-mark) | ||
477 | ("M-g i" . consult-imenu) | ||
478 | ("M-g I" . consult-imenu-multi) | ||
479 | ;; M-s bindings (search-map) | ||
480 | ("M-s d" . consult-find) | ||
481 | ("M-s D" . consult-locate) | ||
482 | ("M-s g" . consult-grep) | ||
483 | ("M-s G" . consult-git-grep) | ||
484 | ("M-s r" . consult-ripgrep) | ||
485 | ("M-s l" . consult-line) | ||
486 | ("M-s L" . consult-line-multi) | ||
487 | ("M-s k" . consult-keep-lines) | ||
488 | ("M-s u" . consult-focus-lines) | ||
489 | ;; Isearch integration | ||
490 | ("M-s e" . consult-isearch-history) | ||
491 | :map isearch-mode-map | ||
492 | ("M-e" . consult-isearch-history) | ||
493 | ("M-s e" . consult-isearch-history) | ||
494 | ("M-s l" . consult-line) | ||
495 | ("M-s L" . consult-line-multi) | ||
496 | ;; Minibuffer history | ||
497 | :map minibuffer-local-map | ||
498 | ("M-s" . consult-history) | ||
499 | ("M-r" . consult-history)) | ||
500 | |||
501 | ;; Enable automatic preview at point in the *Completions* buffer. This is | ||
502 | ;; relevant when you use the default completion UI. | ||
503 | :hook (completion-list-mode . consult-preview-at-point-mode) | ||
504 | |||
505 | ;; The :init configuration is always executed (Not lazy) | ||
506 | :init | ||
507 | |||
508 | ;; Optionally configure the register formatting. This improves the register | ||
509 | ;; preview for `consult-register', `consult-register-load', | ||
510 | ;; `consult-register-store' and the Emacs built-ins. | ||
511 | (setq register-preview-delay 0.5 | ||
512 | register-preview-function #'consult-register-format) | ||
513 | |||
514 | ;; Optionally tweak the register preview window. | ||
515 | ;; This adds thin lines, sorting and hides the mode line of the window. | ||
516 | (advice-add #'register-preview :override #'consult-register-window) | ||
517 | |||
518 | (define-advice completing-read-multiple (:filter-args (args) indicator) | ||
519 | (cons (format "[CRM%s] %s" | ||
520 | (replace-regexp-in-string | ||
521 | "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" | ||
522 | crm-separator) | ||
523 | (car args)) | ||
524 | (cdr args))) | ||
525 | |||
526 | ;; Use Consult to select xref locations with preview | ||
527 | (setq xref-show-xrefs-function #'consult-xref | ||
528 | xref-show-definitions-function #'consult-xref) | ||
529 | |||
530 | (setq completion-in-region-function #'consult-completion-in-region) | ||
531 | |||
532 | ;; Configure other variables and modes in the :config section, | ||
533 | ;; after lazily loading the package. | ||
534 | :config | ||
535 | |||
536 | ;; Optionally configure preview. The default value | ||
537 | ;; is 'any, such that any key triggers the preview. | ||
538 | ;; (setq consult-preview-key 'any) | ||
539 | ;; (setq consult-preview-key (kbd "M-.")) | ||
540 | ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>"))) | ||
541 | ;; For some commands and buffer sources it is useful to configure the | ||
542 | ;; :preview-key on a per-command basis using the `consult-customize' macro. | ||
543 | (consult-customize | ||
544 | consult-theme :preview-key '(:debounce 0.2 any) | ||
545 | consult-ripgrep consult-git-grep consult-grep | ||
546 | consult-bookmark consult-recent-file consult-xref | ||
547 | consult--source-bookmark consult--source-file-register | ||
548 | consult--source-recent-file consult--source-project-recent-file | ||
549 | ;; :preview-key (kbd "M-.") | ||
550 | :preview-key '(:debounce 0.4 any)) | ||
551 | |||
552 | ;; Optionally configure the narrowing key. | ||
553 | ;; Both < and C-+ work reasonably well. | ||
554 | (setq consult-narrow-key "<") ;; (kbd "C-+") | ||
555 | |||
556 | ;; Optionally make narrowing help available in the minibuffer. | ||
557 | ;; You may want to use `embark-prefix-help-command' or which-key instead. | ||
558 | (define-key consult-narrow-map (vconcat consult-narrow-key "?") | ||
559 | #'consult-narrow-help)) | ||
560 | |||
561 | (use-package orderless | ||
562 | :ensure t :demand t | ||
563 | :init | ||
564 | (setopt completion-styles '(substring orderless basic) | ||
565 | completion-category-defaults nil | ||
566 | completion-category-overrides | ||
567 | '((file (styles basic partial-completion))))) | ||
568 | |||
569 | (use-package marginalia | ||
570 | :ensure t :demand t | ||
571 | :config | ||
572 | (marginalia-mode)) | ||
573 | |||
574 | (use-package embark | ||
575 | :ensure t | ||
576 | :bind | ||
577 | (("C-." . embark-act) | ||
578 | ("M-." . embark-dwim) | ||
579 | ("C-h B" . embark-bindings)) | ||
580 | :init | ||
581 | (setopt prefix-help-command #'embark-prefix-help-command) | ||
582 | :config | ||
583 | (add-to-list 'display-buffer-alist | ||
584 | '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" | ||
585 | nil | ||
586 | (window-parameters (mode-line-format . none))))) | ||
587 | |||
588 | (use-package embark-consult | ||
589 | :ensure t | ||
590 | :hook | ||
591 | (embark-collect-mode . consult-preview-at-point-mode)) | ||
592 | |||
593 | (use-package undo-fu-session | ||
594 | :ensure t | ||
595 | :config | ||
596 | (setq undo-fu-session-incompatible-files | ||
597 | '("/COMMIT_EDITMSG\\'" | ||
598 | "/git-rebase-todo\\'")) | ||
599 | (global-undo-fu-session-mode)) | ||
600 | |||
376 | ;;; basics.el ends here | 601 | ;;; basics.el ends here |