chore(emacs): improved startup time
f99b002c
7 file(s) · +46 −23
| 1 | 1 | ;;; early-init.el -*- lexical-binding: t; -*- |
|
| 2 | 2 | ||
| 3 | 3 | ;; Faster startup: defer GC, restore after init |
|
| 4 | - | (setq gc-cons-threshold most-positive-fixnum) |
|
| 4 | + | (setq gc-cons-threshold most-positive-fixnum |
|
| 5 | + | gc-cons-percentage 1.0) |
|
| 5 | 6 | (add-hook 'emacs-startup-hook |
|
| 6 | - | (lambda () (setq gc-cons-threshold (* 16 1024 1024)))) |
|
| 7 | + | (lambda () (setq gc-cons-threshold (* 16 1024 1024) |
|
| 8 | + | gc-cons-percentage 0.1))) |
|
| 9 | + | ||
| 10 | + | ;; Every `load'/`require' checks file names against these regexps; skip that |
|
| 11 | + | ;; during init and restore afterwards (adapted from minimal-emacs.d) |
|
| 12 | + | (let ((handlers file-name-handler-alist)) |
|
| 13 | + | ;; keep jka-compr so compressed .el.gz libraries still load |
|
| 14 | + | (setq file-name-handler-alist (list (rassq 'jka-compr-handler handlers))) |
|
| 15 | + | (add-hook 'emacs-startup-hook |
|
| 16 | + | (lambda () |
|
| 17 | + | (setq file-name-handler-alist |
|
| 18 | + | (delete-dups (append file-name-handler-alist handlers)))) |
|
| 19 | + | 101)) |
|
| 7 | 20 | ||
| 8 | - | ;; Skip UI chrome before first frame draws |
|
| 9 | 21 | (setq package-enable-at-startup t |
|
| 10 | 22 | inhibit-startup-screen t |
|
| 11 | - | frame-inhibit-implied-resize t) |
|
| 23 | + | inhibit-startup-echo-area-message user-login-name |
|
| 24 | + | frame-inhibit-implied-resize t |
|
| 25 | + | frame-resize-pixelwise t |
|
| 26 | + | auto-mode-case-fold nil) |
|
| 27 | + | ||
| 28 | + | ;; Skip UI chrome before first frame draws |
|
| 12 | 29 | (push '(menu-bar-lines . 0) default-frame-alist) |
|
| 13 | 30 | (push '(tool-bar-lines . 0) default-frame-alist) |
|
| 14 | 31 | (push '(vertical-scroll-bars) default-frame-alist) |
| 14 | 14 | (setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/") |
|
| 15 | 15 | ("nongnu" . "https://elpa.nongnu.org/nongnu/") |
|
| 16 | 16 | ("melpa" . "https://melpa.org/packages/"))) |
|
| 17 | - | (unless package-archive-contents (package-refresh-contents)) |
|
| 17 | + | ;; No refresh here: use-package :ensure refreshes on its own when a package is missing. |
|
| 18 | 18 | (setq use-package-always-ensure t) |
|
| 19 | 19 | ||
| 20 | 20 | (require 'init-defaults) |
| 1 | 1 | ;;; init-erc.el -*- lexical-binding: t; -*- |
|
| 2 | 2 | ||
| 3 | - | (require 'auth-source-pass) |
|
| 4 | - | ||
| 5 | 3 | ;; soju password: read from `pass' (gpg-encrypted), cached in memory per session |
|
| 6 | 4 | (defvar my/soju-pass-entry "irc/soju") |
|
| 7 | 5 | (defvar my/soju--password nil) |
| 1 | 1 | ;;; init-jabber.el -*- lexical-binding: t; -*- |
|
| 2 | 2 | ||
| 3 | - | (require 'auth-source-pass) |
|
| 4 | - | ||
| 5 | 3 | ;; Built from git for OMEMO. Native module needs mbedtls 3.x headers, gcc, |
|
| 6 | 4 | ;; make and pkg-config on PATH (4.x dropped mbedtls/aes.h). |
|
| 7 | 5 | (use-package jabber |
| 23 | 23 | ||
| 24 | 24 | (use-package eglot |
|
| 25 | 25 | :ensure nil |
|
| 26 | + | :defer t |
|
| 26 | 27 | :custom |
|
| 27 | 28 | (eglot-autoshutdown t) ; kill server when last buffer closes |
|
| 28 | 29 | (eglot-events-buffer-config '(:size 0 :format full)) ; no event logging |
|
| 29 | 30 | (eglot-extend-to-xref t) ; stay in eglot when jumping into deps |
|
| 30 | 31 | :config |
|
| 31 | 32 | (dolist (entry my/lsp-servers) |
|
| 32 | - | (let ((modes (ensure-list (car entry))) |
|
| 33 | - | (cmd (cdr entry))) |
|
| 34 | - | (when (executable-find (car cmd)) |
|
| 35 | - | (add-to-list 'eglot-server-programs (cons modes cmd)) |
|
| 36 | - | (dolist (mode modes) |
|
| 37 | - | (add-hook (intern (format "%s-hook" mode)) #'eglot-ensure)))))) |
|
| 33 | + | (when (executable-find (cadr entry)) |
|
| 34 | + | (add-to-list 'eglot-server-programs |
|
| 35 | + | (cons (ensure-list (car entry)) (cdr entry)))))) |
|
| 36 | + | ||
| 37 | + | ;; Hooks go in now so eglot itself only loads when a matching buffer opens |
|
| 38 | + | (dolist (entry my/lsp-servers) |
|
| 39 | + | (when (executable-find (cadr entry)) |
|
| 40 | + | (dolist (mode (ensure-list (car entry))) |
|
| 41 | + | (add-hook (intern (format "%s-hook" mode)) #'eglot-ensure)))) |
|
| 38 | 42 | ||
| 39 | 43 | ;;; Indentation per language |
|
| 40 | 44 | (defvar my/indent-settings |
| 41 | 41 | ;; Proton Bridge rewrites PGP/MIME into multipart/mixed with the armored |
|
| 42 | 42 | ;; block as an attachment, so Emacs won't auto-decrypt. Pull the block out |
|
| 43 | 43 | ;; of the raw message and decrypt it by hand. |
|
| 44 | - | (require 'mm-decode) |
|
| 45 | - | (require 'epg) |
|
| 46 | - | (require 'cl-lib) |
|
| 44 | + | (require 'cl-lib) ; cl-labels, expanded at load time |
|
| 47 | 45 | ||
| 48 | 46 | (defun my/mail--pgp-blocks (path) |
|
| 49 | 47 | "Return armored PGP message strings found in the parts of PATH." |
|
| 48 | + | (require 'mm-decode) |
|
| 50 | 49 | (with-temp-buffer |
|
| 51 | 50 | (insert-file-contents-literally path) |
|
| 52 | 51 | (let (blocks) |
|
| 63 | 62 | (defun my/mail-decrypt-bridge () |
|
| 64 | 63 | "Decrypt the PGP block of the mu4e message at point into a buffer." |
|
| 65 | 64 | (interactive) |
|
| 65 | + | (require 'epg) |
|
| 66 | 66 | (let* ((msg (mu4e-message-at-point)) |
|
| 67 | 67 | (blocks (or (my/mail--pgp-blocks (mu4e-message-field msg :path)) |
|
| 68 | 68 | (user-error "No PGP block in message"))) |
|
| 1 | 1 | ;;; init-tools.el -*- lexical-binding: t; -*- |
|
| 2 | 2 | ||
| 3 | - | (use-package magit) |
|
| 3 | + | (use-package magit |
|
| 4 | + | :defer t) |
|
| 4 | 5 | ||
| 5 | 6 | (use-package diff-hl |
|
| 6 | 7 | :hook ((after-init . global-diff-hl-mode) |
|
| 27 | 28 | '(diff-hl-margin-delete ((t (:foreground "#aa6c6c" :background unspecified :weight bold)))))) |
|
| 28 | 29 | ||
| 29 | 30 | (use-package elfeed |
|
| 31 | + | :defer t |
|
| 30 | 32 | :config |
|
| 31 | 33 | (setq-default elfeed-search-filter "@6-months-ago") |
|
| 32 | 34 | ||
| 60 | 62 | (face-remap-add-relative 'default :family "BerkeleyMono Nerd Font Mono" :height 140)) |
|
| 61 | 63 | (add-hook 'elfeed-show-mode-hook #'my/elfeed-show-font)) |
|
| 62 | 64 | ||
| 63 | - | ;; ob-go isn't bundled with org; must load before org-babel-do-load-languages |
|
| 64 | - | (use-package ob-go) |
|
| 65 | + | ;; ob-go isn't bundled with org; required in org's :config below |
|
| 66 | + | (use-package ob-go |
|
| 67 | + | :defer t) |
|
| 65 | 68 | ||
| 66 | 69 | (use-package org |
|
| 67 | 70 | :ensure nil |
|
| 71 | + | :defer t |
|
| 68 | 72 | :config |
|
| 73 | + | (require 'ob-go) |
|
| 69 | 74 | (org-babel-do-load-languages |
|
| 70 | 75 | 'org-babel-load-languages |
|
| 71 | 76 | '((js . t) |
|
| 126 | 131 | "l" 'dired-find-file |
|
| 127 | 132 | "q" 'quit-window)) |
|
| 128 | 133 | ||
| 129 | - | (require 'posts) |
|
| 130 | - | (require 'uguu) |
|
| 134 | + | (autoload 'posts-compose "posts" nil t) |
|
| 135 | + | (autoload 'uguu-upload-file "uguu" nil t) |
|
| 136 | + | (autoload 'uguu-upload-clipboard "uguu" nil t) |
|
| 131 | 137 | ||
| 132 | 138 | (provide 'init-tools) |
|