minimal-emacs.d - A Customizable Emacs init.el
and early-init.el
that Provides Better Defaults and Faster Startup
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.
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. (More information about the minimal-emacs.d features can be found here: Features.)
If you're looking for the ideal starter kit to customize Emacs, you've found it. The minimal-emacs.d project is:
- Minimal yet effective: A solid starting point.
- Better defaults: Improved settings for usability, UI, garbage collection, and built-in packages.
- No forced modes: Unlike other frameworks or starter kits, minimal-emacs.d does not impose modes or require packages. You have full control over which global or minor modes to enable and which packages to load with
require
. - Customizable foundation: Designed to be extended, not replaced. This README.md offers extensive recommendations for customizing your minimal-emacs.d configuration. (Reminder: Never modify init.el and early-init.el. Modify these instead...)
The author uses minimal-emacs.d as his early-init.el
and init.el
, alongside 146 packages (See the packages that the author is using here). Yet, thanks to its efficient design, Emacs still starts in just 0.22 seconds:
(The theme shown in the screenshot above is the tomorrow-night-deepblue-theme.el, available on MELPA.)
In addition to minimal-emacs.d, startup speed is influenced by your computer's processing power and disk speed. To establish a baseline, start Emacs with only minimal-emacs.d and no additional configurations, then run M-x emacs-init-time
. Incrementally modify your init files and observe the impact on startup time. For consistent comparisons, always test on the same computer and Emacs version. It's also important to ensure that all packages are deferred using :defer t
and :commands
, which makes Emacs load them only when needed (see additional examples in this README.md). While startup time is important, other factors, like native compilation, are even more important. Although native compilation may introduce some brief initial and negligible initial delay, it is beneficial in the long run as it significantly speeds up Emacs.
- minimal-emacs.d - A Customizable Emacs
init.el
andearly-init.el
that Provides Better Defaults and Faster Startup- Install minimal-emacs.d
- Update minimal-emacs.d
- Customizations: Never modify init.el and early-init.el. Modify these instead...
- Debug on error
- Customizations: UI (pre-early-init.el)
- Customizations: Packages (post-init.el)
- Optimization: Native Compilation
- How to activate recentf, savehist, saveplace, and auto-revert?
- Activating autosave
- Code completion with corfu
- Configuring Vertico, Consult, and Embark
- Code folding
- Changing the default theme
- Enhancing undo/redo
- Configuring Vim keybindings using Evil?
- Configuring LSP Servers with Eglot (built-in)
- Session Management
- Configuring org-mode
- Inhibit the mouse
- Spell checker
- A better Emacs help buffer
- Enhancing the Elisp development experience
- Preventing Emacs from saving custom.el
- Which other customizations can be interesting to add?
- Customizations: pre-early-init.el
- Frequently asked questions
- How to display Emacs startup duration?
- How to use MELPA stable?
- How to load a local lisp file for machine-specific configurations?
- How to load Emacs customizations?
- How to increase gc-cons-threshold?
- How to change the outline-mode or outline-minor-mode Ellipsis (...) to (▼)?
- How to prevent Emacs from loading .dir-locals.el files?
- How to make minimal-emacs.d use an environment variable to change ~/.emacs.d to another directory?
- Are post-early-init.el and pre-init.el the same file in terms of the logic?
- Why is the menu bar disabled by default?
- Why did the author develop minimal-emacs.d?
- How to keep minimal-emacs.d pre-*.el and post-*.el files in a separate directory?
- How to make minimal-emacs.d install packages in the early-init phase instead of the init phase?
- Comments from users
- Features
- Author and license
- Links
- Important: Ensure that the
~/.emacs
and~/.emacs.el
files do not exist. These files cause Emacs to ignore~/.emacs.d/init.el
. This behavior is due to the way Emacs searches for initialization files (more information). Simply delete the ~/.emacs and ~/.emacs.el files avoid this issue. - Debug: If a package or any other functionality is not working as expected, start Emacs with
emacs --debug-init
to enable debug mode and obtain the backtrace. - Prerequisite: git
Execute the following command install this repository into ~/.emacs.d
:
git clone https://github.com/jamescherti/minimal-emacs.d ~/.emacs.d
To install minimal-emacs.d in a non-default directory, use the --init-directory
Emacs option to specify your desired configuration path. For example, to install minimal-emacs.d in ~/.minimal-emacs.d/
, follow these steps:
-
Clone the repository into
~/.minimal-emacs.d/
using:git clone https://github.com/jamescherti/minimal-emacs.d ~/.minimal-emacs.d
-
Start Emacs with the new configuration directory:
emacs --init-directory ~/.minimal-emacs.d/
To keep your Emacs configuration up to date, you can pull the latest changes from the repository. Run the following command in your terminal:
git -C ~/.emacs.d pull
The init.el
and early-init.el
files should never be modified directly because they are intended to be managed by Git during an update.
The minimal-emacs.d init files support additional customization files that are loaded at different stages of the Emacs startup process. These files allow you to further customize the initialization sequence:
-
~/.emacs.d/pre-init.el
: This file is loaded beforeinit.el
. Use it to set up variables or configurations that need to be available early in the initialization process but afterearly-init.el
. -
~/.emacs.d/post-init.el
: This file is loaded afterinit.el
. It is useful for additional configurations or package setups that depend on the configurations ininit.el
. -
~/.emacs.d/pre-early-init.el
: This file is loaded beforeearly-init.el
. Use it for configurations that need to be set even earlier in the startup sequence, typically affecting the initial setup of the Emacs environment. -
~/.emacs.d/post-early-init.el
: This file is loaded afterearly-init.el
but beforeinit.el
. It is useful for setting up configurations that depend on the early initialization but need to be set before the main initialization begins.
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:
;;; FILENAME.el --- DESCRIPTION -*- no-byte-compile: t; lexical-binding: t; -*-
Replace FILENAME.el
with the actual name and DESCRIPTION with a brief description of its purpose.
(Only if you know what you're doing: Removing no-byte-compile: t;
from your init files allows Emacs to compile them, improving load and execution speed. However, if you do so, you may need to add required dependencies. For example, if you're using use-package
, add (require 'use-package)
at the top of post-init.el
to ensure all necessary use-package
variables and functions are loaded.)
Important: The examples in this README reference pre/post init files in the ~/.emacs.d/
directory, but the files pre-early-init.el
, post-early-init.el
, pre-init.el
, and post-init.el
should be placed in the same directory as init.el
and early-init.el
, regardless of their location.
During the development of your init files, the author strongly recommends adding the following line at the very beginning of your ~/.emacs.d/pre-early-init.el
file:
(setq debug-on-error t)
Enabling debug-on-error
at this stage allows you to catch errors that might otherwise cause Emacs to fail silently or behave unpredictably.
Note: Enabling the tool-bar, menu-bar, and similar UI elements may slightly increase your startup time.
To customize your Emacs setup to include various user interface elements, you can use the following settings in your ~/.emacs.d/pre-early-init.el
:
(setq minimal-emacs-ui-features '(context-menu tool-bar menu-bar dialogs tooltips))
These settings control the visibility of dialogs, context menus, toolbars, menu bars, and tooltips.
Native compilation enhances Emacs performance by converting Elisp code into native machine code, resulting in faster execution and improved responsiveness.
-
To check if native compilation is enabled, evaluate:
(native-comp-available-p)
(A non-nil result indicates that native compilation is active.)
-
Ensure all libraries are byte-compiled and native-compiled using compile-angel.el. To install compile-angel, add the following code at the very beginning of your
~/.emacs.d/post-init.el
file, before all other packages:
;; Ensure adding the following compile-angel code at the very beginning
;; of your `~/.emacs.d/post-init.el` file, before all other packages.
(use-package compile-angel
:ensure t
:demand t
:custom
;; Set `compile-angel-verbose` to nil to suppress output from compile-angel.
;; Drawback: The minibuffer will not display compile-angel's actions.
(compile-angel-verbose t)
:config
;; The following directive prevents compile-angel from compiling your init
;; files. If you choose to remove this push to `compile-angel-excluded-files'
;; and compile your pre/post-init files, ensure you understand the
;; implications and thoroughly test your code. For example, if you're using
;; `use-package', you'll need to explicitly add `(require 'use-package)` at
;; the top of your init file.
(push "/pre-init.el" compile-angel-excluded-files)
(push "/post-init.el" compile-angel-excluded-files)
(push "/pre-early-init.el" compile-angel-excluded-files)
(push "/post-early-init.el" compile-angel-excluded-files)
;; A local mode that compiles .el files whenever the user saves them.
;; (add-hook 'emacs-lisp-mode-hook #'compile-angel-on-save-local-mode)
;; A global mode that compiles .el files before they are loaded.
(compile-angel-on-load-mode))
The recentf, savehist, saveplace, and auto-revert built-in packages are already configured by minimal-emacs.d. All you need to do is activate them by adding the following to ~/.emacs.d/post-init.el
:
;; Auto-revert in Emacs is a feature that automatically updates the
;; contents of a buffer to reflect changes made to the underlying file
;; on disk.
(add-hook 'after-init-hook #'global-auto-revert-mode)
;; recentf is an Emacs package that maintains a list of recently
;; accessed files, making it easier to reopen files you have worked on
;; recently.
(add-hook 'after-init-hook #'(lambda()
(let ((inhibit-message t))
(recentf-mode 1))))
(add-hook 'kill-emacs-hook #'recentf-cleanup)
;; savehist is an Emacs feature that preserves the minibuffer history between
;; sessions. It saves the history of inputs in the minibuffer, such as commands,
;; search strings, and other prompts, to a file. This allows users to retain
;; their minibuffer history across Emacs restarts.
(add-hook 'after-init-hook #'savehist-mode)
;; save-place-mode enables Emacs to remember the last location within a file
;; upon reopening. This feature is particularly beneficial for resuming work at
;; the precise point where you previously left off.
(add-hook 'after-init-hook #'save-place-mode)
Enabling auto-save-mode
mitigates the risk of data loss in the event of a crash. Auto-saved data can be recovered using the recover-file
or recover-session
functions.
To enable autosave, add the following to ~/.emacs.d/post-init.el
:
;; Enable `auto-save-mode' to prevent data loss. Use `recover-file' or
;; `recover-session' to restore unsaved changes.
(setq auto-save-default t)
(setq auto-save-interval 300)
(setq auto-save-timeout 30)
When auto-save-visited-mode
is enabled, Emacs will auto-save file-visiting buffers after a certain amount of idle time if the user forgets to save it with save-buffer
or C-x s
for example.
This is different from auto-save-mode
: auto-save-mode
periodically saves all modified buffers, creating backup files, including those not associated with a file, while auto-save-visited-mode
only saves file-visiting buffers after a period of idle time, directly saving to the file itself without creating backup files.
(setq auto-save-visited-interval 5) ; Save after 5 seconds if inactivity
(auto-save-visited-mode 1)
Corfu enhances in-buffer completion by displaying a compact popup with current candidates, positioned either below or above the point. Candidates can be selected by navigating up or down.
Cape, or Completion At Point Extensions, extends the capabilities of in-buffer completion. It integrates with Corfu or the default completion UI, by providing additional backends through completion-at-point-functions.
To configure corfu
and cape
, add the following to ~/.emacs.d/post-init.el
:
(use-package corfu
:ensure t
:defer t
:commands (corfu-mode global-corfu-mode)
:hook ((prog-mode . corfu-mode)
(shell-mode . corfu-mode)
(eshell-mode . corfu-mode))
:custom
;; Hide commands in M-x which do not apply to the current mode.
(read-extended-command-predicate #'command-completion-default-include-p)
;; Disable Ispell completion function. As an alternative try `cape-dict'.
(text-mode-ispell-word-completion nil)
(tab-always-indent 'complete)
;; Enable Corfu
:config
(global-corfu-mode))
(use-package cape
:ensure t
:defer t
:commands (cape-dabbrev cape-file cape-elisp-block)
:bind ("C-c p" . cape-prefix-map)
:init
;; Add to the global default value of `completion-at-point-functions' which is
;; used by `completion-at-point'.
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-elisp-block))
Vertico, Consult, and Embark collectively enhance Emacs' completion and navigation capabilities. Vertico provides a vertical completion interface, making it easier to navigate and select from completion candidates (e.g., when M-x
is pressed). Consult offers a suite of commands for efficient searching, previewing, and interacting with buffers, file contents, and more, improving various tasks. Embark integrates with these tools to provide context-sensitive actions and quick access to commands based on the current selection, further improving user efficiency and workflow within Emacs. Together, they create a cohesive and powerful environment for managing completions and interactions.
Add the following to ~/.emacs.d/post-init.el
to set up Vertico, Consult, and Embark:
(use-package vertico
;; (Note: It is recommended to also enable the savehist package.)
:ensure t
:defer t
:commands vertico-mode
:hook (after-init . vertico-mode))
(use-package orderless
;; Vertico leverages Orderless' flexible matching capabilities, allowing users
;; to input multiple patterns separated by spaces, which Orderless then
;; matches in any order against the candidates.
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles partial-completion)))))
(use-package marginalia
;; Marginalia allows Embark to offer you preconfigured actions in more contexts.
;; In addition to that, Marginalia also enhances Vertico by adding rich
;; annotations to the completion candidates displayed in Vertico's interface.
:ensure t
:defer t
:commands (marginalia-mode marginalia-cycle)
:hook (after-init . marginalia-mode))
(use-package embark
;; Embark is an Emacs package that acts like a context menu, allowing
;; users to perform context-sensitive actions on selected items
;; directly from the completion interface.
:ensure t
:defer t
:commands (embark-act
embark-dwim
embark-export
embark-collect
embark-bindings
embark-prefix-help-command)
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
(setq prefix-help-command #'embark-prefix-help-command)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
:ensure t
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(use-package consult
:ensure t
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command)
("C-x b" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("C-x 5 b" . consult-buffer-other-frame)
("C-x t b" . consult-buffer-other-tab)
("C-x r b" . consult-bookmark)
("C-x p b" . consult-project-buffer)
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop)
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake)
("M-g g" . consult-goto-line)
("M-g M-g" . consult-goto-line)
("M-g o" . consult-outline)
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings in `search-map'
("M-s d" . consult-find)
("M-s c" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history)
("M-s e" . consult-isearch-history)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history)
("M-r" . consult-history))
;; Enable automatic preview at point in the *Completions* buffer.
:hook (completion-list-mode . consult-preview-at-point-mode)
:init
;; Optionally configure the register formatting. This improves the register
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
(setq consult-narrow-key "<"))
The built-in outline-minor-mode
provides structured code folding in modes such as Emacs Lisp and Python, allowing users to collapse and expand sections based on headings or indentation levels. This feature enhances navigation and improves the management of large files with hierarchical structures.
Alternatively, hs-minor-mode
offers basic code folding for blocks defined by curly braces, functions, or other language-specific delimiters. However, for more flexible folding that supports multiple nested levels, outline-minor-mode
is generally the preferred choice, as it enables finer control over section visibility in deeply structured code.
For example, to enable outline-minor-mode
in Emacs Lisp:
(add-hook 'emacs-lisp-mode-hook #'outline-minor-mode)
For folding based on indentation levels, the outline-indent Emacs package provides a minor mode that enables folding according to the indentation structure:
(use-package outline-indent
:ensure t
:defer t
:commands outline-indent-minor-mode
:custom
(outline-indent-ellipsis " ▼ ")
:init
;; The minor mode can also be automatically activated for a certain modes.
(add-hook 'python-mode-hook #'outline-indent-minor-mode)
(add-hook 'python-ts-mode-hook #'outline-indent-minor-mode)
(add-hook 'yaml-mode-hook #'outline-indent-minor-mode)
(add-hook 'yaml-ts-mode-hook #'outline-indent-minor-mode))
In addition to code folding, outline-indent also allows: moving indented blocks up and down, indenting/unindenting to adjust indentation levels, inserting a new line with the same indentation level as the current line, Move backward/forward to the indentation level of the current line, and more.
For instance, to switch to a another theme than the default one, add the following to the ~/.emacs.d/post-init.el
file:
(mapc #'disable-theme custom-enabled-themes) ; Disable all active themes
(load-theme 'modus-operandi t) ; Load the built-in theme
(If you prefer dark themes, replace modus-operandi
with modus-vivendi
.)
Emacs includes several built-in themes that you can use without installing additional packages:
tango-dark
(Face colors using the Tango palette. Dark background.)tango
(Face colors using the Tango palette. Light background.)modus-operandi
modus-operandi-deuteranopia
modus-operandi-tinted
modus-operandi-tritanopia
modus-vivendi
modus-vivendi-deuteranopia
modus-vivendi-tinted
modus-vivendi-tritanopia
tsdh-dark
(A dark theme used and created by Tassilo Horn.)tsdh-light
(A light Emacs theme.)adwaita
(Face colors similar to the default theme of Gnome 3 / Adwaita.)deeper-blue
(Face colors using a deep blue background.)dichromacy
(Face colors suitable for red/green color-blind users.)leuven-dark
(Face colors with a dark background.)leuven
(Face colors with a light background.)light-blue
(Face colors utilizing a light blue background.)manoj-dark
(Very high contrast faces with a black background.)misterioso
(Predominantly blue/cyan faces on a dark cyan background.)wheatgrass
(High-contrast green/blue/brown faces on a black background.)whiteboard
(Face colors similar to markers on a whiteboard.)wombat
(Medium-contrast faces with a dark gray background.)
(To experiment with different themes, use M-x customize-themes
.)
If you're interested in exploring third-party Emacs themes, consider the following:
ef-themes
(available on MELPA): A collection of light and dark themes for GNU Emacs, designed to offer colorful yet highly legible options. They are aimed at users seeking something with more visual flair compared to the more minimalist modus-themes.doom-themes
(available on MELPA): An extensive collection of high-quality, visually appealing themes for Emacs, designed to offer a sleek and modern aesthetic, while drawing inspiration from popular community themes.tomorrow-night-deepblue-theme
(available on MELPA): A beautiful deep blue variant of the Tomorrow Night theme, which is renowned for its elegant color palette. It features a deep blue background color that creates a calming atmosphere. This theme is a great choice for those who miss the blue themes that were trendy a few years ago. (The theme was inspired by classic text editors such as QuickBASIC, RHIDE, and Turbo Pascal, as well as tools such as Midnight Commander.)
The undo-fu package is a lightweight wrapper around Emacs' built-in undo system, providing more convenient undo/redo functionality while preserving access to the full undo history. The undo-fu-session package complements undo-fu by enabling the saving and restoration of undo history across Emacs sessions, even after restarting.
The default undo system in Emacs has two main issues that undo-fu fixes:
- Redo requires two steps: To redo an action after undoing, you need to press a key twice, which can be annoying and inefficient.
- Accidental over-redo: When redoing, it's easy to go too far back, past the point where you started the undo, which makes it hard to return to the exact state you wanted to restore.
To install and configure these packages, add the following to ~/.emacs.d/post-init.el
:
;; The undo-fu package is a lightweight wrapper around Emacs' built-in undo
;; system, providing more convenient undo/redo functionality.
(use-package undo-fu
:defer t
:commands (undo-fu-only-undo
undo-fu-only-redo
undo-fu-only-redo-all
undo-fu-disable-checkpoint)
:config
(global-unset-key (kbd "C-z"))
(global-set-key (kbd "C-z") 'undo-fu-only-undo)
(global-set-key (kbd "C-S-z") 'undo-fu-only-redo))
;; The undo-fu-session package complements undo-fu by enabling the saving
;; and restoration of undo history across Emacs sessions, even after restarting.
(use-package undo-fu-session
:defer t
:commands undo-fu-session-global-mode
:hook (after-init . undo-fu-session-global-mode))
Configuring Vim keybindings in Emacs can greatly enhance your editing efficiency if you are accustomed to Vim's modal editing style. Add the following to ~/.emacs.d/post-init.el
to set up Evil mode:
;; Required by evil-collection
(eval-when-compile
;; It has to be defined before evil
(setq evil-want-integration t)
(setq evil-want-keybinding nil))
;; Uncomment the following if you are using undo-fu
;; (setq evil-undo-system 'undo-fu)
;; Vim emulation
(use-package evil
:ensure t
:defer t
:commands (evil-mode evil-define-key)
:hook (after-init . evil-mode))
(eval-when-compile
;; It has to be defined before evil-colllection
(setq evil-collection-setup-minibuffer t))
(use-package evil-collection
:after evil
:ensure t
:config
(evil-collection-init))
You can also use the vim-tab-bar Emacs package to ~/.emacs.d/post-init.el
to give the built-in Emacs tab-bar a style similar to Vim's tabbed browsing interface:
;; Give Emacs tab-bar a style similar to Vim's
(use-package vim-tab-bar
:ensure t
:commands vim-tab-bar-mode
:hook (after-init . vim-tab-bar-mode))
The evil-surround
package simplifies handling surrounding characters, such as parentheses, brackets, quotes, etc. It provides key bindings to easily add, change, or delete these surrounding characters in pairs. For instance, you can surround the currently selected text with double quotes in visual state using S"
or gS"
:
(use-package evil-surround
:after evil
:ensure t
:defer t
:commands global-evil-surround-mode
:custom
(evil-surround-pairs-alist
'((?\( . ("(" . ")"))
(?\[ . ("[" . "]"))
(?\{ . ("{" . "}"))
(?\) . ("(" . ")"))
(?\] . ("[" . "]"))
(?\} . ("{" . "}"))
(?< . ("<" . ">"))
(?> . ("<" . ">"))))
:hook (after-init . global-evil-surround-mode))
You can also add the following code to enable commenting and uncommenting by pressing gcc
in normal mode and gc
in visual mode (thanks you to the Reddit user u/mistakenuser for this contribution, which replaces the evil-commentary package):
(with-eval-after-load "evil"
(evil-define-operator my-evil-comment-or-uncomment (beg end)
"Toggle comment for the region between BEG and END."
(interactive "<r>")
(comment-or-uncomment-region beg end))
(evil-define-key 'normal 'global (kbd "gc") 'my-evil-comment-or-uncomment))
To set up Language Server Protocol (LSP) servers using Eglot, you can configure it in your Emacs setup as follows. This configuration ensures minimal disruption from Eglot's progress reporting and optimizes performance by disabling unnecessary logging.
To configure eglot
, add the following to ~/.emacs.d/post-init.el
:
(use-package eglot
:ensure nil
:defer t
:commands (eglot
eglot-ensure
eglot-rename
eglot-format-buffer))
Here is an example of how to configure Eglot to enable or disable certain options for the pylsp
server in Python development. (Note that a third-party tool, python-lsp-server, must be installed):
(setq-default eglot-workspace-configuration
`(:pylsp (:plugins
(;; Fix imports and syntax using `eglot-format-buffer`
:isort (:enabled t)
:autopep8 (:enabled t)
;; Syntax checkers (works with Flymake)
:pylint (:enabled t)
:pycodestyle (:enabled t)
:flake8 (:enabled t)
:pyflakes (:enabled t)
:pydocstyle (:enabled t)
:mccabe (:enabled t)
:yapf (:enabled :json-false)
:rope_autoimport (:enabled :json-false)))))
(add-hook 'python-mode-hook #'eglot)
(add-hook 'python-ts-mode-hook #'eglot)
The easysession.el
Emacs package is a session manager for Emacs that can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, windows/splits, the built-in tab-bar (including tabs, their buffers, and windows), and Emacs frames. It offers a convenient and effortless way to manage Emacs editing sessions and utilizes built-in Emacs functions to persist and restore frames.
To configure easysession, add the following to ~/.emacs.d/post-init.el
:
(use-package easysession
:ensure t
:defer t
:commands (easysession-switch-to
easysession-save-as
easysession-save-mode
easysession-load-including-geometry)
:custom
(easysession-mode-line-misc-info t) ; Display the session in the modeline
(easysession-save-interval (* 10 60)) ; Save every 10 minutes
:init
;; Key mappings:
;; C-c l for switching sessions
;; and C-c s for saving the current session
(global-set-key (kbd "C-c l") 'easysession-switch-to)
(global-set-key (kbd "C-c s") 'easysession-save-as)
;; The depth 102 and 103 have been added to to `add-hook' to ensure that the
;; session is loaded after all other packages. (Using 103/102 is particularly
;; useful for those using minimal-emacs.d, where some optimizations restore
;; `file-name-handler-alist` at depth 101 during `emacs-startup-hook`.)
(add-hook 'emacs-startup-hook #'easysession-load-including-geometry 102)
(add-hook 'emacs-startup-hook #'easysession-save-mode 103))
To configure org-mode, add the following to ~/.emacs.d/post-init.el
:
(use-package org
:ensure t
:defer t
:commands (org-mode org-version)
:mode
("\\.org\\'" . org-mode)
:custom
(org-hide-leading-stars t)
(org-startup-indented t)
(org-adapt-indentation nil)
(org-edit-src-content-indentation 0)
(org-startup-truncated nil)
(org-fontify-done-headline t)
(org-fontify-todo-headline t)
(org-fontify-whole-heading-line t)
(org-fontify-quote-and-verse-blocks t))
The inhibit-mouse package disables mouse input in Emacs.
This package is useful for users who want to disable the mouse to:
- Prevent accidental clicks or cursor movements that may unexpectedly change the cursor position.
- Reinforce a keyboard-centric workflow by discouraging reliance on the mouse for navigation.
To configure inhibit-mouse, add the following to ~/.emacs.d/post-init.el
:
(use-package inhibit-mouse
:ensure t
:config
(if (daemonp)
(add-hook 'server-after-make-frame-hook #'inhibit-mouse-mode)
(inhibit-mouse-mode 1)))
NOTE: inhibit-mouse-mode
allows users to disable and re-enable mouse functionality, giving them the flexibility to use the mouse when needed.
The flyspell
package is a built-in Emacs minor mode that provides on-the-fly spell checking. It highlights misspelled words as you type, offering interactive corrections. In text modes, it checks the entire buffer, while in programming modes, it typically checks only comments and strings. It integrates with external spell checkers like aspell
, hunspell
, or ispell
to provide suggestions and corrections.
To configure flyspell, add the following to ~/.emacs.d/post-init.el
:
(use-package ispell
:ensure nil
:defer t
:commands (ispell ispell-minor-mode)
:custom
;; Set the ispell program name to aspell
(ispell-program-name "aspell")
;; Configures Aspell's suggestion mode to "ultra", which provides more
;; aggressive and detailed suggestions for misspelled words. The language
;; is set to "en_US" for US English, which can be replaced with your desired
;; language code (e.g., "en_GB" for British English, "de_DE" for German).
(ispell-extra-args '("--sug-mode=ultra" "--lang=en_US")))
(use-package flyspell
:ensure nil
:defer t
:commands flyspell-mode
:hook
((prog-mode . flyspell-prog-mode)
(text-mode . (lambda()
(if (or (derived-mode-p 'yaml-mode)
(derived-mode-p 'yaml-ts-mode)
(derived-mode-p 'ansible-mode))
(flyspell-prog-mode)
(flyspell-mode 1)))))
:config
;; Remove strings from Flyspell
(setq flyspell-prog-text-faces (delq 'font-lock-string-face
flyspell-prog-text-faces))
;; Remove doc from Flyspell
(setq flyspell-prog-text-faces (delq 'font-lock-doc-face
flyspell-prog-text-faces)))
Helpful is an alternative to the built-in Emacs help that provides much more contextual information.
To configure helpful, add the following to ~/.emacs.d/post-init.el
:
(use-package helpful
:defer t
:commands (helpful-callable
helpful-variable
helpful-key
helpful-command
helpful-at-point
helpful-function)
:bind
([remap describe-command] . helpful-command)
([remap describe-function] . helpful-callable)
([remap describe-key] . helpful-key)
([remap describe-symbol] . helpful-symbol)
([remap describe-variable] . helpful-variable)
:custom
(helpful-max-buffers 7))
To enhance the Elisp development experience, add the following to ~/.emacs.d/post-init.el
:
;; Enables automatic indentation of code while typing
(use-package aggressive-indent
:ensure t
:defer t
:commands aggressive-indent-mode
:hook
(emacs-lisp-mode . aggressive-indent-mode))
;; Highlights function and variable definitions in Emacs Lisp mode
(use-package highlight-defined
:ensure t
:defer t
:commands highlight-defined-mode
:hook
(emacs-lisp-mode . highlight-defined-mode))
Other optional packages that may be useful include:
;; Prevent parenthesis imbalance
(use-package paredit
:ensure t
:defer t
:commands paredit-mode
:hook
(emacs-lisp-mode . paredit-mode)
:config
(define-key paredit-mode-map (kbd "RET") nil))
;; For paredit+Evil mode users: enhances paredit with Evil mode compatibility
;; --------------------------------------------------------------------------
;; (use-package enhanced-evil-paredit
;; :ensure t
;; :defer t
;; :commands enhanced-evil-paredit-mode
;; :hook
;; (paredit-mode . enhanced-evil-paredit-mode))
;; Displays visible indicators for page breaks
(use-package page-break-lines
:ensure t
:defer t
:commands (page-break-lines-mode
global-page-break-lines-mode)
:hook
(emacs-lisp-mode . page-break-lines-mode))
;; Provides functions to find references to functions, macros, variables,
;; special forms, and symbols in Emacs Lisp
(use-package elisp-refs
:ensure t
:defer t
:commands (elisp-refs-function
elisp-refs-macro
elisp-refs-variable
elisp-refs-special
elisp-refs-symbol))
To prevent Emacs from saving customization information to a custom file, set custom-file
to null-device
by adding to the following to ~/.emacs.d/post-init.el
:
(setq custom-file null-device)
-
Read the following article from the same author: Essential Emacs Packages for Efficient Software Development and Text Editing
-
You can also add the following to
~/.emacs.d/post-init.el
:
;; Allow Emacs to upgrade built-in packages, such as Org mode
(setq package-install-upgrade-built-in t)
;; Display the current line and column numbers in the mode line
(setq line-number-mode t)
(setq column-number-mode t)
(setq mode-line-position-column-line-format '("%l:%C"))
;; Display of line numbers in the buffer:
;; (display-line-numbers-mode 1)
(use-package which-key
:ensure nil ; builtin
:defer t
:commands which-key-mode
:hook (after-init . which-key-mode)
:custom
(which-key-idle-delay 1.5)
(which-key-idle-secondary-delay 0.25)
(which-key-add-column-padding 1)
(which-key-max-description-length 40))
(unless (and (eq window-system 'mac)
(bound-and-true-p mac-carbon-version-string))
;; Enables `pixel-scroll-precision-mode' on all operating systems and Emacs
;; versions, except for emacs-mac.
;;
;; Enabling `pixel-scroll-precision-mode' is unnecessary with emacs-mac, as
;; this version of Emacs natively supports smooth scrolling.
;; https://bitbucket.org/mituharu/emacs-mac/commits/65c6c96f27afa446df6f9d8eff63f9cc012cc738
(setq pixel-scroll-precision-use-momentum nil) ; Precise/smoother scrolling
(pixel-scroll-precision-mode 1))
;; Display the time in the modeline
(add-hook 'after-init-hook #'display-time-mode)
;; Paren match highlighting
(add-hook 'after-init-hook #'show-paren-mode)
;; Track changes in the window configuration, allowing undoing actions such as
;; closing windows.
(add-hook 'after-init-hook #'winner-mode)
;; Replace selected text with typed text
;; (delete-selection-mode 1)
(use-package uniquify
:ensure nil
:custom
(uniquify-buffer-name-style 'reverse)
(uniquify-separator "•")
(uniquify-after-kill-buffer-p t)
(uniquify-ignore-buffers-re "^\\*"))
;; Window dividers separate windows visually. Window dividers are bars that can
;; be dragged with the mouse, thus allowing you to easily resize adjacent
;; windows.
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Dividers.html
(add-hook 'after-init-hook #'window-divider-mode)
;; Dired buffers: Automatically hide file details (permissions, size,
;; modification date, etc.) and all the files in the `dired-omit-files' regular
;; expression for a cleaner display.
(add-hook 'dired-mode-hook #'dired-hide-details-mode)
;; Hide files from dired
(setq dired-omit-files (concat "\\`[.]\\'"
"\\|\\(?:\\.js\\)?\\.meta\\'"
"\\|\\.\\(?:elc|a\\|o\\|pyc\\|pyo\\|swp\\|class\\)\\'"
"\\|^\\.DS_Store\\'"
"\\|^\\.\\(?:svn\\|git\\)\\'"
"\\|^\\.ccls-cache\\'"
"\\|^__pycache__\\'"
"\\|^\\.project\\(?:ile\\)?\\'"
"\\|^flycheck_.*"
"\\|^flymake_.*"))
(add-hook 'dired-mode-hook #'dired-omit-mode)
;; Configure Emacs to ask for confirmation before exiting
(setq confirm-kill-emacs 'y-or-n-p)
;; Enabled backups save your changes to a file intermittently
(setq make-backup-files t)
(setq vc-make-backup-files t)
(setq kept-old-versions 10)
(setq kept-new-versions 10)
It is also recommended to read the following articles:
- Automating Table of Contents Update for Markdown Documents (e.g., README.md)
- Maintaining proper indentation in indentation-sensitive programming languages
Emacs, by default, stores various configuration files, caches, backups, and other data in the ~/.emacs.d
directory. Over time, this directory can become cluttered with numerous files, making it difficult to manage and maintain.
A common solution to this issue is installing the no-littering package; however, this package is not essential.
An alternative lightweight approach is to simply change the default ~/.emacs.d
directory to ~/.emacs.d/var/
, which will contain all the files that Emacs typically stores in the base directory. This can be accomplished by adding the following code to ~/.emacs.d/pre-early-init.el
:
;; Reducing clutter in ~/.emacs.d by redirecting files to ~/emacs.d/var/
;; IMPORTANT: This part should be in the pre-early-init.el file
(setq minimal-emacs-var-dir (expand-file-name "var/" minimal-emacs-user-directory))
(setq package-user-dir (expand-file-name "elpa" minimal-emacs-var-dir))
(setq user-emacs-directory minimal-emacs-var-dir)
IMPORTANT: The code above should be added to ~/.emacs.d/pre-early-init.el
, not the other files, as it modifies the behavior of all subsequent init files.
Add the straight.el bootstrap code to ~/.emacs.d/pre-init.el
:
;; Straight bootstrap
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name
"straight/repos/straight.el/bootstrap.el"
(or (bound-and-true-p straight-base-dir)
user-emacs-directory)))
(bootstrap-version 7))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
Add to ~/.emacs.d/pre-early-init.el
:
;; By default, minimal-emacs-package-initialize-and-refresh is set to t, which
;; makes minimal-emacs.d call the built-in package manager. Since Elpaca will
;; replace the package manager, there is no need to call it.
(setq minimal-emacs-package-initialize-and-refresh nil)
And add the elpaca bootstrap code to ~/.emacs.d/pre-init.el
:
(defvar elpaca-installer-version 0.10)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
:ref nil :depth 1 :inherit ignore
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
:build (:not elpaca--activate-package)))
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
(build (expand-file-name "elpaca/" elpaca-builds-directory))
(order (cdr elpaca-order))
(default-directory repo))
(add-to-list 'load-path (if (file-exists-p build) build repo))
(unless (file-exists-p repo)
(make-directory repo t)
(when (<= emacs-major-version 28) (require 'subr-x))
(condition-case-unless-debug err
(if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
,@(when-let* ((depth (plist-get order :depth)))
(list (format "--depth=%d" depth) "--no-single-branch"))
,(plist-get order :repo) ,repo))))
((zerop (call-process "git" nil buffer t "checkout"
(or (plist-get order :ref) "--"))))
(emacs (concat invocation-directory invocation-name))
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
((require 'elpaca))
((elpaca-generate-autoloads "elpaca" repo)))
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
(error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
(unless (require 'elpaca-autoloads nil t)
(require 'elpaca)
(elpaca-generate-autoloads "elpaca" repo)
(load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))
To measure and display the time taken for Emacs to start, you can use the following Emacs Lisp function. This function will report both the startup duration and the number of garbage collections that occurred during initialization.
Add the following to your ~/.emacs.d/pre-early-init.el
file:
(defun display-startup-time ()
"Display the startup time and number of garbage collections."
(message "Emacs init loaded in %.2f seconds (Full emacs-startup: %.2fs) with %d garbage collections."
(float-time (time-subtract after-init-time before-init-time))
(time-to-seconds (time-since before-init-time))
gcs-done))
(add-hook 'emacs-startup-hook #'display-startup-time 100)
(Alternatively, you may use the built-in M-x emacs-init-time
command to obtain the startup duration. However, emacs-init-time
does not account for the portion of the startup process that occurs after after-init-time
.)
By default, minimal-emacs.d uses MELPA instead of MELPA Stable. If you prefer to use MELPA Stable, you can follow the instructions below. However, please note the following important warning:
IMPORTANT: Some MELPA Stable packages are outdated and lack important features.
Here are the key differences between MELPA (the default repository used in minimal-emacs.d) and MELPA Stable:
- MELPA is a rolling release repository for Emacs packages, where packages are continuously updated with the latest commits from their respective development branches, delivering the most current features and bug fixes. While MELPA features the latest changes, most Emacs package developers have learned to maintain a relatively stable master branch, which contributes to MELPA’s overall stability. Furthermore, MELPA includes a broader selection of packages.
- In contrast, MELPA Stable is a repository that hosts versioned, tagged releases of packages. However, MELPA Stable does not guarantee more reliability than MELPA, as its tagged versions may still suffer from issues like uncoordinated dependencies or incomplete testing, and updates are less frequent, often based on developer discretion rather than every new commit.
If you prefer MELPA Stable over MELPA, you can add MELPA Stable and prioritize it. To ensure packages are fetched from MELPA Stable first, add the following configuration to ~/.emacs.d/post-early-init.el
:
;; Add melpa-stable to `package-archives'
(push '("melpa-stable" . "https://stable.melpa.org/packages/") package-archives)
;; This change increases MELPA Stable priority to 70, above MELPA,
;; ensuring that MELPA is preferred for package installations
;; over MELPA Stable.
(customize-set-variable 'package-archive-priorities '(("gnu" . 99)
("nongnu" . 80)
("melpa-stable" . 70)
("melpa" . 0)))
Add the following line to the end of your post-init.el
file:
(minimal-emacs-load-user-init "local.el")
This allows local.el
to load, enabling custom configurations specific to the machine.
(Ensure that local.el
is in the same directory as post-init.el
.)
To load customizations saved by Emacs (M-x customize
), add the following code snippet to the post-init.el
file. This ensures that the custom file, typically set to a separate file for user preferences, is loaded without errors or messages during startup:
(load custom-file 'noerror 'nomessage)
Add the following to ~/.emacs.d/pre-early-init.el
to ensure that minimal-emacs.d restores the specified amount after startup:
(setq minimal-emacs-gc-cons-threshold (* 64 1024 1024))
If you want to to change the outline-mode or outline-minor-mode Ellipsis (...) to (▼), use the code snippet in this article: Changing the Ellipsis (“…”) in outline-mode and outline-minor-mode.
By default, Emacs loads .dir-locals.el
from the current directory or its parents and applies project-specific settings such as indentation, compilation commands, or custom minor modes. While useful in many cases, this behavior can introduce unintended overrides, inconsistencies, or even security risks when working with untrusted projects.
If you want to prevent Emacs from applying these directory-local settings, you can disable .dir-locals.el
by setting enable-dir-local-variables
to nil
:
(setq enable-dir-local-variables nil)
Add the following to the top of the ~/.emacs.d/pre-early-init.el
file to make minimal-emacs.d use the MINIMAL_EMACS_USER_DIRECTORY
environment variable to change ~/.emacs.d
to another directory:
;; Place this at the very beginning of pre-early-init.el
(let ((previous-minimal-emacs-user-directory (expand-file-name
minimal-emacs-user-directory))
(env-dir (getenv "MINIMAL_EMACS_USER_DIRECTORY")))
(setq minimal-emacs-user-directory (if env-dir
(expand-file-name env-dir)
(expand-file-name user-emacs-directory)))
(unless (string= minimal-emacs-user-directory
previous-minimal-emacs-user-directory)
;; Load pre-early-init.el from the new directory
(minimal-emacs-load-user-init "pre-early-init.el")))
During the execution of early-init.el
(and pre-early-init.el
and post-early-init.el
), Emacs has not yet loaded the graphical user interface (GUI). This file is used for configurations that need to be applied before the GUI is initialized, such as settings that affect the early stages of the Emacs startup process.
Thus, post-early-init.el
and pre-init.el
serve different purposes and are not the same.
The menu bar is disabled by default in minimal-emacs.d to provide a minimal, distraction-free environment, which many experienced users prefer.
The menu bar can be re-enabled by adding the following configuration to ~/.emacs.d/pre-early-init.el
:
(setq minimal-emacs-ui-features '(menu-bar))
Other UI features can also be enabled by adding the following to ~/.emacs.d/pre-early-init.el
:
(setq minimal-emacs-ui-features '(context-menu tool-bar menu-bar dialogs tooltips))
The author began working on it after realizing that no existing starter kit offered a truly minimal setup with the flexibility for users to choose exactly what to include in their configuration.
To ensure the minimal-emacs.d configuration loads post-early-init.el
, pre-init.el
, and post-init.el
from a different directory, such as ~/.config/minimal-emacs.d/
, modify the minimal-emacs-user-directory
variable by adding the following to your ~/.emacs.d/pre-early-init.el
file:
(setq minimal-emacs-user-directory "~/.config/minimal-emacs.d/")
This will ensure that the minimal-emacs.d configuration loads post-early-init.el
, pre-init.el
, and post-init.el
from ~/.config/minimal-emacs.d/
.
Keep in mind that if you change the minimal-emacs-user-directory
, minimal-emacs.d will attempt to load the rest of the configuration from that directory (e.g., ~/.config/minimal-emacs/post-early-init.el
, ~/.config/minimal-emacs/pre-init.el
and ~/.config/minimal-emacs/post-init.el
, etc.).
To install and load packages during the early-init phase, add the following to post-early-init.el
:
(setq minimal-emacs-package-initialize-and-refresh nil)
;; If you want to ignore the warning:
;; "Warning (package): Unnecessary call to package-initialize in init file."
;; Uncomment the following setq:
;; (setq warning-suppress-types '((package)))
;; Initialize packages in the early-init phase instead of init
(progn
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(eval-when-compile
(require 'use-package)))
;; TODO: Add your use-package code here
A drawback of using the early-init phase instead of init is that if a package fails (e.g, due to a network issue), no output will be displayed in the Emacs GUI. You will need to open a terminal to view Emacs's stdout for error messages.
- JamesBrickley (Shout out to this starter-kit: Minimal-Emacs ) appreciates that minimal-emacs.d provides an optimized early-init.el and init.el for fast startup times and sensible default settings. He highlights that the project includes all the essential configurations needed for a well-tuned Emacs setup, eliminating the need to sift through conflicting advice on topics like garbage collection optimization. While he has encountered similar settings before, he also discovered new optimizations he had not seen elsewhere.
- Leading_Ad6415 commented on Reddit that after switching to minimal-emacs.d, their configuration execution time decreased from 3 seconds to just 1 second by simply replacing their
init.el
andearly-init.el
files with those from the project. - Another user commented on Reddit, highlighting how a minimal-emacs.d significantly enhanced their Emacs performance. They reported substantial startup time reductions on both their main machine (from ~2.25 to ~0.95 seconds) and an older laptop (from ~2.95 to ~1.27 seconds) while also experiencing a generally snappier performance within Emacs. The user expressed gratitude for the project, calling it fantastic.
- Cyneox commented on Reddit, expressing gratitude for the resource and sharing their experience. They mentioned it was their fourth attempt to set up a vanilla configuration and highlighted that they had been using the repository as a foundation for their customizations over the past few days. They appreciated the absence of unexplained behavior and the clear instructions on where to place files. The user reported successful testing on both Linux and macOS, noting that everything functioned smoothly, including in the terminal.
- rrajath has been using the minimal-emacs.d config for the past several months and loves it. His previous setup used to take around 4 seconds to load, but with minimal-emacs.d, it now loads in just 1 second.
- LionyxML considers that minimal-emacs.d contains one of the best README files he has ever read. The author of minimal-emacs.d found his comment encouraging. Reading this README.md is highly recommended for anyone looking to start customizing their minimal-emacs.d configuration.
- cyneox: "Still using it and loving it! Thanks for the regular updates."
-
Performance Improvements:
- Increases the amount read from processes in a single chunk.
- Prefers loading newer compiled files.
- Reduces startup screen and message noise, including removing the "For information about GNU Emacs..." message.
- Configures Emacs to start with a scratch buffer in
fundamental-mode
to shave seconds off startup time. - Delays garbage collection during startup to improve performance and resets it to a more reasonable value once Emacs has started.
- Customizes
file-name-handler-alist
for improved startup time and package load time (Special thanks to the Doom Emacs developers for thefile-name-handler-alist
optimizations; This function have been inspired by their project and will contribute to improving vanilla Emacs configurations.) - Reduces rendering workload by not rendering cursors or regions in non-focused windows.
- Disables warnings from the legacy advice API and suppresses warnings about aliased variables.
- Avoids unnecessary excessive UI updates.
- Disables font compacting to avoid high memory usage.
- Defer tool bar setup
- Unset command line options irrelevant to the current OS
-
Native Compilation and Byte Compilation:
- Configures native compilation and byte compilation settings
- Suppresses compiler warnings and errors during native compilation.
-
UI Element Management:
- Disables the startup screen and messages, including menu bar, tool bar, and scroll bars.
- Configures Emacs to avoid resizing frames and minimizes unnecessary UI updates.
-
Package Management:
- Configures package archives and priorities for MELPA, ELPA, and other repositories.
-
Customizable Initialization Files:
- Supports additional configuration files (
pre-init.el
,post-init.el
,pre-early-init.el
, andpost-early-init.el
) to allow further customization at different stages of the startup process.
- Supports additional configuration files (
-
File Management:
- Manages auto-save and backup files, including backup options and version control settings.
-
User Experience Enhancements:
- Configures user interface settings such as cursor behavior, scrolling, and response to prompts.
- Disables beeping and blinking to avoid distractions.
-
Buffer and Window Configuration:
- Sets default fringe widths and buffer boundaries.
- Configures smooth scrolling and cursor behavior for a more seamless editing experience.
-
Miscellaneous
- Verifies that the Emacs configuration has loaded successfully and issues a warning if there are any issues.
- Configure and optimize settings for Eglot, recentf, savehist, auto-save, and others without enabling the modes themselves. This modifies the behavior and preferences to improve performance and usability.
- Configure Ediff to use a single frame and split windows horizontally
The minimal-emacs.d project has been written by James Cherti and is distributed under terms of the GNU General Public License version 3, or, at your choice, any later version.
Copyright (C) 2024-2025 James Cherti
This program 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 3 of the License, or (at your option) any later version.
This program 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 this program (in the .LICENSE file).
Other Emacs packages by the same author:
- compile-angel.el: Speed up Emacs! This package guarantees that all .el files are both byte-compiled and native-compiled, which significantly speeds up Emacs.
- outline-indent.el: An Emacs package that provides a minor mode that enables code folding and outlining based on indentation levels for various indentation-based text files, such as YAML, Python, and other indented text files.
- easysession.el: Easysession is lightweight Emacs session manager that can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, the tab-bar, and the Emacs frames (with or without the Emacs frames size, width, and height).
- vim-tab-bar.el: Make the Emacs tab-bar Look Like Vim's Tab Bar.
- elispcomp: A command line tool that allows compiling Elisp code directly from the terminal or from a shell script. It facilitates the generation of optimized .elc (byte-compiled) and .eln (native-compiled) files.
- tomorrow-night-deepblue-theme.el: The Tomorrow Night Deepblue Emacs theme is a beautiful deep blue variant of the Tomorrow Night theme, which is renowned for its elegant color palette that is pleasing to the eyes. It features a deep blue background color that creates a calming atmosphere. The theme is also a great choice for those who miss the blue themes that were trendy a few years ago.
- Ultyas: A command-line tool designed to simplify the process of converting code snippets from UltiSnips to YASnippet format.
- dir-config.el: Automatically find and evaluate .dir-config.el Elisp files to configure directory-specific settings.
- flymake-bashate.el: A package that provides a Flymake backend for the bashate Bash script style checker.
- flymake-ansible-lint.el: An Emacs package that offers a Flymake backend for ansible-lint.
- inhibit-mouse.el: A package that disables mouse input in Emacs, offering a simpler and faster alternative to the disable-mouse package.
- quick-sdcv.el: This package enables Emacs to function as an offline dictionary by using the sdcv command-line tool directly within Emacs.
- enhanced-evil-paredit.el: An Emacs package that prevents parenthesis imbalance when using evil-mode with paredit. It intercepts evil-mode commands such as delete, change, and paste, blocking their execution if they would break the parenthetical structure.