summaryrefslogtreecommitdiff
path: root/files/emacs/.emacs.d/early-init.el
diff options
context:
space:
mode:
authorMitch Taylor <mitch@mitchtaylor.xyz>2026-03-22 22:07:22 -0300
committerMitch Taylor <mitch@mitchtaylor.xyz>2026-03-22 22:07:22 -0300
commit04126e9fda050fa753ddc22511e3c3f8dc275f7a (patch)
tree41d9f9276c1e09c1cb86f94133bdf90f041d1ed2 /files/emacs/.emacs.d/early-init.el
initial commit
Diffstat (limited to 'files/emacs/.emacs.d/early-init.el')
-rw-r--r--files/emacs/.emacs.d/early-init.el492
1 files changed, 492 insertions, 0 deletions
diff --git a/files/emacs/.emacs.d/early-init.el b/files/emacs/.emacs.d/early-init.el
new file mode 100644
index 0000000..c0c97e9
--- /dev/null
+++ b/files/emacs/.emacs.d/early-init.el
@@ -0,0 +1,492 @@
+;;; early-init.el --- Early Init -*- lexical-binding: t; -*-
+
+;; Author: James Cherti <https://www.jamescherti.com/contact/>
+;; URL: https://github.com/jamescherti/minimal-emacs.d
+;; Package-Requires: ((emacs "29.1"))
+;; Keywords: maint
+;; Version: 1.4.1
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;;; Commentary:
+;; The minimal-emacs.d project is a lightweight and optimized Emacs base
+;; (init.el and early-init.el) that gives you full control over your
+;; configuration. It provides better defaults, an optimized startup, and a clean
+;; foundation for building your own vanilla Emacs setup.
+;;
+;; Building the minimal-emacs.d init.el and early-init.el was the result of
+;; extensive research and testing to fine-tune the best parameters and
+;; optimizations for an Emacs configuration.
+;;
+;; Do not modify this file; instead, modify pre-early-init.el or
+;; post-early-init.el.
+
+;;; Code:
+
+;;; Internal variables
+
+;; Backup of `gc-cons-threshold' and `gc-cons-percentage' before startup.
+(defvar minimal-emacs--backup-gc-cons-threshold gc-cons-threshold)
+(defvar minimal-emacs--backup-gc-cons-percentage gc-cons-percentage)
+
+;; Temporarily raise the garbage collection threshold to its maximum value.
+;; It will be restored later to controlled values.
+(setq gc-cons-threshold most-positive-fixnum)
+(setq gc-cons-percentage 1.0)
+
+;;; Variables
+
+(defvar minimal-emacs-ui-features '()
+ "List of user interface features to enable in minimal Emacs setup.
+This variable holds a list of Emacs UI features that can be enabled:
+- context-menu (Enables the context menu in graphical environments.)
+- tool-bar (Enables the tool bar in graphical environments.)
+- menu-bar (Enables the menu bar in graphical environments.)
+- dialogs (Enables both file dialogs and dialog boxes.)
+- tooltips (Enables tooltips.)")
+
+(defvar minimal-emacs-frame-title-format "%b – Emacs"
+ "Template for displaying the title bar of visible and iconified frame.")
+
+(defvar minimal-emacs-debug (bound-and-true-p init-file-debug)
+ "Non-nil to enable debug.")
+
+(defvar minimal-emacs-optimize-startup-gc t
+ "If non-nil, increase `gc-cons-threshold' during startup to reduce pauses.
+After Emacs finishes loading, `gc-cons-threshold' is restored to the value
+stored in `minimal-emacs-gc-cons-threshold'.")
+
+(defvar minimal-emacs-gc-cons-threshold (* 32 1024 1024)
+ "Value to which `gc-cons-threshold' is set after Emacs startup.
+Ignored if `minimal-emacs-optimize-startup-gc' is nil.")
+
+(defvar minimal-emacs-gc-cons-percentage gc-cons-percentage
+ "Value to which `gc-cons-percentage' is set after Emacs startup.
+Ignored if `minimal-emacs-optimize-startup-gc' is nil.")
+
+(defvar minimal-emacs-gc-cons-threshold-restore-delay nil
+ "Number of seconds to wait before restoring `gc-cons-threshold'.")
+
+(defvar minimal-emacs-optimize-file-name-handler-alist t
+ "Enable optimization of `file-name-handler-alist'.
+When non-nil, this variable activates optimizations to reduce file name handler
+lookups during Emacs startup.")
+
+(defvar minimal-emacs-disable-mode-line-during-startup t
+ "Disable the mode line during startup.
+This reduces visual clutter and slightly enhances startup performance. The
+tradeoff is that the mode line is hidden during the startup phase.")
+
+(defvar minimal-emacs-package-initialize-and-refresh t
+ "Whether to automatically initialize and refresh packages.
+When set to non-nil, Emacs will automatically call `package-initialize' and
+`package-refresh-contents' to set up and update the package system.")
+
+(defvar minimal-emacs-inhibit-redisplay-during-startup nil
+ "Suppress redisplay during startup to improve performance.
+This prevents visual updates while Emacs initializes. The tradeoff is that you
+won't see the progress or activities during the startup process.")
+
+(defvar minimal-emacs-inhibit-message-during-startup nil
+ "Suppress startup messages for a cleaner experience.
+This slightly enhances performance. The tradeoff is that you won't be informed
+of the progress or any relevant activities during startup.")
+
+(defvar minimal-emacs-user-directory user-emacs-directory
+ "Directory beneath minimal-emacs.d files are placed.
+Note that this should end with a directory separator.")
+
+(defvar minimal-emacs-load-pre-early-init t
+ "If non-nil, attempt to load `pre-early-init.el`.")
+
+(defvar minimal-emacs-load-post-early-init t
+ "If non-nil, attempt to load `post-early-init.el`.")
+
+(defvar minimal-emacs-load-pre-init t
+ "If non-nil, attempt to load `pre-init.el`.")
+
+(defvar minimal-emacs-load-post-init t
+ "If non-nil, attempt to load `post-init.el`.")
+
+;;; Load pre-early-init.el
+
+;; Prefer loading newer compiled files
+(setq load-prefer-newer t)
+(when minimal-emacs-debug
+ (setq debug-on-error minimal-emacs-debug))
+
+(defvar minimal-emacs--success nil)
+(defun minimal-emacs--check-success ()
+ "Verify that the Emacs configuration has loaded successfully."
+ (unless minimal-emacs--success
+ (cond
+ ((or (file-exists-p (expand-file-name "~/.emacs.el"))
+ (file-exists-p (expand-file-name "~/.emacs")))
+ (error "Emacs ignored loading 'init.el'. Please ensure that files such as ~/.emacs or ~/.emacs.el do not exist, as they may be preventing Emacs from loading the 'init.el' file"))
+
+ (t
+ (error "Configuration error. Debug by starting Emacs with: --debug-init")))))
+
+(unless noninteractive
+ (add-hook 'emacs-startup-hook #'minimal-emacs--check-success 102))
+
+(defvar minimal-emacs-load-compiled-init-files nil
+ "If non-nil, attempt to load byte-compiled .elc for init files.
+This will enable minimal-emacs to load byte-compiled or possibly native-compiled
+init files for the following initialization files: pre-init.el, post-init.el,
+pre-early-init.el, and post-early-init.el.")
+
+(defun minimal-emacs--remove-el-file-suffix (filename)
+ "Remove the Elisp file suffix from FILENAME and return it (.el, .el.gz...)."
+ (let ((suffixes (mapcar (lambda (ext) (concat ".el" ext))
+ load-file-rep-suffixes)))
+ (catch 'done
+ (dolist (suffix suffixes filename)
+ (when (string-suffix-p suffix filename)
+ (setq filename (substring filename 0 (- (length suffix))))
+ (throw 'done t))))
+ filename))
+
+(defun minimal-emacs-load-user-init (filename)
+ "Execute a file of Lisp code named FILENAME."
+ (let ((init-file (expand-file-name filename
+ minimal-emacs-user-directory)))
+ (if (not minimal-emacs-load-compiled-init-files)
+ (load init-file :no-error (not minimal-emacs-debug) :nosuffix)
+ ;; Remove the file suffix (.el, .el.gz, etc.) to let the `load' function
+ ;; select between .el and .elc files.
+ (setq init-file (minimal-emacs--remove-el-file-suffix init-file))
+ (load init-file :no-error (not minimal-emacs-debug)))))
+
+(when minimal-emacs-load-pre-early-init
+ (minimal-emacs-load-user-init "pre-early-init.el"))
+
+(setq custom-theme-directory
+ (expand-file-name "themes/" minimal-emacs-user-directory))
+
+(setq custom-file (expand-file-name "custom.el" minimal-emacs-user-directory))
+
+;;; Garbage collection
+;; Garbage collection significantly affects startup times. This setting delays
+;; garbage collection during startup but will be reset later.
+
+(defun minimal-emacs--restore-gc-values ()
+ "Restore garbage collection values to minimal-emacs.d values."
+ (setq gc-cons-threshold minimal-emacs-gc-cons-threshold)
+ (setq gc-cons-percentage minimal-emacs-gc-cons-percentage))
+
+(defun minimal-emacs--restore-gc ()
+ "Restore garbage collection settings."
+ (if (and (bound-and-true-p minimal-emacs-gc-cons-threshold-restore-delay)
+ ;; In noninteractive mode, the event loop does not run
+ (not noninteractive))
+ ;; Defer garbage collection during initialization to avoid 2 collections.
+ (run-with-timer minimal-emacs-gc-cons-threshold-restore-delay nil
+ #'minimal-emacs--restore-gc-values)
+ (minimal-emacs--restore-gc-values)))
+
+(if minimal-emacs-optimize-startup-gc
+ ;; `gc-cons-threshold' is managed by minimal-emacs.d
+ (add-hook 'emacs-startup-hook #'minimal-emacs--restore-gc 105)
+ ;; gc-cons-threshold is not managed by minimal-emacs.d.
+ (when (= gc-cons-threshold most-positive-fixnum)
+ (setq gc-cons-threshold minimal-emacs--backup-gc-cons-threshold)
+ (setq gc-cons-percentage minimal-emacs--backup-gc-cons-percentage)))
+
+;;; Native compilation and Byte compilation
+
+(unless (and (featurep 'native-compile)
+ (fboundp 'native-comp-available-p)
+ (native-comp-available-p))
+ ;; Deactivate the `native-compile' feature if it is not available
+ (setq features (delq 'native-compile features)))
+
+(setq native-comp-warning-on-missing-source minimal-emacs-debug
+ native-comp-async-report-warnings-errors (or minimal-emacs-debug 'silent))
+
+(setq jka-compr-verbose minimal-emacs-debug)
+(setq byte-compile-warnings minimal-emacs-debug
+ byte-compile-verbose minimal-emacs-debug)
+
+;;; Miscellaneous
+
+(set-language-environment "UTF-8")
+
+;; Increase how much is read from processes in a single chunk
+(setq read-process-output-max (* 2 1024 1024)) ; 1024kb
+
+(setq process-adaptive-read-buffering nil)
+
+;; Don't ping things that look like domain names.
+(setq ffap-machine-p-known 'reject)
+
+(setq warning-minimum-level (if minimal-emacs-debug :warning :error))
+(setq warning-suppress-types '((lexical-binding)))
+
+(when minimal-emacs-debug
+ (setq message-log-max 16384))
+
+;; In PGTK, this timeout introduces latency. Reducing it from the default 0.1
+;; improves responsiveness of childframes and related packages.
+(when (boundp 'pgtk-wait-for-event-timeout)
+ (setq pgtk-wait-for-event-timeout 0.001))
+
+;; Disable warnings from the legacy advice API. They aren't useful.
+(setq ad-redefinition-action 'accept)
+
+;;; Performance: Miscellaneous options
+
+;; Font compacting can be very resource-intensive, especially when rendering
+;; icon fonts on Windows. This will increase memory usage.
+(setq inhibit-compacting-font-caches t)
+
+(when (not noninteractive)
+ ;; Resizing the Emacs frame can be costly when changing the font. Disable this
+ ;; to improve startup times with fonts larger than the system default.
+ (setq frame-resize-pixelwise t)
+
+ ;; Without this, Emacs will try to resize itself to a specific column size
+ (setq frame-inhibit-implied-resize t)
+
+ ;; A second, case-insensitive pass over `auto-mode-alist' is time wasted.
+ ;; No second pass of case-insensitive search over auto-mode-alist.
+ (setq auto-mode-case-fold nil)
+
+ ;; Reduce *Message* noise at startup. An empty scratch buffer (or the
+ ;; dashboard) is more than enough, and faster to display.
+ (setq inhibit-startup-screen t
+ inhibit-startup-echo-area-message user-login-name)
+ (setq initial-buffer-choice nil
+ inhibit-startup-buffer-menu t
+ inhibit-x-resources t)
+
+ ;; Disable bidirectional text scanning for a modest performance boost.
+ (setq-default bidi-display-reordering 'left-to-right
+ bidi-paragraph-direction 'left-to-right)
+
+ ;; Give up some bidirectional functionality for slightly faster re-display.
+ (setq bidi-inhibit-bpa t)
+
+ ;; Remove "For information about GNU Emacs..." message at startup
+ (advice-add 'display-startup-echo-area-message :override #'ignore)
+
+ ;; Suppress the vanilla startup screen completely. We've disabled it with
+ ;; `inhibit-startup-screen', but it would still initialize anyway.
+ (advice-add 'display-startup-screen :override #'ignore)
+
+ (unless minimal-emacs-debug
+ ;; Unset command line options irrelevant to the current OS. These options
+ ;; are still processed by `command-line-1` but have no effect.
+ (unless (eq system-type 'darwin)
+ (setq command-line-ns-option-alist nil))
+ (unless (memq initial-window-system '(x pgtk))
+ (setq command-line-x-option-alist nil))))
+
+;;; Performance: File-name-handler-alist
+
+(defvar minimal-emacs--old-file-name-handler-alist (default-toplevel-value
+ 'file-name-handler-alist))
+
+(defun minimal-emacs--respect-file-handlers (fn args-left)
+ "Respect file handlers.
+FN is the function and ARGS-LEFT is the same argument as `command-line-1'.
+Emacs processes command-line files very early in startup. These files may
+include special paths like TRAMP paths, so restore `file-name-handler-alist' for
+this stage of initialization."
+ (let ((file-name-handler-alist (if args-left
+ minimal-emacs--old-file-name-handler-alist
+ file-name-handler-alist)))
+ (funcall fn args-left)))
+
+(defun minimal-emacs--restore-file-name-handler-alist ()
+ "Restore `file-name-handler-alist'."
+ (set-default-toplevel-value
+ 'file-name-handler-alist
+ ;; Merge instead of overwrite to preserve any changes made since startup.
+ (delete-dups (append file-name-handler-alist
+ minimal-emacs--old-file-name-handler-alist))))
+
+(when (and minimal-emacs-optimize-file-name-handler-alist
+ (not minimal-emacs-debug))
+ ;; Determine the state of bundled libraries using calc-loaddefs.el. If
+ ;; compressed, retain the gzip handler in `file-name-handler-alist`. If
+ ;; compiled or neither, omit the gzip handler during startup for improved
+ ;; startup and package load time.
+ (set-default-toplevel-value
+ 'file-name-handler-alist
+ (if (locate-file-internal "calc-loaddefs.el" load-path)
+ nil
+ (list (rassq 'jka-compr-handler
+ minimal-emacs--old-file-name-handler-alist))))
+
+ ;; Ensure the new value persists through any current let-binding.
+ (put 'file-name-handler-alist 'initial-value
+ minimal-emacs--old-file-name-handler-alist)
+
+ ;; Emacs processes command-line files very early in startup. These files may
+ ;; include special paths TRAMP. Restore `file-name-handler-alist'.
+ (advice-add 'command-line-1 :around #'minimal-emacs--respect-file-handlers)
+
+ (add-hook 'emacs-startup-hook #'minimal-emacs--restore-file-name-handler-alist
+ 101))
+
+;;; Performance: Inhibit redisplay
+
+(defun minimal-emacs--reset-inhibit-redisplay ()
+ "Reset inhibit redisplay."
+ (setq-default inhibit-redisplay nil)
+ (remove-hook 'post-command-hook #'minimal-emacs--reset-inhibit-redisplay))
+
+(when (and minimal-emacs-inhibit-redisplay-during-startup
+ (not noninteractive)
+ (not minimal-emacs-debug))
+ ;; Suppress redisplay and redraw during startup to avoid delays and
+ ;; prevent flashing an unstyled Emacs frame.
+ (setq-default inhibit-redisplay t)
+ (add-hook 'post-command-hook #'minimal-emacs--reset-inhibit-redisplay -100))
+
+;;; Performance: Inhibit message
+
+(defun minimal-emacs--reset-inhibit-message ()
+ "Reset inhibit message."
+ (setq-default inhibit-message nil)
+ (remove-hook 'post-command-hook #'minimal-emacs--reset-inhibit-message))
+
+(when (and minimal-emacs-inhibit-message-during-startup
+ (not noninteractive)
+ (not minimal-emacs-debug))
+ (setq-default inhibit-message t)
+ (add-hook 'post-command-hook #'minimal-emacs--reset-inhibit-message -100))
+
+;;; Performance: Disable mode-line during startup
+
+(defvar-local minimal-emacs--hidden-mode-line nil
+ "Store the buffer-local value of `mode-line-format' during startup.")
+
+(when (and minimal-emacs-disable-mode-line-during-startup
+ (not noninteractive)
+ (not minimal-emacs-debug))
+ (put 'mode-line-format
+ 'initial-value (default-toplevel-value 'mode-line-format))
+ (setq-default mode-line-format nil)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (local-variable-p 'mode-line-format)
+ (setq minimal-emacs--hidden-mode-line mode-line-format)
+ (setq mode-line-format nil)))))
+
+;;; Restore values
+
+(defun minimal-emacs--startup-load-user-init-file (fn &rest args)
+ "Advice to reset `mode-line-format'. FN and ARGS are the function and args."
+ (unwind-protect
+ ;; Start up as normal
+ (apply fn args)
+ ;; If we don't undo inhibit-{message, redisplay} and there's an error, we'll
+ ;; see nothing but a blank Emacs frame.
+ (when minimal-emacs-inhibit-message-during-startup
+ (setq-default inhibit-message nil))
+ (when minimal-emacs-inhibit-redisplay-during-startup
+ (setq-default inhibit-redisplay nil))
+ ;; Restore the mode-line
+ (when minimal-emacs-disable-mode-line-during-startup
+ (unless (default-toplevel-value 'mode-line-format)
+ (setq-default mode-line-format (get 'mode-line-format
+ 'initial-value)))
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (local-variable-p 'minimal-emacs--hidden-mode-line)
+ (setq mode-line-format minimal-emacs--hidden-mode-line)
+ (kill-local-variable 'minimal-emacs--hidden-mode-line)))))))
+
+(advice-add 'startup--load-user-init-file :around
+ #'minimal-emacs--startup-load-user-init-file)
+
+;;; UI elements
+
+(setq frame-title-format minimal-emacs-frame-title-format
+ icon-title-format minimal-emacs-frame-title-format)
+
+;; Disable startup screens and messages
+(setq inhibit-splash-screen t)
+
+;; I intentionally avoid calling `menu-bar-mode', `tool-bar-mode', and
+;; `scroll-bar-mode' because manipulating frame parameters can trigger or queue
+;; a superfluous and potentially expensive frame redraw at startup, depending
+;; on the window system. The variables must also be set to `nil' so users don't
+;; have to call the functions twice to re-enable them.
+(unless (memq 'menu-bar minimal-emacs-ui-features)
+ (push '(menu-bar-lines . 0) default-frame-alist)
+ (unless (memq window-system '(mac ns))
+ (setq menu-bar-mode nil)))
+
+(defun minimal-emacs--setup-toolbar (&rest _)
+ "Setup the toolbar."
+ (when (fboundp 'tool-bar-setup)
+ (advice-remove 'tool-bar-setup #'ignore)
+ (when (bound-and-true-p tool-bar-mode)
+ (funcall 'tool-bar-setup))))
+
+(unless noninteractive
+ (when (fboundp 'tool-bar-setup)
+ ;; Temporarily override the tool-bar-setup function to prevent it from
+ ;; running during the initial stages of startup
+ (advice-add 'tool-bar-setup :override #'ignore)
+
+ (advice-add 'startup--load-user-init-file :after
+ #'minimal-emacs--setup-toolbar)))
+
+(unless (memq 'tool-bar minimal-emacs-ui-features)
+ (push '(tool-bar-lines . 0) default-frame-alist)
+ (setq tool-bar-mode nil))
+
+(setq default-frame-scroll-bars 'right)
+(push '(vertical-scroll-bars) default-frame-alist)
+(push '(horizontal-scroll-bars) default-frame-alist)
+(setq scroll-bar-mode nil)
+
+(unless (memq 'tooltips minimal-emacs-ui-features)
+ (when (bound-and-true-p tooltip-mode)
+ (tooltip-mode -1)))
+
+;; Disable GUIs because they are inconsistent across systems, desktop
+;; environments, and themes, and they don't match the look of Emacs.
+(unless (memq 'dialogs minimal-emacs-ui-features)
+ (setq use-file-dialog nil)
+ (setq use-dialog-box nil))
+
+;;; Security
+(setq gnutls-verify-error t) ; Prompts user if there are certificate issues
+(setq tls-checktrust t) ; Ensure SSL/TLS connections undergo trust verification
+(setq gnutls-min-prime-bits 3072) ; Stronger GnuTLS encryption
+
+;; This results in a more compact output that emphasizes performance
+(setq use-package-expand-minimally t)
+
+(setq use-package-minimum-reported-time (if minimal-emacs-debug 0 0.1))
+(setq use-package-verbose minimal-emacs-debug)
+(setq use-package-always-ensure (not noninteractive))
+(setq use-package-enable-imenu-support t)
+
+;; package.el
+(setq package-enable-at-startup nil) ; Let the init.el file handle this
+(setq package-quickstart-file
+ (expand-file-name "package-quickstart.el" user-emacs-directory))
+(setq package-archives '(("melpa" . "https://melpa.org/packages/")
+ ("gnu" . "https://elpa.gnu.org/packages/")
+ ("nongnu" . "https://elpa.nongnu.org/nongnu/")
+ ("melpa-stable" . "https://stable.melpa.org/packages/")))
+(setq package-archive-priorities '(("gnu" . 99)
+ ("nongnu" . 80)
+ ("melpa" . 70)
+ ("melpa-stable" . 50)))
+
+;;; Load post-early-init.el
+
+(when minimal-emacs-load-post-early-init
+ (minimal-emacs-load-user-init "post-early-init.el"))
+
+;; Local variables:
+;; byte-compile-warnings: (not obsolete free-vars)
+;; End:
+
+;;; early-init.el ends here