Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork77
minimal-emacs.d - Better Emacs defaults and optimized startup, intended to serve as a solid foundation for your vanilla Emacs configuration
jamescherti/minimal-emacs.d
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
minimal-emacs.d - A Customizable Emacsinit.el andearly-init.el that Provides Better Defaults and Faster Startup
Theminimal-emacs.d project is a lightweight and optimized Emacs base (init.el andearly-init.el) thatgives 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 theminimal-emacs.dinit.el andearly-init.el was the result ofextensive research and testing to fine-tune the best parameters and optimizations for an Emacs configuration.(More information about theminimal-emacs.d features can be found here:Features.)
If this enhances your workflow, please show your support by⭐ starring minimal-emacs.d on GitHub to help more Emacs users discover its benefits.
Here are the instructions for installing minimal-emacs.d:Install minimal-emacs.d.
Theminimal-emacs.d project is:
- Minimal yet effective: A solid starting point.
- Better defaults: Improved settings for usability, UI, garbage collection, and built-in packages.
- 0 packages loaded / 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.
- Customizable foundation: Designed to be extended, not replaced. This README.md offers extensive recommendations for customizing yourminimal-emacs.d configuration. (Reminder:Never modify init.el and early-init.el. Modify these instead...)
Theminimal-emacs.d project includes two initialization files:
early-init.el: Loaded early in the Emacs startup process, before the graphical interface is initialized. Introduced in Emacs 27, this file configures settings that influence startup performance and GUI behavior prior to package loading.init.el: Loaded after the graphical interface is initialized. This file contains user customizations, including variable settings, package loading, mode configurations, and keybindings.
Excluding empty lines, comments, and docstrings, the minimal-emacs.d configuration is approximately 450 lines long. It does not introduce additional functionality beyond offering improved default settings. The user retains full control over which packages to install and which modes to enable.
Emacs comes with many well-designed defaults, but it also retains some less-than-ideal settings, often due to historical constraints or legacy compatibility. The purpose ofminimal-emacs.d is to offer refined defaults that improve both usability and performance, replacing long-standing Emacs settings that no longer serve modern workflows well.



