From 6b4430b85403c45f2f6add23f577b8b5de61da08 Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Mon, 12 Aug 2024 16:31:11 -0400 Subject: [PATCH] Optimize Emacs startup and UI settings Streamlined startup by optimizing garbage collection, UI elements, and performance settings. Moved redundant configurations from init.el to early-init.el for better startup efficiency. Made adjustments to init-ui.el for better tool-bar handling post-init. --- emacs/.emacs.d/config/init-ui.el | 11 +- emacs/.emacs.d/early-init.el | 223 ++++++++++++++++++++++++++++++- emacs/.emacs.d/init.el | 10 -- 3 files changed, 225 insertions(+), 19 deletions(-) diff --git a/emacs/.emacs.d/config/init-ui.el b/emacs/.emacs.d/config/init-ui.el index 05b7065..d30d2b0 100644 --- a/emacs/.emacs.d/config/init-ui.el +++ b/emacs/.emacs.d/config/init-ui.el @@ -1,10 +1,11 @@ ;; -*- lexical-binding: t; -*- -;; Don't show ugly graphical UI elements -(when (window-system) - (tool-bar-mode -1) - (scroll-bar-mode -1) - (tooltip-mode -1)) +;; For some reason, the tool-bar-mode disabling in early-init.el was leaving the frame title too tall, so +;; toggle it on and off +(add-hook 'after-init-hook + (lambda () + (tool-bar-mode) + (tool-bar-mode -1))) (when (fboundp 'mac-auto-operator-composition-mode) (setq mac-auto-operator-composition-characters diff --git a/emacs/.emacs.d/early-init.el b/emacs/.emacs.d/early-init.el index 879c03b..b174de9 100644 --- a/emacs/.emacs.d/early-init.el +++ b/emacs/.emacs.d/early-init.el @@ -1,7 +1,222 @@ -;; -*- lexical-binding: t; -*- +;; -*- no-byte-compile: t; lexical-binding: t; -*- +;; Borrowed from https://github.com/jamescherti/minimal-emacs.d/blob/main/early-init.el + +;;; Variables +(defvar minimal-emacs-debug nil + "Non-nil to enable debug.") + +(defvar minimal-emacs-gc-cons-threshold (* 16 1024 1024) + "The value of `gc-cons-threshold' after Emacs startup.") + +(defvar minimal-emacs-frame-title-format "%b – Emacs" + "Template for displaying the title bar of visible and iconified frame.") + +;;; Misc + +(set-language-environment "UTF-8") + +;; Set-language-environment sets default-input-method, which is unwanted. +(setq default-input-method nil) + +;;; Garbage collection +;; Garbage collection significantly affects startup times. This setting delays +;; garbage collection during startup but will be reset later. + +(setq gc-cons-threshold most-positive-fixnum) + +(add-hook 'emacs-startup-hook + (lambda () + (setq gc-cons-threshold minimal-emacs-gc-cons-threshold))) + +;;; Performance + +;; Prefer loading newer compiled files (setq load-prefer-newer t) -;; Some startup time optimizations stolen from Doom emacs -(setq gc-cons-threshold most-positive-fixnum ; 2^61 bytes - gc-cons-percentage 0.6) +;; Increase how much is read from processes in a single chunk (default is 4kb). +(setq read-process-output-max (* 256 1024)) ; 256kb + +;; Reduce rendering/line scan work by not rendering cursors or regions in +;; non-focused windows. +(setq-default cursor-in-non-selected-windows nil) +(setq highlight-nonselected-windows nil) + +;; Disable warnings from the legacy advice API. They aren't useful. +(setq ad-redefinition-action 'accept) + +;; Ignore warnings about "existing variables being aliased". +(setq warning-suppress-types '((defvaralias) (lexical-binding))) + +;; Don't ping things that look like domain names. +(setq ffap-machine-p-known 'reject) + +;; By default, Emacs "updates" its ui more often than it needs to +(setq idle-update-delay 1.0) + +;; 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) + +(unless (daemonp) + (let ((old-value (default-toplevel-value 'file-name-handler-alist))) + (set-default-toplevel-value + 'file-name-handler-alist + ;; 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. + (if (eval-when-compile + (locate-file-internal "calc-loaddefs.el" load-path)) + nil + (list (rassq 'jka-compr-handler old-value)))) + ;; Ensure the new value persists through any current let-binding. + (set-default-toplevel-value 'file-name-handler-alist + file-name-handler-alist) + ;; Remember the old value to reset it as needed. + (add-hook 'emacs-startup-hook + (lambda () + (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 old-value)))) + 101)) + + (unless noninteractive + (progn + ;; Disable mode-line-format during init + (defun minimal-emacs--reset-inhibited-vars-h () + (setq-default inhibit-redisplay nil + ;; Inhibiting `message' only prevents redraws and + inhibit-message nil) + (redraw-frame)) + + (setq-default mode-line-format nil) + + (defun minimal-emacs--startup-load-user-init-file (fn &rest args) + "Around advice for startup--load-user-init-file to reset mode-line-format." + (let (init) + (unwind-protect + (progn + (apply fn args) ; Start up as normal + (setq init t)) + (unless init + ;; If we don't undo inhibit-{message, redisplay} and there's an + ;; error, we'll see nothing but a blank Emacs frame. + (minimal-emacs--reset-inhibited-vars-h)) + (unless (default-toplevel-value 'mode-line-format) + (setq-default mode-line-format + minimal-emacs--default-mode-line-format))))) + + (advice-add 'startup--load-user-init-file :around + #'minimal-emacs--startup-load-user-init-file)) + + ;; 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) + + ;; Shave seconds off startup time by starting the scratch buffer in + ;; `fundamental-mode' + (setq initial-major-mode 'fundamental-mode + initial-scratch-message nil))) + +;;; Native compilation and Byte compilation + +(if (and (featurep 'native-compile) + (fboundp 'native-comp-available-p) + (native-comp-available-p)) + ;; Activate `native-compile' + (setq native-comp-deferred-compilation t + package-native-compile t) + ;; Deactivate the `native-compile' feature if it is not available + (setq features (delq 'native-compile features))) + +;; Suppress compiler warnings and don't inundate users with their popups. +(setq native-comp-async-report-warnings-errors + (or minimal-emacs-debug 'silent)) +(setq native-comp-warning-on-missing-source minimal-emacs-debug) + +(setq debug-on-error minimal-emacs-debug + jka-compr-verbose minimal-emacs-debug) + +(setq byte-compile-warnings minimal-emacs-debug) +(setq byte-compile-verbose minimal-emacs-debug) + +;;; Disable unneeded UI elements + +;; 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. +(push '(menu-bar-lines . 0) default-frame-alist) +(push '(tool-bar-lines . 0) default-frame-alist) +(push '(vertical-scroll-bars) default-frame-alist) +(push '(horizontal-scroll-bars) default-frame-alist) + +(setq tool-bar-mode nil + scroll-bar-mode nil) + +(when (bound-and-true-p tooltip-mode) + (tooltip-mode -1)) + +;; Disable GUIs because theyr are inconsistent across systems, desktop +;; environments, and themes, and they don't match the look of Emacs. +(setq use-file-dialog nil) +(setq use-dialog-box nil) + +(unless (memq window-system '(mac ns)) + ;; (menu-bar-mode -1) + (setq menu-bar-mode nil)) + +(when (fboundp 'horizontal-scroll-bar-mode) + (horizontal-scroll-bar-mode -1)) + +;; Allow for shorter responses: "y" for yes and "n" for no. +(if (boundp 'use-short-answers) + (setq use-short-answers t) + (advice-add #'yes-or-no-p :override #'y-or-n-p)) +(defalias #'view-hello-file #'ignore) ; Never show the hello file + +;;; package.el +;; Since Emacs 27, package initialization occurs before `user-init-file' is +;; loaded, but after `early-init-file'. +(setq package-enable-at-startup t) + +(setq package-quickstart nil) + +(setq frame-title-format minimal-emacs-frame-title-format + icon-title-format minimal-emacs-frame-title-format) + +(provide 'early-init) + +;;; early-init.el ends here diff --git a/emacs/.emacs.d/init.el b/emacs/.emacs.d/init.el index 6a457d2..ceb9541 100644 --- a/emacs/.emacs.d/init.el +++ b/emacs/.emacs.d/init.el @@ -1,14 +1,5 @@ ;; -*- lexical-binding: t; -*- -;; Some startup time optimizations stolen from Doom emacs -(defvar file-name-handler-alist-backup file-name-handler-alist) -(setq file-name-handler-alist nil) -(add-hook 'emacs-startup-hook - (lambda () - (setq gc-cons-threshold 16777216 ; 16mb - gc-cons-percentage 0.1 - file-name-handler-alist file-name-handler-alist-backup))) - ;; Start the server after init (autoload 'server-running-p "server") (defun server-start-if-not-running () @@ -62,7 +53,6 @@ (exec-path-from-shell-check-startup-files nil) (exec-path-from-shell-arguments '("-l"))) - ;; Don't use this file as the custom-file (setq custom-file (expand-file-name "custom.el" user-emacs-directory))