From a866f750be27ff694be31a2344a5e17dc21748cc Mon Sep 17 00:00:00 2001 From: James Cherti <60946298+jamescherti@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:27:13 -0400 Subject: [PATCH 1/4] Refactor minimal-emacs.d --- .github/workflows/ci.yml | 42 +++++ .gitignore | 1 + README.md | 2 + early-init.el | 374 ++++++++++++++++++++++----------------- init.el | 49 +++-- 5 files changed, 283 insertions(+), 185 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..33a3756 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +--- +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Emacs. If not, see . +# + +name: CI +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + emacs-version: + - 29.1 + - 29.4 + - 30.1 + python-version: + - 3.11 + steps: + # Cask + - uses: actions/checkout@v2 + - uses: purcell/setup-emacs@master + with: + version: ${{ matrix.emacs-version }} + + - name: Compile + run: | + LISP_ERR_ON_WARN="(setq byte-compile-error-on-warn t) (setq byte-compile-warnings '(not obsolete free-vars))" + emacs -batch -L . --eval "(progn $LISP_ERR_ON_WARN )" -f batch-byte-compile early-init.el + emacs -batch -L . --eval "(progn $LISP_ERR_ON_WARN (load \"early-init.el\" nil t t) )" -f batch-byte-compile init.el diff --git a/.gitignore b/.gitignore index e787da3..85d862e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ !early-init.el !init.el !.images/ +!.github/ !.LICENSE diff --git a/README.md b/README.md index a3e0846..eaa7aba 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # *minimal-emacs.d* - A Customizable Emacs `init.el` and `early-init.el` that Provides Better Defaults and Faster Startup +![](https://raw.githubusercontent.com/jamescherti/easysession.el/main/.images/made-for-gnu-emacs.svg) +![Build Status](https://github.com/jamescherti/minimal-emacs.d/actions/workflows/ci.yml/badge.svg) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) The **minimal-emacs.d** project is a lightweight, bloat-free Emacs base (`init.el` and `early-init.el`) that **gives you full control over your configuration** (without the complexity of, for instance, Doom Emacs or Spacemacs). It provides better defaults, an optimized startup, and a clean foundation for building your own vanilla Emacs setup. diff --git a/early-init.el b/early-init.el index 6aef9ab..71b2364 100644 --- a/early-init.el +++ b/early-init.el @@ -1,4 +1,4 @@ -;;; early-init.el --- Early Init -*- no-byte-compile: t; lexical-binding: t; -*- +;;; early-init.el --- Early Init -*- lexical-binding: t; -*- ;; Author: James Cherti ;; URL: https://github.com/jamescherti/minimal-emacs.d @@ -18,16 +18,12 @@ (defvar minimal-emacs-ui-features '() "List of user interface features to disable in minimal Emacs setup. - This variable holds a list 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. - -Each feature in the list corresponds to a specific UI component that can be -turned on.") +- `tooltips`: Enables tooltips.") (defvar minimal-emacs-frame-title-format "%b – Emacs" "Template for displaying the title bar of visible and iconified frame.") @@ -60,7 +56,9 @@ By disabling startup messages, this slightly enhances performance and provides a cleaner startup. The tradeoff is that you won't be informed of the progress or any relevant activities during startup.") -(defvar minimal-emacs-disable-mode-line-during-startup nil +(defvar minimal-emacs--optimize-file-name-handler-alist t) + +(defvar minimal-emacs-disable-mode-line-during-startup t "Disable the mode line during startup to improve performance. This reduces visual clutter and slightly enhances startup performance. The tradeoff is that the mode line is hidden during the startup phase, giving a more @@ -81,9 +79,16 @@ minimalistic appearance during startup.") "Verify that the Emacs configuration has loaded successfully." (unless minimal-emacs--success (cond - (t (error (concat "Configuration error in: '%s'. Debug by starting Emacs " - "with: emacs --debug-init") - minimal-emacs--stage))))) + ((and (or (string= minimal-emacs--stage "pre-early-init.el") + (string= minimal-emacs--stage "early-init.el") + (string= minimal-emacs--stage "post-early-init.el")) + (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 in: '%s'. Debug by starting Emacs with: emacs --debug-init" + minimal-emacs--stage))))) (add-hook 'emacs-startup-hook #'minimal-emacs--check-success 102) (defun minimal-emacs-load-user-init (filename) @@ -92,7 +97,7 @@ minimalistic appearance during startup.") minimal-emacs-user-directory))) (when (file-exists-p init-file) (setq minimal-emacs--stage (file-name-nondirectory init-file)) - (load init-file nil t t)))) + (load init-file nil t)))) (minimal-emacs-load-user-init "pre-early-init.el") (setq minimal-emacs--stage "early-init.el") @@ -105,152 +110,16 @@ minimalistic appearance during startup.") ;; Garbage collection significantly affects startup times. This setting delays ;; garbage collection during startup but will be reset later. +(setq garbage-collection-messages minimal-emacs-debug) + +(defun minimal-emacs--restore-gc-cons-threshold () + "Restore `minimal-emacs-gc-cons-threshold'." + (setq gc-cons-threshold minimal-emacs-gc-cons-threshold)) + (when minimal-emacs-optimize-startup-gc (setq gc-cons-threshold most-positive-fixnum) - - (defun minimal-emacs--restore-gc-cons-threshold () - "Restore `minimal-emacs-gc-cons-threshold'." - (setq gc-cons-threshold minimal-emacs-gc-cons-threshold)) (add-hook 'emacs-startup-hook #'minimal-emacs--restore-gc-cons-threshold 105)) -;;; Misc - -(set-language-environment "UTF-8") - -;; Set-language-environment sets default-input-method, which is unwanted. -(setq default-input-method nil) - -(setq warning-minimum-level (if minimal-emacs-debug :warning :error)) - -;;; Performance - -;; 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))) - ;; 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 (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. - (put 'file-name-handler-alist 'initial-value old-value) - ;; 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. - (define-advice command-line-1 (:around (fn args-left) respect-file-handlers) - (let ((file-name-handler-alist - (if args-left old-value file-name-handler-alist))) - (funcall fn args-left))) - - ;; Restore the old value to reset it as needed. - (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 old-value)))) - - (add-hook - 'emacs-startup-hook #'minimal-emacs--restore-file-name-handler-alist 101)) - - (unless noninteractive - (unless minimal-emacs-debug - (when minimal-emacs-inhibit-redisplay-during-startup - ;; Suppress redisplay and redraw during startup to avoid delays and - ;; prevent flashing an unstyled Emacs frame. - (defun minimal-emacs--reset-inhibit-redisplay () - (setq-default inhibit-redisplay nil) - (remove-hook 'post-command-hook #'minimal-emacs--reset-inhibit-redisplay)) - - (setq-default inhibit-redisplay t) - (add-hook 'post-command-hook #'minimal-emacs--reset-inhibit-redisplay -100)) - - (when minimal-emacs-inhibit-message-during-startup - (defun minimal-emacs--reset-inhibit-message () - (setq-default inhibit-message nil) - (remove-hook 'post-command-hook #'minimal-emacs--reset-inhibit-message)) - - (setq-default inhibit-message t) - (add-hook 'post-command-hook #'minimal-emacs--reset-inhibit-message -100)) - - (put 'mode-line-format - 'initial-value (default-toplevel-value 'mode-line-format)) - (when minimal-emacs-disable-mode-line-during-startup - (setq-default mode-line-format nil) - (dolist (buf (buffer-list)) - (with-current-buffer buf - (setq mode-line-format nil)))) - - (defun minimal-emacs--startup-load-user-init-file (fn &rest args) - "Advice for startup--load-user-init-file to reset mode-line-format." - (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)))))) - - (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) - - (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))))) - ;;; Native compilation and Byte compilation (if (and (featurep 'native-compile) @@ -272,6 +141,184 @@ minimalistic appearance during startup.") (setq byte-compile-warnings minimal-emacs-debug byte-compile-verbose minimal-emacs-debug) +;;; Miscellaneous + +(set-language-environment "UTF-8") + +;; Set-language-environment sets default-input-method, which is unwanted. +(setq default-input-method nil) + +;; 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))) + +;;; 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 (and (not (daemonp)) (not noninteractive)) + ;; 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) + + (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 (daemonp)) + (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 (daemonp)) + (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 (daemonp)) + (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 + +(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)))))) + +(when (and minimal-emacs-disable-mode-line-during-startup + (not (daemonp)) + (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 + (setq mode-line-format nil))) + (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 @@ -290,17 +337,22 @@ minimalistic appearance during startup.") (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 (daemonp) (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) - (define-advice startup--load-user-init-file - (:after (&rest _) minimal-emacs-setup-toolbar) - (advice-remove #'tool-bar-setup #'ignore) - (when tool-bar-mode - (tool-bar-setup)))))) + (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)) @@ -345,4 +397,8 @@ minimalistic appearance during startup.") (provide 'early-init) +;; Local variables: +;; byte-compile-warnings: (not obsolete free-vars) +;; End: + ;;; early-init.el ends here diff --git a/init.el b/init.el index 52bdf57..e9b03f2 100644 --- a/init.el +++ b/init.el @@ -1,4 +1,4 @@ -;;; init.el --- Init -*- no-byte-compile: t; lexical-binding: t; -*- +;;; init.el --- Init -*- lexical-binding: t; -*- ;; Author: James Cherti ;; URL: https://github.com/jamescherti/minimal-emacs.d @@ -16,23 +16,23 @@ ;;; Load pre-init.el (setq minimal-emacs--stage "init.el") -(minimal-emacs-load-user-init "pre-init.el") +(if (fboundp 'minimal-emacs-load-user-init) + (minimal-emacs-load-user-init "pre-init.el") + (error "The early-init.el file failed to loaded")) (setq minimal-emacs--stage "init.el") ;;; Before package -;; 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) - ;; Ask the user whether to terminate asynchronous compilations on exit. ;; This prevents native compilation from leaving temporary files in /tmp. (setq native-comp-async-query-on-exit t) +;; Allow for shorter responses: "y" for yes and "n" for no. +(setq read-answer-short t) +(if (boundp 'use-short-answers) + (setq use-short-answers t) + (advice-add 'yes-or-no-p :override #'y-or-n-p)) + ;;; Undo/redo (setq undo-limit (* 13 160000) @@ -44,26 +44,22 @@ (when (bound-and-true-p minimal-emacs-package-initialize-and-refresh) ;; Initialize and refresh package contents again if needed (package-initialize) - (unless package-archive-contents + (unless (seq-empty-p package-archive-contents) (package-refresh-contents)) ;; Install use-package if necessary (unless (package-installed-p 'use-package) (package-install 'use-package)) - ;; Ensure use-package is available at compile time + ;; Ensure use-package is available (eval-when-compile (require 'use-package))) -;; Ensure the 'use-package' package is installed and loaded - ;;; Features, warnings, and errors ;; Disable warnings from the legacy advice API. They aren't useful. (setq ad-redefinition-action 'accept) -(setq warning-suppress-types '((lexical-binding))) - ;;; Minibuffer ;; Allow nested minibuffers @@ -79,11 +75,6 @@ ;; By default, Emacs "updates" its ui more often than it needs to (setq idle-update-delay 1.0) -;; Allow for shorter responses: "y" for yes and "n" for no. -(setq read-answer-short t) -(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 ;; No beeping or blinking @@ -427,8 +418,8 @@ ;;; Ediff ;; Configure Ediff to use a single frame and split windows horizontally -(setq ediff-window-setup-function #'ediff-setup-windows-plain - ediff-split-window-function #'split-window-horizontally) +(setq ediff-window-setup-function 'ediff-setup-windows-plain + ediff-split-window-function 'split-window-horizontally) ;;; Help @@ -515,8 +506,8 @@ ;;; xref ;; Enable completion in the minibuffer instead of the definitions buffer -(setq xref-show-definitions-function #'xref-show-definitions-completing-read - xref-show-xrefs-function #'xref-show-definitions-completing-read) +(setq xref-show-definitions-function 'xref-show-definitions-completing-read + xref-show-xrefs-function 'xref-show-definitions-completing-read) ;;; abbrev @@ -540,8 +531,14 @@ (put cmd 'disabled nil)) ;;; Load post init -(minimal-emacs-load-user-init "post-init.el") +(when (fboundp 'minimal-emacs-load-user-init) + (minimal-emacs-load-user-init "post-init.el")) (setq minimal-emacs--success t) (provide 'init) + +;; Local variables: +;; byte-compile-warnings: (not obsolete free-vars) +;; End: + ;;; init.el ends here From 4eb6947f783450f0baf0b8548226adcb2333b2fe Mon Sep 17 00:00:00 2001 From: James Cherti <60946298+jamescherti@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:30:29 -0400 Subject: [PATCH 2/4] Rename variable to minimal-emacs-optimize-file-name-handler-alist --- early-init.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/early-init.el b/early-init.el index 71b2364..f1ab1cb 100644 --- a/early-init.el +++ b/early-init.el @@ -56,7 +56,7 @@ By disabling startup messages, this slightly enhances performance and provides a cleaner startup. The tradeoff is that you won't be informed of the progress or any relevant activities during startup.") -(defvar minimal-emacs--optimize-file-name-handler-alist t) +(defvar minimal-emacs-optimize-file-name-handler-alist t) (defvar minimal-emacs-disable-mode-line-during-startup t "Disable the mode line during startup to improve performance. @@ -232,7 +232,7 @@ this stage of initialization." (delete-dups (append file-name-handler-alist minimal-emacs--old-file-name-handler-alist)))) -(when (and minimal-emacs--optimize-file-name-handler-alist +(when (and minimal-emacs-optimize-file-name-handler-alist (not (daemonp)) (not minimal-emacs-debug)) ;; Determine the state of bundled libraries using calc-loaddefs.el. If From c8424cb94c6c1f87b7b9e521778c14b370805d1f Mon Sep 17 00:00:00 2001 From: James Cherti <60946298+jamescherti@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:31:05 -0400 Subject: [PATCH 3/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eaa7aba..338e2dd 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ The minimal-emacs.d init files support additional customization files that are l Always begin your `pre-init.el`, `post-init.el`, `post-early-init.el`, and `pre-early-init.el` files with the following header to prevent them from being byte-compiled and to activate lexical binding: ```elisp -;;; FILENAME.el --- DESCRIPTION -*- no-byte-compile: t; lexical-binding: t; -*- +;;; FILENAME.el --- DESCRIPTION -*- lexical-binding: t; -*- ``` (Replace `FILENAME.el` with the actual name and DESCRIPTION with a brief description of its purpose.) From 70d5507ed130f7b657da61b9e8df9dbe5f599394 Mon Sep 17 00:00:00 2001 From: James Cherti <60946298+jamescherti@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:49:50 -0400 Subject: [PATCH 4/4] Update comments --- early-init.el | 99 +++++++++++++++++++++++++++------------------------ init.el | 38 +++++++------------- 2 files changed, 65 insertions(+), 72 deletions(-) diff --git a/early-init.el b/early-init.el index f1ab1cb..7675277 100644 --- a/early-init.el +++ b/early-init.el @@ -19,11 +19,11 @@ (defvar minimal-emacs-ui-features '() "List of user interface features to disable in minimal Emacs setup. This variable holds a list 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.") +- 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.") @@ -31,39 +31,40 @@ This variable holds a list Emacs UI features that can be enabled: (defvar minimal-emacs-debug (bound-and-true-p init-file-debug) "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-gc-cons-threshold (* 32 1024 1024) + "Value to set `gc-cons-threshold' to after Emacs startup. +Ignored if `minimal-emacs-optimize-startup-gc' is nil.") (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--restore-gc-cons-threshold'.") +(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-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, leading to a cleaner and -faster startup. 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. -By disabling startup messages, this slightly enhances performance and provides a -cleaner startup. The tradeoff is that you won't be informed of the progress or -any relevant activities during startup.") - -(defvar minimal-emacs-optimize-file-name-handler-alist t) - -(defvar minimal-emacs-disable-mode-line-during-startup t - "Disable the mode line during startup to improve performance. -This reduces visual clutter and slightly enhances startup performance. The -tradeoff is that the mode line is hidden during the startup phase, giving a more -minimalistic appearance during startup.") - (defvar minimal-emacs-user-directory user-emacs-directory "The default value of the `user-emacs-directory' variable.") @@ -289,6 +290,19 @@ this stage of initialization." ;;; Performance: Disable mode-line during startup +(when (and minimal-emacs-disable-mode-line-during-startup + (not (daemonp)) + (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 + (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 @@ -306,18 +320,8 @@ this stage of initialization." (setq-default mode-line-format (get 'mode-line-format 'initial-value)))))) -(when (and minimal-emacs-disable-mode-line-during-startup - (not (daemonp)) - (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 - (setq mode-line-format nil))) - (advice-add 'startup--load-user-init-file :around - #'minimal-emacs--startup-load-user-init-file)) +(advice-add 'startup--load-user-init-file :around + #'minimal-emacs--startup-load-user-init-file) ;;; UI elements @@ -344,15 +348,16 @@ this stage of initialization." (when (bound-and-true-p tool-bar-mode) (funcall 'tool-bar-setup)))) -(unless (daemonp) - (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) +(when (and (not (daemonp)) + (not 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))) - (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)) diff --git a/init.el b/init.el index e9b03f2..dc743a1 100644 --- a/init.el +++ b/init.el @@ -178,8 +178,7 @@ (setq auto-save-no-message t) ;; Do not auto-disable auto-save after deleting large chunks of -;; text. The purpose of auto-save is to provide a failsafe, and -;; disabling it contradicts this objective. +;; text. (setq auto-save-include-big-deletions t) (setq auto-save-list-file-prefix @@ -206,8 +205,7 @@ ;;; recentf -;; `recentf' is an that maintains a list of recently accessed files, making it -;; easier to reopen files you have worked on recently. +;; `recentf' is an that maintains a list of recently accessed files. (setq recentf-max-saved-items 300) ; default is 20 (setq recentf-max-menu-items 15) (setq recentf-auto-cleanup (if (daemonp) 300 'never)) @@ -217,8 +215,7 @@ ;;; saveplace -;; `save-place-mode' enables Emacs to remember the last location within a file -;; upon reopening. +;; Enables Emacs to remember the last location within a file upon reopening. (setq save-place-file (expand-file-name "saveplace" user-emacs-directory)) (setq save-place-limit 600) @@ -254,25 +251,20 @@ ;;; Scrolling -;; Enables faster scrolling through unfontified regions. This may result in -;; brief periods of inaccurate syntax highlighting immediately after scrolling, -;; which should quickly self-correct. +;; Enables faster scrolling. This may result in brief periods of inaccurate +;; syntax highlighting, which should quickly self-correct. (setq fast-but-imprecise-scrolling t) ;; Move point to top/bottom of buffer before signaling a scrolling error. (setq scroll-error-top-bottom t) -;; Keeps screen position if the scroll command moved it vertically out of the -;; window. +;; Keep screen position if scroll command moved it vertically out of the window. (setq scroll-preserve-screen-position t) -;; Emacs spends excessive time recentering when the cursor moves more than N -;; lines past the window edges (N is the value of `scroll-conservatively'). This -;; can be slow in larger files. If `scroll-conservatively' is set above 100, the -;; window is never automatically recentered. +;; If `scroll-conservatively' is set above 100, the window is never +;; automatically recentered, which decreases the time spend recentering. (setq scroll-conservatively 101) -;; Reduce cursor lag by: ;; 1. Preventing automatic adjustments to `window-vscroll' for long lines. ;; 2. Resolving the issue of random half-screen jumps during scrolling. (setq auto-window-vscroll nil) @@ -319,9 +311,8 @@ ;; Avoid automatic frame resizing when adjusting settings. (setq global-text-scale-adjust-resizes-frames nil) -;; This controls how long Emacs will blink to show the deleted pairs with -;; `delete-pair'. A longer delay can be annoying as it causes a noticeable pause -;; after each deletion, disrupting the flow of editing. +;; A longer delay can be annoying as it causes a noticeable pause after each +;; deletion, disrupting the flow of editing. (setq delete-pair-blink-delay 0.03) (setq-default left-fringe-width 8) @@ -427,9 +418,8 @@ (setq apropos-do-all t) ;; Fixes #11: Prevents help command completion from triggering autoload. -;; (e.g., apropos-command, apropos-variable, apropos...) -;; Loading additional files for completion can slow down help commands -;; and may unintentionally execute initialization code from some libraries. +;; Loading additional files for completion can slow down help commands and may +;; unintentionally execute initialization code from some libraries. (setq help-enable-completion-autoload nil) (setq help-enable-autoload nil) (setq help-enable-symbol-autoload nil) @@ -449,9 +439,7 @@ (setq eglot-report-progress nil) ; Prevent Eglot minibuffer spam ;; Eglot optimization: Disable `eglot-events-buffer' to maintain consistent -;; performance in long-running Emacs sessions. By default, it retains 2,000,000 -;; lines, and each new event triggers pretty-printing of the entire buffer, -;; leading to a gradual performance decline. +;; performance in long-running Emacs sessions. (setq eglot-events-buffer-config '(:size 0 :format full)) ;;; Flymake