The author usesminimal-emacs.d as hisearly-init.el andinit.el, alongside146 packages (See the packages that the author is using here). Yet, thanks to its efficient design, Emacs stillstarts in just 0.22 seconds:
In addition tominimal-emacs.d, startup speed is influenced by your computer's processing power and disk speed. To establish a baseline, start Emacs with onlyminimal-emacs.d and no additional configurations, then runM-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.
- gnudoc on Reddit: "That's a great learning resource. Thank you for your work on it and for sharing it!"
- dewyke on Reddit: "Lots of good stuff in there, even for people who already have established ways of organising their configs."
- JamesBrickley (Shout out to this starter-kit: Minimal-Emacs ) appreciates thatminimal-emacs.d provides an optimizedearly-init.el andinit.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.
- Brandon Schneider (skarekrow): "...the minimal-emacs project is incredible. I love how documented it is as a beginner to learn from. Thank you for all the effort you've put into that and the other packages you maintain. It's a huge boon to new users."
- Leading_Ad6415 commented on Reddit that after switching tominimal-emacs.d, their configuration execution time decreased from 3 seconds to just 1 second by simply replacing their
init.elandearly-init.elfiles 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.
- Sebagabones on GitHub: "...let me say that I am loving minimal-emacs.d, it has been brilliant so far! :)"
- Mlepnos1984 on Reddit: "I give you an A+ on documentation, the readme is great!"
- rrajath on Reddit 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 on Reddit considers thatminimal-emacs.d contains one of the best README files he has ever read. The author ofminimal-emacs.d found his comment encouraging. Reading this README.md is highly recommended for anyone looking to start customizing theirminimal-emacs.d configuration.
- cyneox on Reddit: "Still using it and loving it! Thanks for the regular updates."
- panchoh on GitHub: "...thank you, @jamescherti! Keep up the fantastic work you are doing!"
- xzway on Reddit: "The minimal-emacs.d configuration is very well-designed and non-intrusive. I'm also using it to refactor my configuration."
- jeenajeena on Reddit: "Thank you. Plenty of inspiring settings. Worth to be read line by line."
- uutangohotel on Reddit: "I get a lot out of minimal-emacs.d — thank you! I use stow to manage my dotfiles in a git repo. I created a submodule in one dir for minimal-emacs.d and another for my “overrides”, e.g. post-init.el. Easy and works great."
- sunng on Reddit: "Nice work! I just created a nix flake to using it on my dev servershttps://codeberg.org/sunng/minimal-emacs.d-nix-hm "
Please share your configuration. It could serve as inspiration for other users.
- minimal-emacs.d - A Customizable Emacs
init.elandearly-init.elthat Provides Better Defaults and Faster Startup- Introduction
- Comments from minimal-emacs.d users
- 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
- Automatic removal of trailing whitespace on save
- Enhancing undo/redo
- Configuring Vim keybindings using Evil?
- Configuring LSP Servers with Eglot (built-in)
- Persisting and Restoring all buffers, windows/split, tab-bar, frames...
- Configuring org-mode
- Configuring markdown-mode (e.g., README.md syntax)
- Tree-sitter Integration (Better Syntax Highlighting)
- Auto upgrade Emacs packages
- Safely terminating unused buffers
- Treemacs, a tree layout file explorer (Sidebar file explorer)
- Inhibit the mouse
- Spell checker
- Efficient jumps for enhanced productivity
- Asynchronous code formatting without cursor disruption
- Efficient template expansion with snippets
- A better Emacshelp buffer
- Enhancing the Elisp development experience
- Showing the tab-bar
- Changing the Default Font
- Persist Text Scale
- Loading the custom.el file
- Which other customizations can be interesting to add?
- Customizations: pre-early-init.el
- Frequently asked questions
- Customizing Scroll Recentering
- How to display Emacs startup duration?
- How to get the latest version of all packages? (unstable)
- How to use MELPA stable?
- How to load a local lisp file for machine-specific configurations?
- How to prevent Emacs from repeatedly performing native compilation on specific Elisp files
- How to load Emacs customizations?
- How to increase gc-cons-threshold?
- 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 makeminimal-emacs.d install packages in the early-init phase instead of the init phase?
- Minimal-emacs.d configurations from users
- Features
- Author and license
- Links
- Important: Ensure that the
~/.emacsand~/.emacs.elfiles 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-initto enable debug mode and obtain the backtrace. - Prerequisite: git
Execute the following command install this repository into~/.emacs.d:
git clone --depth 1 https://github.com/jamescherti/minimal-emacs.d ~/.emacs.dTo installminimal-emacs.d in a non-default directory, use the--init-directory Emacs option to specify your desired configuration path. For example, to installminimal-emacs.d in~/.minimal-emacs.d/, follow these steps:
Clone the repository into
~/.minimal-emacs.d/using:git clone --depth 1 https://github.com/jamescherti/minimal-emacs.d ~/.minimal-emacs.dStart 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 pullTheinit.el andearly-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.elbut 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 yourpre-init.el,post-init.el,post-early-init.el, andpre-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; -*-ReplaceFILENAME.el with the actual name and DESCRIPTION with a brief description of its purpose.
(Only if you know what you're doing: Removingno-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 usinguse-package, add(require 'use-package) at the top ofpost-init.el to ensure all necessaryuse-package variables and functions are loaded.)
Important: The examples in this README reference pre/post init files in the~/.emacs.d/ directory, but the filespre-early-init.el,post-early-init.el,pre-init.el, andpost-init.el should be placed in the same directory asinit.el andearly-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-errort)
Enablingdebug-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 or menu-bar 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-menutool-bar menu-bar dialogs tooltips))
These settings control the visibility of dialogs, context menus, toolbars, menu bars, and tooltips.
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/;; NOTE: This must be placed in 'pre-early-init.el'.(setq user-emacs-directory (expand-file-name"var/" minimal-emacs-user-directory))(setq package-user-dir (expand-file-name"elpa" user-emacs-directory))
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.
This README.md offers guidance on installing optional external packages. While Emacs and minimal-emacs.d are fully functional without them, the recommended packages can enhance your experience and introduce additional features, which is why they are suggested.
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 usingcompile-angel.el. To install compile-angel, add the following code to the
~/.emacs.d/post-init.elfile:
;; Native compilation enhances Emacs performance by converting Elisp code into;; native machine code, resulting in faster execution and improved;; responsiveness.;;;; 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:demandt:ensuret: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-verboset):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;; the`use-package' macro, you'll need to explicitly add:;; (eval-when-compile (require 'use-package));; at the top of your init file. (push"/init.el" compile-angel-excluded-files) (push"/early-init.el" compile-angel-excluded-files) (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 prior to loading them via`load' or;;`require'. Additionally, it compiles all packages that were loaded before;; the mode`compile-angel-on-load-mode' was activated. (compile-angel-on-load-mode1))
The recentf, savehist, saveplace, and auto-revert built-in packages are already configured byminimal-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.(use-package autorevert:ensurenil:commands (auto-revert-mode global-auto-revert-mode):hook (after-init. global-auto-revert-mode):custom (auto-revert-interval3) (auto-revert-remote-filesnil) (auto-revert-use-notifyt) (auto-revert-avoid-pollingnil) (auto-revert-verboset));; Recentf is an Emacs package that maintains a list of recently;; accessed files, making it easier to reopen files you have worked on;; recently.(use-package recentf:ensurenil:commands (recentf-mode recentf-cleanup):hook (after-init. recentf-mode):custom (recentf-auto-cleanup (if (daemonp)300'never)) (recentf-exclude (list"\\.tar$""\\.tbz2$""\\.tbz$""\\.tgz$""\\.bz2$""\\.bz$""\\.gz$""\\.gzip$""\\.xz$""\\.zip$""\\.7z$""\\.rar$""COMMIT_EDITMSG\\'""\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$""-autoloads\\.el$""autoload\\.el$")):config;; A cleanup depth of -90 ensures that`recentf-cleanup' runs before;;`recentf-save-list', allowing stale entries to be removed before the list;; is saved by`recentf-save-list', which is automatically added to;;`kill-emacs-hook' by`recentf-mode'. (add-hook'kill-emacs-hook#'recentf-cleanup-90));; 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.(use-package savehist:ensurenil:commands (savehist-mode savehist-save):hook (after-init. savehist-mode):custom (savehist-autosave-interval600) (savehist-additional-variables '(kill-ring; clipboard register-alist; macros mark-ring global-mark-ring; marks search-ring regexp-search-ring)));; 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.(use-package saveplace:ensurenil:commands (save-place-mode save-place-local-mode):hook (after-init. save-place-mode):custom (save-place-limit400))
Enablingauto-save-mode mitigates the risk of data loss in the event of a crash. Auto-saved data can be recovered using therecover-file orrecover-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-defaultt)(setq auto-save-interval300)(setq auto-save-timeout30)
Whenauto-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 withsave-buffer orC-x s for example.
This is different fromauto-save-mode:auto-save-mode periodically saves all modified buffers, creating backup files, including those not associated with a file, whileauto-save-visited-mode only saves file-visiting buffers after a period of idle time, directly saving to the file itself without creating backup files.
;; 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-interval5); Save after 5 seconds if inactivity(auto-save-visited-mode1)
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 configurecorfu andcape, add the following to~/.emacs.d/post-init.el:
;; 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.(use-package corfu:ensuret: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-completionnil) (tab-always-indent'complete);; Enable Corfu:config (global-corfu-mode));; 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.(use-package cape:ensuret: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, andEmbark 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., whenM-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:
;; Vertico provides a vertical completion interface, making it easier to;; navigate and select from completion candidates (e.g., when `M-x` is pressed).(use-package vertico;; (Note: It is recommended to also enable the savehist package.):ensuret:config (vertico-mode));; 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.(use-package orderless:ensuret:custom (completion-styles '(orderless basic)) (completion-category-defaultsnil) (completion-category-overrides '((file (styles partial-completion)))));; 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.(use-package marginalia:ensuret:commands (marginalia-mode marginalia-cycle):hook (after-init. marginalia-mode));; Embark integrates with Consult and Vertico 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.(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.:ensuret: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:ensuret:hook (embark-collect-mode. consult-preview-at-point-mode));; Consult offers a suite of commands for efficient searching, previewing, and;; interacting with buffers, file contents, and more, improving various tasks.(use-package consult:ensuret: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-delay0.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);; Aggressive asynchronous that yield instantaneous results. (suitable for;; high-performance systems.) Note: Minad, the author of Consult, does not;; recommend aggressive values.;; Read: https://github.com/minad/consult/discussions/951;;;; However, the author of minimal-emacs.d uses these parameters to achieve;; immediate feedback from Consult.;; (setq consult-async-input-debounce 0.02;; consult-async-input-throttle 0.05;; consult-async-refresh-delay 0.02):config (consult-customize consult-theme:preview-key '(:debounce0.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 '(:debounce0.4 any)) (setq consult-narrow-key"<"))
The built-inoutline-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 enableoutline-minor-mode in Emacs Lisp:
;; 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.(use-package outline:ensurenil:commands outline-minor-mode:hook ((emacs-lisp-mode. outline-minor-mode);; Use " ▼" instead of the default ellipsis "..." for folded text to make;; folds more visually distinctive and readable. (outline-minor-mode. (lambda() (let* ((display-table (or buffer-display-table (make-display-table))) (face-offset (* (face-id'shadow) (ash122))) (value (vconcat (mapcar (lambda (c) (+ face-offset c))" ▼")))) (set-display-table-slot display-table'selective-display value) (setq buffer-display-table display-table))))))
For folding based on indentation levels, theoutline-indent Emacs package provides a minor mode that enables folding according to the indentation structure:
;; The outline-indent Emacs package provides a minor mode that enables code;; folding based on indentation levels.;;;; In addition to code folding, *outline-indent* 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 other features.(use-package outline-indent:ensuret: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))
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-operandit); Load the built-in theme
(If you prefer dark themes, replacemodus-operandi withmodus-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-operandimodus-operandi-deuteranopiamodus-operandi-tintedmodus-operandi-tritanopiamodus-vivendimodus-vivendi-deuteranopiamodus-vivendi-tintedmodus-vivendi-tritanopiatsdh-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, useM-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 minimalistmodus-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.)
Trailing whitespace refers to any spaces or tabs that appear after the last non-whitespace character on a line. These characters have no semantic value and can lead to unnecessary diffs in version control, inconsistent formatting, or visual clutter. Removing them improves code clarity and consistency.
Thestripspace Emacs package providesstripspace-local-mode, a minor mode that automatically removes trailing whitespace and blank lines at the end of the buffer when saving.
To enablestripspace and automatically delete trailing whitespace, add the following configuration to~/.emacs.d/post-init.el:
;; The stripspace Emacs package provides stripspace-local-mode, a minor mode;; that automatically removes trailing whitespace and blank lines at the end of;; the buffer when saving.(use-package stripspace:ensuret:commands stripspace-local-mode;; Enable for prog-mode-hook, text-mode-hook, conf-mode-hook:hook ((prog-mode. stripspace-local-mode) (text-mode. stripspace-local-mode) (conf-mode. stripspace-local-mode)):custom;; The`stripspace-only-if-initially-clean' option:;; - nil to always delete trailing whitespace.;; - Non-nil to only delete whitespace when the buffer is clean initially.;; (The initial cleanliness check is performed when`stripspace-local-mode';; is enabled.) (stripspace-only-if-initially-cleannil);; Enabling`stripspace-restore-column' preserves the cursor's column position;; even after stripping spaces. This is useful in scenarios where you add;; extra spaces and then save the file. Although the spaces are removed in the;; saved file, the cursor remains in the same position, ensuring a consistent;; editing experience without affecting cursor placement. (stripspace-restore-columnt))
Theundo-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. Theundo-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:ensuret: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:ensuret: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 upEvil mode:
;; Uncomment the following if you are using undo-fu;; (setq evil-undo-system 'undo-fu);; Vim emulation(use-package evil:ensuret:commands (evil-mode evil-define-key):hook (after-init. evil-mode):init;; It has to be defined before evil (setq evil-want-integrationt) (setq evil-want-keybindingnil):custom;; Make :s in visual mode operate only on the actual visual selection;; (character or block), instead of the full lines covered by the selection (evil-ex-visual-char-ranget);; Use Vim-style regular expressions in search and substitute commands,;; allowing features like \v (very magic), \zs, and \ze for precise matches (evil-ex-search-vim-style-regexpt);; Enable automatic horizontal split below (evil-split-window-belowt);; Enable automatic vertical split to the right (evil-vsplit-window-rightt);; Disable echoing Evil state to avoid replacing eldoc (evil-echo-statenil);; Do not move cursor back when exiting insert state (evil-move-cursor-backnil);; Make `v$` exclude the final newline (evil-v$-excludes-newlinet);; Allow C-h to delete in insert state (evil-want-C-h-deletet);; Enable C-u to delete back to indentation in insert state (evil-want-C-u-deletet);; Enable fine-grained undo behavior (evil-want-fine-undot);; Allow moving cursor beyond end-of-line in visual block mode (evil-move-beyond-eolt);; Disable wrapping of search around buffer (evil-search-wrapnil);; Whether Y yanks to the end of the line (evil-want-Y-yank-to-eolt))(use-package evil-collection:after evil:ensuret:init;; It has to be defined before evil-colllection (setq evil-collection-setup-minibuffert):config (evil-collection-init))
You can also install thevim-tab-bar package to enhance the built-in Emacs tab-bar with a minimalist, Vim-inspired design that automatically adapts to the active Emacs theme. Beyond its Vim-inspired design, thevim-tab-bar package is valued by users who prioritize theme consistency, as it integrates the Emacs tab-bar with any Emacs theme, producing a visually coherent and polished interface:
;; Give Emacs tab-bar a style similar to Vim's(use-package vim-tab-bar:ensuret:commands vim-tab-bar-mode:hook (after-init. vim-tab-bar-mode))
(The screenshot above showcases how vim-tab-bar modifies the built-in Emacs tab-bar.)
Theevil-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 usingS" orgS":
;; 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:ensuret: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 pressinggcc in normal mode andgc in visual mode (thanks you to the Reddit user u/mistakenuser for this contribution, which replaces the evil-commentary package):
;; The following code enables commenting and uncommenting by pressing gcc in;; normal mode and gc in visual mode.(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, add the following to~/.emacs.d/post-init.el:
;; Set up the Language Server Protocol (LSP) servers using Eglot.(use-package eglot:ensurenil:commands (eglot-ensure eglot-rename eglot-format-buffer))
Here is an example of how to configure Eglot to enable or disable certain options for thepylsp server in Python development. (Note that a third-party tool,python-lsp-server, must be installed):
;; Configure Eglot to enable or disable certain options for the pylsp server;; in Python development. (Note that a third-party tool,;; https://github.com/python-lsp/python-lsp-server, must be installed),(add-hook'python-mode-hook#'eglot-ensure)(add-hook'python-ts-mode-hook#'eglot-ensure)(setq-default eglot-workspace-configuration `(:pylsp (:plugins (;; Fix imports and syntax using `eglot-format-buffer`:isort (:enabledt):autopep8 (:enabledt);; Syntax checkers (works with Flymake):pylint (:enabledt):pycodestyle (:enabledt):flake8 (:enabledt):pyflakes (:enabledt):pydocstyle (:enabledt):mccabe (:enabledt):yapf (:enabled:json-false):rope_autoimport (:enabled:json-false)))))
Theeasysession 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 configureeasysession, add the following to~/.emacs.d/post-init.el:
;; The easysession 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.(use-package easysession:ensuret:commands (easysession-switch-to easysession-save-as easysession-save-mode easysession-load-including-geometry):custom (easysession-mode-line-misc-infot); Display the session in the modeline (easysession-save-interval (*1060)); 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-geometry102) (add-hook'emacs-startup-hook#'easysession-save-mode103))
Org mode is a major mode designed for organizing notes, planning, task management, and authoring documents using plain text with a simple and expressive markup syntax. It supports hierarchical outlines, TODO lists, scheduling, deadlines, time tracking, and exporting to multiple formats including HTML, LaTeX, PDF, and Markdown.
To configureorg-mode, add the following to~/.emacs.d/post-init.el:
;; Org mode is a major mode designed for organizing notes, planning, task;; management, and authoring documents using plain text with a simple and;; expressive markup syntax. It supports hierarchical outlines, TODO lists,;; scheduling, deadlines, time tracking, and exporting to multiple formats;; including HTML, LaTeX, PDF, and Markdown.(use-packageorg:ensuret:commands (org-mode org-version):mode ("\\.org\\'". org-mode):custom (org-hide-leading-starst) (org-startup-indentedt) (org-adapt-indentationnil) (org-edit-src-content-indentation0);; (org-fontify-done-headline t);; (org-fontify-todo-headline t);; (org-fontify-whole-heading-line t);; (org-fontify-quote-and-verse-blocks t) (org-startup-truncatedt))
Themarkdown-mode package provides a major mode for Emacs for syntax highlighting, editing commands, and preview support for Markdown documents. It supports core Markdown syntax as well as extensions like GitHub Flavored Markdown (GFM).
To configuremarkdown-mode, add the following to~/.emacs.d/post-init.el:
;; The markdown-mode package provides a major mode for Emacs for syntax;; highlighting, editing commands, and preview support for Markdown documents.;; It supports core Markdown syntax as well as extensions like GitHub Flavored;; Markdown (GFM).(use-package markdown-mode:commands (gfm-mode gfm-view-mode markdown-mode markdown-view-mode):mode (("\\.markdown\\'". markdown-mode) ("\\.md\\'". markdown-mode) ("README\\.md\\'". gfm-mode)):bind (:map markdown-mode-map ("C-c C-e". markdown-do)))
This configuration sets upmarkdown-mode with deferred loading to improve startup performance. The:commands and:mode keywords ensure that the mode is loaded only when needed—for example, when opening.md,.markdown, orREADME.md files. Files namedREADME.md are specifically associated withgfm-mode, which is for GitHub Flavored Markdown syntax. Themarkdown-command variable is set to"multimarkdown" to specify the Markdown processor used for previews and exports. Additionally, a keybinding (C-c C-e) is defined inmarkdown-mode-map to invokemarkdown-do, which can be customized to perform common Markdown-related actions.
Table of contents: To generate a table of contents when editing Markdown files, add the following to your~/.emacs.d/post-init.el:
;; Automatically generate a table of contents when editing Markdown files(use-package markdown-toc:ensuret:commands (markdown-toc-generate-toc markdown-toc-generate-or-refresh-toc markdown-toc-delete-toc markdown-toc--toc-already-present-p):custom (markdown-toc-header-toc-title"**Table of Contents**"))
Once installed:
- Toinsert a table of contents for the first time, run:
M-x markdown-toc-generate-toc - Toupdate an existing table of contents, run:
M-x markdown-toc-generate-or-refresh-toc - Toremove an existing table of contents, run:
M-x markdown-toc-delete-toc
These commands work on any Markdown buffer and rely on properly formatted headers (e.g.,#,##) to build the table of contents.
The author also recommends reading the following article:Emacs: Automating Table of Contents Update for Markdown Documents (e.g., README.md).
Tree-sitter is an incremental parsing system introduced in Emacs 29 that provides precise, high-performance syntax analysis and highlighting by constructing concrete syntax trees from source code. It supports a broad set of programming languages, including Bash, C, C++, C#, CMake, CSS, Dockerfile, Go, Java, JavaScript, JSON, Python, Rust, TOML, TypeScript, YAML, Elisp, Lua, Markdown, and many others. Unlike traditional font-lock, which relies on regular expressions, Tree-sitter uses formal grammar definitions to build real-time parse trees, enabling accurate syntax highlighting, structural navigation, code folding, and foundational support for advanced editing features like refactoring.
The configuration below enables Tree-sitter support using thetreesit-auto package. Settingtreesit-auto-add-to-auto-mode-alist to'all ensures that all available Tree-sitter modes are automatically activated for their corresponding file types. Enablingglobal-treesit-auto-mode applies this behavior globally, improving syntax accuracy and consistency across supported languages.
To enable Tree-sitter, add the following to your~/.emacs.d/post-init.el:
;; Tree-sitter in Emacs is an incremental parsing system introduced in Emacs 29;; that provides precise, high-performance syntax highlighting. It supports a;; broad set of programming languages, including Bash, C, C++, C#, CMake, CSS,;; Dockerfile, Go, Java, JavaScript, JSON, Python, Rust, TOML, TypeScript, YAML,;; Elisp, Lua, Markdown, and many others.(use-package treesit-auto:ensuret:custom (treesit-auto-install'prompt):config (treesit-auto-add-to-auto-mode-alist'all) (global-treesit-auto-mode))
Theauto-package-update automates the process of updating installed packages managed bypackage.el. Instead of requiring users to manually invokepackage-list-packages and update each package,auto-package-update can check for available updates at regular intervals, perform updates in the background, and optionally hide the results buffer or prompt before applying changes.
To configureauto-package-update, add the following to~/.emacs.d/post-init.el:
;; This automates the process of updating installed packages(use-package auto-package-update:ensuret:custom;; Set the number of days between automatic updates.;; Here, packages will only be updated if at least 7 days have passed;; since the last successful update. (auto-package-update-interval7);; Suppress display of the *auto-package-update results* buffer after updates.;; This keeps the user interface clean and avoids unnecessary interruptions. (auto-package-update-hide-resultst);; Automatically delete old package versions after updates to reduce disk;; usage and keep the package directory clean. This prevents the accumulation;; of outdated files in Emacs’s package directory, which consume;; unnecessary disk space over time. (auto-package-update-delete-old-versionst);; Uncomment the following line to enable a confirmation prompt;; before applying updates. This can be useful if you want manual control.;; (auto-package-update-prompt-before-update t):config;; Run package updates automatically at startup, but only if the configured;; interval has elapsed. (auto-package-update-maybe);; Schedule a background update attempt daily at 10:00 AM.;; This uses Emacs' internal timer system. If Emacs is running at that time,;; the update will be triggered. Otherwise, the update is skipped for that;; day. Note that this scheduled update is independent of;; `auto-package-update-maybe` and can be used as a complementary or;; alternative mechanism. (auto-package-update-at-time"10:00"))
Thebuffer-terminator Emacs packageautomatically and safely kills buffers, ensuring a clean and efficient workspace whileenhancing the performance of Emacs by reducing open buffers, which minimizes active modes, timers, processes...
Beyond performance,buffer-terminator provides other benefits. For instance, if you occasionally need to close annoying or unused buffers,buffer-terminator can handle this automatically, eliminating the need for manual intervention. (The default configuration is suitable for most users. However, thebuffer-terminator package is highly customizable. You can define specific rules for retaining or terminating buffers by modifying thebuffer-terminator-rules-alist with your preferred set of rules.)
To configurebuffer-terminator, add the following to~/.emacs.d/post-init.el:
(use-package buffer-terminator:ensuret:custom;; Enable/Disable verbose mode to log buffer cleanup events (buffer-terminator-verbosenil);; Set the inactivity timeout (in seconds) after which buffers are considered;; inactive (default is 30 minutes): (buffer-terminator-inactivity-timeout (*3060)); 30 minutes;; Define how frequently the cleanup process should run (default is every 10;; minutes): (buffer-terminator-interval (*1060)); 10 minutes:config (buffer-terminator-mode1))
(By default,buffer-terminator automatically determines which buffers are safe to terminate. However, if you need to define specific rules for keeping or terminating certain buffers, you can configure them usingbuffer-terminator-rules-alist.)
Thetreemacs package is a file and project explorer for Emacs that provides a visually structured tree layout similar to file browsers in modern IDEs. It integrates well with various Emacs packages such asprojectile,lsp-mode, andmagit, allowing users to navigate their project structure efficiently.
To configuretreemacs, add the following to~/.emacs.d/post-init.el:
;; A file and project explorer for Emacs that displays a structured tree;; layout, similar to file browsers in modern IDEs. It functions as a sidebar;; in the left window, providing a persistent view of files, projects, and;; other elements.(use-package treemacs:ensuret:commands (treemacs treemacs-select-window treemacs-delete-other-windows treemacs-select-directory treemacs-bookmark treemacs-find-file treemacs-find-tag):bind (:map global-map ("M-0". treemacs-select-window) ("C-x t 1". treemacs-delete-other-windows) ("C-x t t". treemacs) ("C-x t d". treemacs-select-directory) ("C-x t B". treemacs-bookmark) ("C-x t C-t". treemacs-find-file) ("C-x t M-t". treemacs-find-tag)):init (with-eval-after-load'winum (define-key winum-keymap (kbd"M-0")#'treemacs-select-window)):config (setq treemacs-collapse-dirs (if treemacs-python-executable30) treemacs-deferred-git-apply-delay0.5 treemacs-directory-name-transformer#'identity treemacs-display-in-side-windowt treemacs-eldoc-display'simple treemacs-file-event-delay2000 treemacs-file-extension-regex treemacs-last-period-regex-value treemacs-file-follow-delay0.2 treemacs-file-name-transformer#'identity treemacs-follow-after-initt treemacs-expand-after-initt treemacs-find-workspace-method'find-for-file-or-pick-first treemacs-git-command-pipe"" treemacs-goto-tag-strategy'refetch-index treemacs-header-scroll-indicators '(nil."^^^^^^") treemacs-hide-dot-git-directoryt treemacs-indentation2 treemacs-indentation-string"" treemacs-is-never-other-windownil treemacs-max-git-entries5000 treemacs-missing-project-action'ask treemacs-move-files-by-mouse-draggingt treemacs-move-forward-on-expandnil treemacs-no-png-imagesnil treemacs-no-delete-other-windowst treemacs-project-follow-cleanupnil treemacs-persist-file (expand-file-name".cache/treemacs-persist" user-emacs-directory) treemacs-position'left treemacs-read-string-input'from-child-frame treemacs-recenter-distance0.1 treemacs-recenter-after-file-follownil treemacs-recenter-after-tag-follownil treemacs-recenter-after-project-jump'always treemacs-recenter-after-project-expand'on-distance treemacs-litter-directories '("/node_modules""/.venv""/.cask") treemacs-project-follow-into-homenil treemacs-show-cursornil treemacs-show-hidden-filest treemacs-silent-filewatchnil treemacs-silent-refreshnil treemacs-sorting'alphabetic-asc treemacs-select-when-already-in-treemacs'move-back treemacs-space-between-root-nodest treemacs-tag-follow-cleanupt treemacs-tag-follow-delay1.5 treemacs-text-scalenil treemacs-user-mode-line-formatnil treemacs-user-header-line-formatnil treemacs-wide-toggle-width70 treemacs-width35 treemacs-width-increment1 treemacs-width-is-initially-lockedt treemacs-workspace-switch-cleanupnil);; The default width and height of the icons is 22 pixels. If you are;; using a Hi-DPI display, uncomment this to double the icon size.;; (treemacs-resize-icons 44) (treemacs-follow-modet) (treemacs-filewatch-modet) (treemacs-fringe-indicator-mode'always);;(when treemacs-python-executable;; (treemacs-git-commit-diff-mode t)) (pcase (cons (not (null (executable-find"git"))) (not (null treemacs-python-executable))) (`(t.t) (treemacs-git-mode'deferred)) (`(t. _) (treemacs-git-mode'simple))) (treemacs-hide-gitignored-files-modenil));; (use-package treemacs-evil;; :after (treemacs evil);; :ensure t);;;; (use-package treemacs-icons-dired;; :hook (dired-mode . treemacs-icons-dired-enable-once);; :ensure t);;;; (use-package treemacs-tab-bar ; treemacs-tab-bar if you use tab-bar-mode;; :after (treemacs);; :ensure t;; :config (treemacs-set-scope-type 'Tabs));;;; (treemacs-start-on-boot)
Theinhibit-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 configureinhibit-mouse, add the following to~/.emacs.d/post-init.el:
;; 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.(use-package inhibit-mouse:ensuret:config (if (daemonp) (add-hook'server-after-make-frame-hook#'inhibit-mouse-mode) (inhibit-mouse-mode1)))
NOTE:inhibit-mouse-mode allows users to disable and re-enable mouse functionality, giving them the flexibility to use the mouse when needed.
Theflyspell 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 likeaspell,hunspell, orispell to provide suggestions and corrections.
NOTE:flyspell-mode can become slow when using Aspell, especially with large buffers or aggressive suggestion settings like--sug-mode=ultra. This slowdown occurs because Flyspell checks words dynamically as you type or navigate text, requiring frequent communication between Emacs and the external Aspell process. Each check involves sending words to Aspell and receiving results, which introduces overhead from process invocation and inter-process communication.
To configureflyspell, add the following to~/.emacs.d/post-init.el:
;; 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.;;;; NOTE: flyspell-mode can become slow when using Aspell, especially with large;; buffers or aggressive suggestion settings like --sug-mode=ultra. This;; slowdown occurs because Flyspell checks words dynamically as you type or;; navigate text, requiring frequent communication between Emacs and the;; external Aspell process. Each check involves sending words to Aspell and;; receiving results, which introduces overhead from process invocation and;; inter-process communication.(use-package ispell:ensurenil:commands (ispell ispell-minor-mode):custom;; Set the ispell program name to aspell (ispell-program-name"aspell");; Define the "en_US" spell-check dictionary locally, telling Emacs to use;; UTF-8 encoding, match words using alphabetic characters, allow apostrophes;; inside words, treat non-alphabetic characters as word boundaries, and pass;; -d en_US to the underlying spell-check program. (ispell-local-dictionary-alist '(("en_US""[[:alpha:]]""[^[:alpha:]]""[']"nil ("-d""en_US")nil utf-8)));; 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")));; 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.(use-package flyspell:ensurenil: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-mode1) (flyspell-mode1))))):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)))
Theavy package is a navigation framework designed for jumping directly to any visible text on the screen with minimal keystrokes. The primary benefit ofavy is a substantial increase in navigational efficiency, as it minimizes keystrokes compared to iterative methods like arrow keys or standard search.
It operates by generating a dynamic, temporary mapping: upon invocation, such as with the commandavy-goto-char oravy-goto-char-2, the user inputs a target character, andavy highlights all visible instances on the screen with unique key sequences. Typing the short sequence corresponding to the desired location instantly moves the point directly there.
To configureavy, add the following to~/.emacs.d/post-init.el:
(use-package avy:ensuret:commands (avy-goto-char avy-goto-char-2 avy-next):init (global-set-key (kbd"C-'")'avy-goto-char-2))
The author recommends usingavy-goto-char-2 (typically bound toC-'). Upon invocation,avy prompts the user to input a two-character sequence. Subsequently, all visible instances of this sequence are highlighted with unique, concise labels (e.g., single letters or numbers). The user then simply presses the key corresponding to the desired label, andavy instantly transports the cursor to that specific occurrence.
Apheleia is an Emacs package designed to run code formatters asynchronously without disrupting the cursor position. Code formatters like Shfmt, Black and Prettier ensure consistency and improve collaboration by automating formatting, but running them on save can introduce latency (e.g., Black takes around 200ms on an empty file) and unpredictably move the cursor when modifying nearby text.
Apheleia solves both problems across all languages, replacing language-specific packages like Blacken and prettier-js. It does this by invoking formatters in anafter-save-hook, ensuring changes are applied only if the buffer remains unmodified.
To maintain cursor stability, Apheleia generates an RCS patch, applies it selectively, and employs a dynamic programming algorithm to reposition the cursor if necessary. If the formatting alters the vertical position of the cursor in the window, Apheleia adjusts the scroll position to preserve visual continuity across all displayed instances of the buffer. This allows enjoying automated code formatting without sacrificing editor responsiveness or usability.
To configureapheleia, add the following to~/.emacs.d/post-init.el:
;; Apheleia is an Emacs package designed to run code formatters (e.g., Shfmt,;; Black and Prettier) asynchronously without disrupting the cursor position.(use-package apheleia:ensuret:commands (apheleia-mode apheleia-global-mode):hook ((prog-mode. apheleia-mode)))
Theyasnippet package provides a template system that enhances text editing by enabling users to define and use snippets, which are predefined templates of code or text. The user triggers snippet expansion by pressing the Tab key after typing an abbreviation, such asif. Upon pressing Tab, YASnippet replaces the abbreviation with the corresponding full template, allowing the user to fill in placeholders or fields within the expanded snippet.
Theyasnippet-snippets package with a comprehensive collection of bundled templates for numerous programming and markup languages, including C, C++, C#, Perl, Python, Ruby, SQL, LaTeX, HTML, CSS...
(NOTE: Users of UltiSnips, a popular snippet engine for Vim, can export their snippets to YASnippet format using the toolultyas)
;; The official collection of snippets for yasnippet.(use-package yasnippet-snippets:ensuret:after yasnippet);; YASnippet is a template system designed that enhances text editing by;; enabling users to define and use snippets. When a user types a short;; abbreviation, YASnippet automatically expands it into a full template, which;; can include placeholders, fields, and dynamic content.(use-package yasnippet:ensuret:commands (yas-minor-mode yas-global-mode):hook (after-init. yas-global-mode):custom (yas-also-auto-indent-first-linet); Indent first line of snippet (yas-also-indent-empty-linest) (yas-snippet-revivalnil); Setting this to t causes issues with undo (yas-wrap-around-regionnil); Do not wrap region when expanding snippets;; (yas-triggers-in-field nil) ; Disable nested snippet expansion;; (yas-indent-line 'fixed) ; Do not auto-indent snippet content;; (yas-prompt-functions '(yas-no-prompt)) ; No prompt for snippet choices:init;; Suppress verbose messages (setq yas-verbosity0))
Helpful is an alternative to the built-in Emacs help that provides much more contextual information.
To configurehelpful, add the following to~/.emacs.d/post-init.el:
;; Helpful is an alternative to the built-in Emacs help that provides much more;; contextual information.(use-package helpful:ensuret: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-buffers7))
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:ensuret:commands aggressive-indent-mode:hook (emacs-lisp-mode. aggressive-indent-mode));; Highlights function and variable definitions in Emacs Lisp mode(use-package highlight-defined:ensuret: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:ensuret: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;; :commands enhanced-evil-paredit-mode;; :hook;; (paredit-mode . enhanced-evil-paredit-mode));; Displays visible indicators for page breaks(use-package page-break-lines:ensuret: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:ensuret:commands (elisp-refs-function elisp-refs-macro elisp-refs-variable elisp-refs-special elisp-refs-symbol))
Configure thetab-bar-show variable to 1 to display the tab bar exclusively when multiple tabs are open:
;; Configure the `tab-bar-show` variable to 1 to display the tab bar exclusively;; when multiple tabs are open:(setopt tab-bar-show1)
To customize the default font, add the following expression to your~/.emacs.d/post-init.el:
;; Set the default font to DejaVu Sans Mono with specific size and weight(set-face-attribute'defaultnil:height130:weight'normal:family"DejaVu Sans Mono")
- Modify the
':weight' value to control the font thickness/boldness. It must be one of the following symbols:'ultra-heavy,'heavy(a.k.a.'black),'ultra-bold(a.k.a.'extra-bold),'bold,'semi-bold(a.k.a.'demi-bold),'medium,'normal(a.k.a.'regular, a.k.a.'book),'semi-light(a.k.a.'demi-light),'light,'extra-light(a.k.a.'ultra-light), or'thin. - Modify the :height value to set the font size, where 100 corresponds to 10 pt, 130 to 13 pt, and so on.
- Modify the
:familyvalue to specify a different font, according to your preference. You can replace it with, for example, "Iosevka Term", "Inconsolata", "JetBrains Mono", "Source Code Pro", or "Hack". (The authors preferred font family is "Iosevka Term", medium weight.)
On Linux, you can display a comprehensive list of all installed font families by executing the following command:
fc-list : family | sed 's/,/\n/g' | sort -uThepersist-text-scale Emacs package providespersist-text-scale-mode, which ensures that all adjustments made withtext-scale-increase andtext-scale-decrease are persisted and restored across sessions. As a result, the text size in each buffer remains consistent, even after restarting Emacs.
This package also facilitates grouping buffers into categories, allowing buffers within the same category to share a consistent text scale. This ensures uniform font sizes when adjusting text scaling. By default:
- Each file-visiting buffer has its own independent text scale.
- Special buffers, identified by their buffer names, each retain their own text scale setting.
- All Dired buffers maintain the same font size, treating Dired as a unified "file explorer" where the text scale remains consistent across different buffers.
This category-based behavior can be further customized by assigning a function to thepersist-text-scale-buffer-category-function variable. The function determines how buffers are categorized by returning a category identifier (string) based on the buffer's context. Buffers within the same category will share the same text scale.
To configure thepersist-text-scale package, add the following to your~/.emacs.d/post-init.el:
(use-package persist-text-scale:commands (persist-text-scale-mode persist-text-scale-restore):hook (after-init. persist-text-scale-mode):custom (text-scale-mode-step1.07))
NOTE: The author advises against loadingcustom.el. Users are instead encouraged to define their configuration programmatically in files such aspost-init.el. Maintaining configuration programmatically offers several advantages: it ensures reproducibility and facilitates version control. This makes it easier to understand, audit, and evolve the configuration over time.
In Emacs, customization variables modified via the UI (e.g.,M-x customize) are typically stored in a separate file, commonly namedcustom.el. To ensure these settings are loaded during Emacs initialization, it is necessary to explicitly load this file if it exists. To accomplish this, add the following form to your~/.emacs.d/post-init.el:
;; In Emacs, customization variables modified via the UI (e.g., M-x customize);; are typically stored in a separate file, commonly named 'custom.el'. To;; ensure these settings are loaded during Emacs initialization, it is necessary;; to explicitly load this file if it exists.(load custom-file'noerror'no-message)
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-int);; When Delete Selection mode is enabled, typed text replaces the selection;; if the selection is active.(delete-selection-mode1);; Display the current line and column numbers in the mode line(setq line-number-modet)(setq column-number-modet)(setq mode-line-position-column-line-format '("%l:%C"));; Display of line numbers in the buffer:(setq-default display-line-numbers-type'relative)(dolist (hook '(prog-mode-hook text-mode-hook conf-mode-hook)) (add-hook hook#'display-line-numbers-mode));; Set the maximum level of syntax highlighting for Tree-sitter modes(setq treesit-font-lock-level4)(use-package which-key:ensurenil; builtin:commands which-key-mode:hook (after-init. which-key-mode):custom (which-key-idle-delay1.5) (which-key-idle-secondary-delay0.25) (which-key-add-column-padding1) (which-key-max-description-length40))(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-momentumnil); Precise/smoother scrolling (pixel-scroll-precision-mode1));; 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)(use-package uniquify:ensurenil:custom (uniquify-buffer-name-style'reverse) (uniquify-separator"•") (uniquify-after-kill-buffer-pt));; 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);; Constrain vertical cursor movement to lines within the buffer(setq dired-movement-style'bounded-files);; 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);; dired: Group directories first(with-eval-after-load'dired (let ((args"--group-directories-first -ahlv")) (when (or (eq system-type'darwin) (eq system-type'berkeley-unix)) (if-let* ((gls (executable-find"gls"))) (setq insert-directory-program gls) (setq argsnil))) (when args (setq dired-listing-switches args))));; Enables visual indication of minibuffer recursion depth after initialization.(add-hook'after-init-hook#'minibuffer-depth-indicate-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-filest)(setq vc-make-backup-filest)(setq kept-old-versions10)(setq kept-new-versions10);; When tooltip-mode is enabled, certain UI elements (e.g., help text,;; mouse-hover hints) will appear as native system tooltips (pop-up windows),;; rather than as echo area messages. This is useful in graphical Emacs sessions;; where tooltips can appear near the cursor.(setq tooltip-hide-delay20); Time in seconds before a tooltip disappears (default: 10)(setq tooltip-delay0.4); Delay before showing a tooltip after mouse hover (default: 0.7)(setq tooltip-short-delay0.08); Delay before showing a short tooltip (Default: 0.1)(tooltip-mode1);; Configure the built-in Emacs server to start after initialization,;; allowing the use of the emacsclient command to open files in the;; current session.(use-package server:ensurenil:commands server-start:hook (after-init. server-start))
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
Thestraight.el package is a declarative package manager for Emacs that aims to replace traditional systems likepackage.el by providing more precise control over package installation and management. Unlikepackage.el, which relies on downloading pre-built packages from ELPA archives,straight.el clones packages directly from their source repositories (typically Git), enabling reproducible and fully source-controlled package configurations.
Add the straight.el bootstrap code to~/.emacs.d/pre-init.el:
;; Straight bootstrap(defvarbootstrap-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-version7)) (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-filenil'nomessage))
NOTE: When using the:hook keyword withuse-package, replaceafter-init andemacs-startup withelpaca-after-init. Similarly, when usingadd-hook, replaceafter-init-hook,emacs-startup-hook withelpaca-after-init-hook to ensure they execute only after Elpaca has activated all queued packages.
Elpaca is a modern, asynchronous package manager for Emacs designed to be a drop-in replacement forpackage.el andstraight.el, with enhanced performance and flexibility. Unlike traditional Emacs package managers, Elpaca installs packages asynchronously, allowing Emacs to remain responsive during installation and updates.
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-refreshnil)
Andadd the Elpaca bootstrap code to~/.emacs.d/pre-init.el:
;; Elpaca bootstrap(defvarelpaca-installer-version0.11)(defvarelpaca-directory (expand-file-name"elpaca/" user-emacs-directory))(defvarelpaca-builds-directory (expand-file-name"builds/" elpaca-directory))(defvarelpaca-repos-directory (expand-file-name"repos/" elpaca-directory))(defvarelpaca-order '(elpaca:repo"https://github.com/progfolio/elpaca.git":refnil:depth1: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 repot) (when (<= emacs-major-version28) (require'subr-x)) (condition-case-unless-debug err (if-let* ((buffer (pop-to-buffer-same-window"*elpaca-bootstrap*")) ((zerop (apply#'call-process `("git"nil,buffert"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 buffert"checkout" (or (plist-get order:ref)"--")))) (emacs (concat invocation-directory invocation-name)) ((zerop (call-process emacsnil buffernil"-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-autoloadsnilt) (require'elpaca) (elpaca-generate-autoloads"elpaca" repo) (let ((load-source-file-functionnil)) (load"./elpaca-autoloads"))))(add-hook'after-init-hook#'elpaca-process-queues)(elpaca `(,@elpaca-order));; Optional: Install use-package support;; If you enable elpaca-use-package, some use-package definitions, such as;; Vertico's, may need modifications. See the following discussion for details:;; https://github.com/jamescherti/minimal-emacs.d/issues/54;;;; (elpaca elpaca-use-package;; (elpaca-use-package-mode))
By default, minimal-emacs.d setsscroll-conservatively to20:
(setq scroll-conservatively20); Default minimal-emacs.d value
This makes Emacs recenters the window when the cursor moves pastscroll-conservatively lines beyond the window edge.
You can override this in yourpost-init.el file. Setting it to0 forces Emacs to recenter the point aggressively, typically positioning it in the middle of the window (NOT RECOMMENDED):
(setq scroll-conservatively0); NOT RECOMMENDED
Although this offers more surrounding context, it results in frequent and pronounced screen movement, which can disrupt navigation. A value of0 is generally discouraged unless this behavior is explicitly desired.
A value of101 minimizes screen movement and maintains point visibility with minimal adjustment:
(setq scroll-conservatively101)
The main drawback of101 is that Emacs will avoid recentering almost entirely, only adjusting the window just enough to keep point visible at the very top or very bottom of the screen. Point can stick to the top or bottom edge of the window, giving you very little context above or below, which can make editing harder if you want surrounding lines visible.
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:
(defundisplay-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-time100)
(Alternatively, you may use the built-inM-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 afterafter-init-time.)
By default,minimal-emacs.d is configured to prioritize packages fromGNU ELPA andNonGNU ELPA repositories overMELPA, ensuring greater stability.
If you prefer to obtain the latest packages from MELPA to access new features and improvements, you can adjust the priority so that Emacsuse-package retrieves the newest versions from MELPA before consulting the stable GNU and NonGNU repositories. While MELPA packages are generally regarded as less stable, actual breakages are uncommon; over the past year, only a single package (package-lint) out of 146 packages in the author’s configuration experienced a brief disruption, which was quickly resolved.
Benefit:
- Ensures access to themost recent package versions, enabling early adoption of new features, performance improvements, and upstream bug fixes.
- Prioritizing MELPA provides abroader selection of cutting-edge packages, including experimental or niche tools that may not yet exist in stable archives.
Drawback:
- Exposure topotential instability, as MELPA packages are often built from the latest commits without extensive regression testing.
- May requireperiodic maintenance, such as resolving dependency conflicts or adapting to API changes in packages that evolve rapidly. (actual breakages are uncommon.)
To ensure that Emacs always installs or updates to the newest versions of all packages, add the following configuration to~/.emacs.d/post-early-init.el:
;; Obtain the latest packages from MELPA to access new features and;; improvements. While MELPA packages are generally regarded as less stable,;; actual breakages are uncommon; over the past year, only a single package;; (package-lint) out of 146 packages in the minimal-emacs.d author’s;; configuration experienced a brief disruption, which was quickly resolved.(setq package-archive-priorities '(("melpa".90) ("gnu".70) ("nongnu".60) ("melpa-stable".50)))
This setup prioritizesMELPA over the stable GNU and NonGNU repositories. When multiple archives provide the same package, Emacs will choose the version from the archive with the highest priority. As a result, you will consistently receive the latest available versions from MELPA while still having access to stable GNU and NonGNU packages when MELPA does not provide them.
In the event of a package breakage, you can direct Emacs to install a package from a specific repository. For instance, to ensure thatevil andevil-collection are installed frommelpa-stable, add the following configuration to~/.emacs.d/post-early-init.el:
(setq package-pinned-packages '((evil."melpa-stable") (evil-collection."melpa-stable")))
Here is a comprehensivepackage-pinned-packages configuration to guarantee that essential packages, such asconsult orcorfu, are retrieved from a stable repository, while all remaining packages are obtained from MELPA according to the `package-archive-priorities' priorities above:
(setq package-pinned-packages '((annalist."melpa-stable") (ansible-doc."melpa-stable") (apheleia."melpa-stable") (basic-mode."melpa-stable") (consult-dir."melpa-stable") (corfu-prescient."melpa-stable") (dtrt-indent."melpa-stable") (dumb-jump."melpa-stable") (elisp-refs."melpa-stable") (evil-collection."melpa-stable") (f."melpa-stable") (flymake-quickdef."melpa-stable") (groovy-mode."melpa-stable") (highlight-defined."melpa-stable") (markdown-toc."melpa-stable") (org-appear."melpa-stable") (package-lint-flymake."melpa-stable") (parent-mode."melpa-stable") (php-mode."melpa-stable") (prescient."melpa-stable") (s."melpa-stable") (tocus."melpa-stable") (treesit-auto."melpa-stable") (vertico-prescient."melpa-stable") (visual-fill-column."melpa-stable") (yasnippet-snippets."melpa-stable") (ace-window."gnu") (aggressive-indent."gnu") (avy."gnu") (cape."gnu") (compat."gnu") (consult."gnu") (corfu."gnu") (csv-mode."gnu") (dash."gnu") (diff-hl."gnu") (diminish."gnu") (easy-escape."gnu") (embark."gnu") (embark-consult."gnu") (expand-region."gnu") (gcmh."gnu") (indent-bars."gnu") (marginalia."gnu") (modus-themes."gnu") (orderless."gnu") (org."gnu") (rainbow-mode."gnu") (transient."gnu") (vertico."gnu") (yasnippet."gnu") (ztree."gnu") (eat."nongnu") (edit-indirect."nongnu") (evil-visualstar."nongnu") (exec-path-from-shell."nongnu") (git-modes."nongnu") (golden-ratio."nongnu") (goto-chg."nongnu") (gptel."nongnu") (lua-mode."nongnu") (magit."nongnu") (markdown-mode."nongnu") (package-lint."nongnu") (page-break-lines."nongnu") (paredit."nongnu") (popup."nongnu") (rainbow-delimiters."nongnu") (undo-fu."nongnu") (undo-fu-session."nongnu") (wgrep."nongnu") (with-editor."nongnu") (ws-butler."nongnu") (yaml-mode."nongnu")))
Note: The minimal-emacs.d author does not recommend using MELPA Stable. Use MELPA instead, which is enabled by default in the minimal-emacs.d configuration.
By default,minimal-emacs.d usesMELPA instead ofMELPA Stable because MELPA Stable offers outdated packages that lack essential features. If you prefer to use MELPA Stable, you may follow the instructions below.
Here are the key differences betweenMELPA (the default repository used in minimal-emacs.d) andMELPA Stable:
- MELPA (preferred) 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:
;; This change increases MELPA Stable priority to 70, above MELPA,;; ensuring that MELPA is preferred for package installations;; over MELPA Stable.;; (Note: The minimal-emacs.d author does not assign higher priority to MELPA;; Stable than to MELPA.);;;; (setq package-archive-priorities '(("gnu" . 90);; ("nongnu" . 80);; ("melpa-stable" . 70);; ("melpa" . 60)))
Add the following line to the end of yourpost-init.el file:
(minimal-emacs-load-user-init"local.el")This allowslocal.el to load, enabling custom configurations specific to the machine.
(Ensure thatlocal.el is in the same directory aspost-init.el.)
In certain Emacs configurations, specific files may be recompiled repeatedly during startup.
Compiling /snap/emacs/current/usr/share/emacs/lisp/org/org-loaddefs.el.gz...Compiling /snap/emacs/current/usr/share/emacs/etc/themes/modus-vivendi-theme.el...
This behavior arises because Emacs performs native compilation on specific Elisp files, and in many scenarios, it is desirable to prevent compilation of files that fail during the process.
Emacs can be configured to bypass native compilation for files whose paths match a list of regular expression patterns by settingnative-comp-jit-compilation-deny-list. For example:
(let ((deny-list '("\\(?:[/\\\\]\\.dir-locals\\.el\\(?:\\.gz\\)?$\\)""\\(?:[/\\\\]modus-vivendi-theme\\.el\\(?:\\.gz\\)?$\\)""\\(?:[/\\\\][^/\\\\]+-loaddefs\\.el\\(?:\\.gz\\)?$\\)""\\(?:[/\\\\][^/\\\\]+-autoloads\\.el\\(?:\\.gz\\)?$\\)"))) (setq native-comp-jit-compilation-deny-list deny-list);; Deprecated (with-no-warnings (setq native-comp-deferred-compilation-deny-list deny-list) (setq comp-deferred-compilation-deny-list deny-list)))
This deny list instructs Emacs to bypass native compilation for files matching the specified patterns, preventing unnecessary or error-prone recompilation while permitting all other files to be compiled normally.
To load customizations saved by Emacs (M-x customize), add the following code snippet to thepost-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)
However, rather than relying on customizations loaded with the code above, the author recommends configuring Emacs through init files (just as you are doing by reading this README.md and customizing packages usinguse-package with the:custom keyword).
Add the following to~/.emacs.d/pre-early-init.el to ensure thatminimal-emacs.d restores the specified amount after startup:
(setq minimal-emacs-gc-cons-threshold (*6410241024))
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 settingenable-dir-local-variables tonil:
(setq enable-dir-local-variablesnil)
Add the following to the top of the~/.emacs.d/pre-early-init.el file to makeminimal-emacs.d use theMINIMAL_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 ofearly-init.el (andpre-early-init.el andpost-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 andpre-init.el serve different purposes and are not the same.
The menu bar is disabled by default inminimal-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-menutool-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 theminimal-emacs.d configuration loadspost-early-init.el,pre-init.el, andpost-init.el from a different directory, such as~/.config/minimal-emacs.d/, modify theminimal-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 theminimal-emacs.d configuration loadspost-early-init.el,pre-init.el, andpost-init.el from~/.config/minimal-emacs.d/.
Keep in mind that if you change theminimal-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 topost-early-init.el:
(setq minimal-emacs-package-initialize-and-refreshnil);; 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.
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-modeto 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-alistfor improved startup time and package load time (Special thanks to the Doom Emacs developers for thefile-name-handler-alistoptimizations; 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
Theminimal-emacs.d project has been written byJames Cherti and is distributed under terms of the GNU General Public License version 3, or, at your choice, any later version.
Copyright (C) 2024-2025James 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).
Contribution from the minimal-emacs.d community:
- Sunng's minimal-emacs.d Nix flake: A Nix flake that enables reproducible deployment of minimal-emacs.d, allowing the Emacs configuration to be pinned, built, and installed through Nix.
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 usingevil-mode withparedit. It interceptsevil-mode commands such as delete, change, and paste, blocking their execution if they would break the parenthetical structure.
- stripspace.el: Ensure Emacs Automatically removes trailing whitespace before saving a buffer, with an option to preserve the cursor column.
- persist-text-scale.el: Ensure that all adjustments made with text-scale-increase and text-scale-decrease are persisted and restored across sessions.
- pathaction.el: Execute the pathaction command-line tool from Emacs. The pathaction command-line tool enables the execution of specific commands on targeted files or directories. Its key advantage lies in its flexibility, allowing users to handle various types of files simply by passing the file or directory as an argument to the pathaction tool. The tool uses a .pathaction.yaml rule-set file to determine which command to execute. Additionally, Jinja2 templating can be employed in the rule-set file to further customize the commands.
About
minimal-emacs.d - Better Emacs defaults and optimized startup, intended to serve as a solid foundation for your vanilla Emacs configuration
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.






