diff --git a/README.md b/README.md
index 984df45..22b38a1 100644
--- a/README.md
+++ b/README.md
@@ -2,35 +2,34 @@


+# *minimal-emacs.d* - A Customizable Emacs `init.el` and `early-init.el` for Better Defaults and Optimized Startup
+
+[](https://www.gnu.org/licenses/gpl-3.0)
+
+
My dotfiles are based on the [minimal-emacs.d](https://github.com/jamescherti/minimal-emacs.d) project. The changes to the source repository will sometimes be synced to this repository, with my own changes being rebased on top.

The original repository contains a lot of useful info, so do check it out.
-
-## Dotfiles setup
-
-
-
-
-**Here are the instructions for installing minimal-emacs.d:** [Install minimal-emacs.d](#install-minimal-emacsd).
-
-### Looking for the ideal starter kit to customize Emacs? You have found it.
+### Looking for the ideal starter kit to customize Emacs?
The *minimal-emacs.d* project is:
-- **Minimal yet effective:** A solid starting point.
-- **Better defaults:** Improved settings for usability, UI, garbage collection, and built-in packages.
-- **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 your *minimal-emacs.d* configuration. (Reminder: [Never modify init.el and early-init.el. Modify these instead...](#customizations-never-modify-initel-and-early-initel-modify-these-instead))
+
+* **Minimal yet effective:** A solid starting point.
+* **Better defaults:** Improved settings for usability, UI, garbage collection, and built-in packages. (Emacs comes with many well-designed defaults, but it also retains some less-than-ideal settings, often due to historical constraints or legacy compatibility.)
+* **0 packages loaded / No forced modes:** Unlike other frameworks, *minimal-emacs.d* does not impose modes or require packages. **You have full control** over which global or minor modes to enable.
+* **Customizable foundation:** Designed to be extended, not replaced. This README offers extensive recommendations for customizing your configuration.
The *minimal-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.
+**Skip to: [Install minimal-emacs.d](#install-minimal-emacsd)**
-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 of *minimal-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.
+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. You retain full control over which packages to install and which modes to enable.

*(The theme shown in the screenshot above is ef-melissa-light, which is part of the ef-themes collection available on MELPA.)*
@@ -39,7 +38,7 @@ Emacs comes with many well-designed defaults, but it also retains some less-than

*(The theme shown in the screenshot above is the *[tomorrow-night-deepblue-theme.el](https://github.com/jamescherti/tomorrow-night-deepblue-theme.el)*, available on MELPA.)*
-### Startup
+### Startup Performance
The author uses *minimal-emacs.d* as his `early-init.el` and `init.el`, alongside **146 packages** ([See the packages that the author is using here](https://www.jamescherti.com/essential-emacs-packages/)). Yet, thanks to its efficient design, Emacs still **starts in just 0.22 seconds**:
@@ -48,9 +47,9 @@ Author of [minimal-emacs.d](https://github.com/jamescherti/minimal-emacs.d) sugg
As such, post-init.el file only contains the minimal setup code, and at the end loads the files in the `.config.d` folder, in alphanumeric order. In those plug-in files the real magic happens. All the files are heavily documented, with mostly self-explanatory names, so I think it will be redundant to list them here. See the files in `config.d` directory for more.
-In addition to *minimal-emacs.d*, startup speed is influenced by your computer's processing power and disk speed. To establish a baseline, start Emacs with only *minimal-emacs.d* and no additional configurations, then run `M-x emacs-init-time`. Incrementally modify your init files and observe the impact on startup time. For consistent comparisons, always test on the same computer and Emacs version. It's also important to ensure that all packages are deferred using `:defer t` and `:commands`, which makes Emacs load them only when needed (see additional examples in this README.md). While startup time is important, other factors, like native compilation, are even more important. Although native compilation may introduce some brief initial and negligible initial delay, it is beneficial in the long run as it significantly speeds up Emacs.
+Startup speed depends on hardware and disk speed. For consistent comparisons, test on the same computer and Emacs version. While startup time is significant, factors like native compilation are also important for long-term performance.
-## Comments from minimal-emacs.d users
+## User Testimonials
- [gnudoc on Reddit](https://www.reddit.com/r/emacs/comments/1feaf37/comment/lmn1hoo/): "That's a great learning resource. Thank you for your work on it and for sharing it!"
- [dewyke on Reddit](https://www.reddit.com/r/emacs/comments/1feaf37/comment/lmq53an/): "Lots of good stuff in there, even for people who already have established ways of organising their configs."
@@ -68,83 +67,108 @@ In addition to *minimal-emacs.d*, startup speed is influenced by your computer's
- [xzway on Reddit](https://www.reddit.com/r/emacs/comments/1p9y8h4/comment/nrh8dye/): "The minimal-emacs.d configuration is very well-designed and non-intrusive. I'm also using it to refactor my configuration."
- [jeenajeena on Reddit](https://www.reddit.com/r/emacs/comments/1p9y8h4/comment/nrfk13i/): "Thank you. Plenty of inspiring settings. Worth to be read line by line."
- [uutangohotel on Reddit](https://www.reddit.com/r/emacs/comments/1p9y8h4/comment/nrg5kja/): "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](https://www.reddit.com/r/emacs/comments/1p9y8h4/comment/ns1nehi/): "Nice work! I just created a nix flake to using it on my dev servers https://codeberg.org/sunng/minimal-emacs.d-nix-hm "
+- [sunng on Reddit](https://www.reddit.com/r/emacs/comments/1p9y8h4/comment/ns1nehi/): "Nice work! I just created a nix flake to using it on my dev servers"
+- [zackattackz287 on Reddit](https://www.reddit.com/r/emacs/comments/1rsmaut/comment/oa8okca/): "Congrats and thank you (and the community around minimal.d) for your work! I've been using it for quite a while now and I've not ever had any breakages when merging changes from main..."
+- [utility on Reddit](https://www.reddit.com/r/emacs/comments/1rsmaut/comment/oa8wrap/): "Excellent. I use this and I'm very happy with it!"
Please share your configuration. It could serve as inspiration for other users.
## Table of Contents
-- [*minimal-emacs.d* - A Customizable Emacs `init.el` and `early-init.el` that Provides Better Defaults and Faster Startup](#minimal-emacsd---a-customizable-emacs-initel-and-early-initel-that-provides-better-defaults-and-faster-startup)
- - [Introduction](#introduction)
- - [Looking for the ideal starter kit to customize Emacs? You have found it.](#looking-for-the-ideal-starter-kit-to-customize-emacs-you-have-found-it)
- - [Startup](#startup)
- - [Comments from minimal-emacs.d users](#comments-from-minimal-emacsd-users)
- - [Install minimal-emacs.d](#install-minimal-emacsd)
- - [Install minimal-emacs.d into `~/.emacs.d`](#install-minimal-emacsd-into-emacsd)
- - [Alternative: Install minimal-emacs.d into `~/.minimal-emacs.d`](#alternative-install-minimal-emacsd-into-minimal-emacsd)
- - [Update minimal-emacs.d](#update-minimal-emacsd)
- - [Customizations: Never modify init.el and early-init.el. Modify these instead...](#customizations-never-modify-initel-and-early-initel-modify-these-instead)
- - [Debug on error](#debug-on-error)
- - [Customizations: UI (pre-early-init.el)](#customizations-ui-pre-early-initel)
- - [How to enable the menu-bar, the tool-bar, dialogs, the contextual menu, and tooltips?](#how-to-enable-the-menu-bar-the-tool-bar-dialogs-the-contextual-menu-and-tooltips)
- - [Reducing clutter in `~/.emacs.d` by redirecting files to `~/.emacs.d/var/`](#reducing-clutter-in-emacsd-by-redirecting-files-to-emacsdvar)
- - [Customizations: Packages (post-init.el)](#customizations-packages-post-initel)
- - [Optimization: Native Compilation](#optimization-native-compilation)
- - [How to activate recentf, savehist, saveplace, and auto-revert?](#how-to-activate-recentf-savehist-saveplace-and-auto-revert)
- - [Activating autosave](#activating-autosave)
- - [auto-save-mode (Prevent data loss in case of crashes)](#auto-save-mode-prevent-data-loss-in-case-of-crashes)
- - [auto-save-visited-mode (Save file buffers after a few seconds of inactivity)](#auto-save-visited-mode-save-file-buffers-after-a-few-seconds-of-inactivity)
- - [Code completion with corfu](#code-completion-with-corfu)
- - [Configuring Vertico, Consult, and Embark](#configuring-vertico-consult-and-embark)
- - [Code folding](#code-folding)
- - [Changing the default theme](#changing-the-default-theme)
- - [Automatic removal of trailing whitespace on save](#automatic-removal-of-trailing-whitespace-on-save)
- - [Enhancing undo/redo](#enhancing-undoredo)
- - [Configuring Vim keybindings using Evil?](#configuring-vim-keybindings-using-evil)
- - [Configuring LSP Servers with Eglot (built-in)](#configuring-lsp-servers-with-eglot-built-in)
- - [Persisting and Restoring all buffers, windows/split, tab-bar, frames...](#persisting-and-restoring-all-buffers-windowssplit-tab-bar-frames)
- - [Configuring org-mode](#configuring-org-mode)
- - [Configuring markdown-mode (e.g., README.md syntax)](#configuring-markdown-mode-eg-readmemd-syntax)
- - [Tree-sitter Integration (Better Syntax Highlighting)](#tree-sitter-integration-better-syntax-highlighting)
- - [Auto upgrade Emacs packages](#auto-upgrade-emacs-packages)
- - [Safely terminating unused buffers](#safely-terminating-unused-buffers)
- - [Treemacs, a tree layout file explorer (Sidebar file explorer)](#treemacs-a-tree-layout-file-explorer-sidebar-file-explorer)
- - [Inhibit the mouse](#inhibit-the-mouse)
- - [Spell checker](#spell-checker)
- - [Efficient jumps for enhanced productivity](#efficient-jumps-for-enhanced-productivity)
- - [Asynchronous code formatting without cursor disruption](#asynchronous-code-formatting-without-cursor-disruption)
- - [Efficient template expansion with snippets](#efficient-template-expansion-with-snippets)
- - [A better Emacs *help* buffer](#a-better-emacs-help-buffer)
- - [Enhancing the Elisp development experience](#enhancing-the-elisp-development-experience)
- - [Showing the tab-bar](#showing-the-tab-bar)
- - [Changing the Default Font](#changing-the-default-font)
- - [Persist Text Scale](#persist-text-scale)
- - [Loading the custom.el file](#loading-the-customel-file)
- - [Which other customizations can be interesting to add?](#which-other-customizations-can-be-interesting-to-add)
- - [Customizations: pre-early-init.el](#customizations-pre-early-initel)
- - [Configuring straight.el](#configuring-straightel)
- - [Configuring Elpaca (package manager)](#configuring-elpaca-package-manager)
- - [Frequently asked questions](#frequently-asked-questions)
- - [Customizing Scroll Recentering](#customizing-scroll-recentering)
- - [How to display Emacs startup duration?](#how-to-display-emacs-startup-duration)
- - [How to get the latest version of all packages? (unstable)](#how-to-get-the-latest-version-of-all-packages-unstable)
- - [How to use MELPA stable?](#how-to-use-melpa-stable)
- - [How to load a local lisp file for machine-specific configurations?](#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-prevent-emacs-from-repeatedly-performing-native-compilation-on-specific-elisp-files)
- - [How to load Emacs customizations?](#how-to-load-emacs-customizations)
- - [How to increase gc-cons-threshold?](#how-to-increase-gc-cons-threshold)
- - [How to prevent Emacs from loading .dir-locals.el files?](#how-to-prevent-emacs-from-loading-dir-localsel-files)
- - [How to make minimal-emacs.d use an environment variable to change ~/.emacs.d to another directory?](#how-to-make-minimal-emacsd-use-an-environment-variable-to-change-emacsd-to-another-directory)
- - [Are post-early-init.el and pre-init.el the same file in terms of the logic?](#are-post-early-initel-and-pre-initel-the-same-file-in-terms-of-the-logic)
- - [Why is the menu bar disabled by default?](#why-is-the-menu-bar-disabled-by-default)
- - [Why did the author develop minimal-emacs.d?](#why-did-the-author-develop-minimal-emacsd)
- - [How to keep minimal-emacs.d pre-\*.el and post-\*.el files in a separate directory?](#how-to-keep-minimal-emacsd-pre-el-and-post-el-files-in-a-separate-directory)
- - [How to make *minimal-emacs.d* install packages in the early-init phase instead of the init phase?](#how-to-make-minimal-emacsd-install-packages-in-the-early-init-phase-instead-of-the-init-phase)
- - [Minimal-emacs.d configurations from users](#minimal-emacsd-configurations-from-users)
- - [Features](#features)
- - [Author and license](#author-and-license)
- - [Links](#links)
+- [*minimal-emacs.d* - A Customizable Emacs `init.el` and `early-init.el` for Better Defaults and Optimized Startup](#minimal-emacsd---a-customizable-emacs-initel-and-early-initel-for-better-defaults-and-optimized-startup)
+ - [Introduction](#introduction)
+ - [Looking for the ideal starter kit to customize Emacs?](#looking-for-the-ideal-starter-kit-to-customize-emacs)
+ - [Startup Performance](#startup-performance)
+ - [User Testimonials](#user-testimonials)
+ - [Install minimal-emacs.d](#install-minimal-emacsd)
+ - [Install minimal-emacs.d into `~/.emacs.d`](#install-minimal-emacsd-into-emacsd)
+ - [Alternative: Install minimal-emacs.d into `~/.minimal-emacs.d`](#alternative-install-minimal-emacsd-into-minimal-emacsd)
+ - [Update minimal-emacs.d](#update-minimal-emacsd)
+ - [Customizations: Never modify init.el and early-init.el. Modify these instead...](#customizations-never-modify-initel-and-early-initel-modify-these-instead)
+ - [Recommendations](#recommendations)
+ - [Always defer package loading](#always-defer-package-loading)
+ - [Customizations: UI (File: pre-early-init.el)](#customizations-ui-file-pre-early-initel)
+ - [How to enable the menu-bar, the tool-bar, dialogs, the contextual menu, and tooltips?](#how-to-enable-the-menu-bar-the-tool-bar-dialogs-the-contextual-menu-and-tooltips)
+ - [Reducing clutter in `~/.emacs.d` by redirecting files to `~/.emacs.d/var/`](#reducing-clutter-in-emacsd-by-redirecting-files-to-emacsdvar)
+ - [Customizations: Packages (File: post-init.el)](#customizations-packages-file-post-initel)
+ - [Optimization: Native Compilation](#optimization-native-compilation)
+ - [Environment Variable Synchronization (Essential for macOS users)](#environment-variable-synchronization-essential-for-macos-users)
+ - [File Management & History: recentf, savehist, saveplace, and auto-revert?](#file-management--history-recentf-savehist-saveplace-and-auto-revert)
+ - [Safety: Auto-Save](#safety-auto-save)
+ - [auto-save-mode (Prevent data loss in case of crashes)](#auto-save-mode-prevent-data-loss-in-case-of-crashes)
+ - [auto-save-visited-mode (Save file buffers after a few seconds of inactivity)](#auto-save-visited-mode-save-file-buffers-after-a-few-seconds-of-inactivity)
+ - [Completion System (Corfu, Vertico, Consult)](#completion-system-corfu-vertico-consult)
+ - [Vertico, Consult, Marginalia, and Embark](#vertico-consult-marginalia-and-embark)
+ - [Enhancing undo/redo](#enhancing-undoredo)
+ - [Changing the default theme](#changing-the-default-theme)
+ - [Configuring Vim keybindings using Evil?](#configuring-vim-keybindings-using-evil)
+ - [Persisting and Restoring all buffers, windows/split, tab-bar, frames...](#persisting-and-restoring-all-buffers-windowssplit-tab-bar-frames)
+ - [Configuring markdown-mode (e.g., README.md syntax)](#configuring-markdown-mode-eg-readmemd-syntax)
+ - [Code folding](#code-folding)
+ - [Kirigami: A unified interface for opening and closing folds](#kirigami-a-unified-interface-for-opening-and-closing-folds)
+ - [outline-minor-mode and hs-minor-mode](#outline-minor-mode-and-hs-minor-mode)
+ - [outline-indent-minor-mode: Folding based on indentation levels](#outline-indent-minor-mode-folding-based-on-indentation-levels)
+ - [treesit-fold](#treesit-fold)
+ - [Asynchronous code formatting without cursor disruption](#asynchronous-code-formatting-without-cursor-disruption)
+ - [Context-aware 'go to definition' functionality for 50+ programming languages](#context-aware-go-to-definition-functionality-for-50-programming-languages)
+ - [Efficient template expansion with snippets](#efficient-template-expansion-with-snippets)
+ - [Spell checker](#spell-checker)
+ - [Automatic removal of trailing whitespace on save](#automatic-removal-of-trailing-whitespace-on-save)
+ - [Highlighting uncommitted changes in the buffer margin (e.g., Git changes)](#highlighting-uncommitted-changes-in-the-buffer-margin-eg-git-changes)
+ - [Configuring org-mode](#configuring-org-mode)
+ - [Configuring LSP Servers with Eglot (built-in)](#configuring-lsp-servers-with-eglot-built-in)
+ - [Auto upgrade Emacs packages](#auto-upgrade-emacs-packages)
+ - [Safely terminating unused buffers](#safely-terminating-unused-buffers)
+ - [Treemacs, a tree layout file explorer (Sidebar file explorer)](#treemacs-a-tree-layout-file-explorer-sidebar-file-explorer)
+ - [A better Emacs *help* buffer](#a-better-emacs-help-buffer)
+ - [Efficient jumps](#efficient-jumps)
+ - [Renaming and deleting files](#renaming-and-deleting-files)
+ - [Enhancing the Elisp development experience](#enhancing-the-elisp-development-experience)
+ - [Inhibiting the mouse](#inhibiting-the-mouse)
+ - [Showing the tab-bar](#showing-the-tab-bar)
+ - [Offline Dictionary](#offline-dictionary)
+ - [Changing the Default Font](#changing-the-default-font)
+ - [Persisting and Restoring Text Scale](#persisting-and-restoring-text-scale)
+ - [A Faster Terminal Emulator](#a-faster-terminal-emulator)
+ - [Loading the custom.el file](#loading-the-customel-file)
+ - [Which other customizations can be interesting to add?](#which-other-customizations-can-be-interesting-to-add)
+ - [File types (Yaml, Dockerfile, Lua, Jinja2, CSV, Vimrc...)](#file-types-yaml-dockerfile-lua-jinja2-csv-vimrc)
+ - [Customizations: Before init (File: pre-init.el)](#customizations-before-init-file-pre-initel)
+ - [Configuring straight.el](#configuring-straightel)
+ - [Configuring Elpaca (package manager)](#configuring-elpaca-package-manager)
+ - [Frequently asked questions](#frequently-asked-questions)
+ - [How to debug my configuration?](#how-to-debug-my-configuration)
+ - [Customizing Scroll Recentering](#customizing-scroll-recentering)
+ - [How to display Emacs startup duration?](#how-to-display-emacs-startup-duration)
+ - [Optimization: Disabling `site-run-file` and `inhibit-default-init`](#optimization-disabling-site-run-file-and-inhibit-default-init)
+ - [Disable `site-start.el` (Pre-Initialization Stage)](#disable-site-startel-pre-initialization-stage)
+ - [Disable `default.el` (Post-Initialization Stage)](#disable-defaultel-post-initialization-stage)
+ - [How to get the latest version of all packages? (unstable)](#how-to-get-the-latest-version-of-all-packages-unstable)
+ - [How to use MELPA stable?](#how-to-use-melpa-stable)
+ - [How to load a local lisp file for machine-specific configurations?](#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-prevent-emacs-from-repeatedly-performing-native-compilation-on-specific-elisp-files)
+ - [How to load Emacs customizations?](#how-to-load-emacs-customizations)
+ - [How to increase gc-cons-threshold?](#how-to-increase-gc-cons-threshold)
+ - [How to prevent Emacs from loading .dir-locals.el files?](#how-to-prevent-emacs-from-loading-dir-localsel-files)
+ - [How to make minimal-emacs.d use an environment variable to change ~/.emacs.d to another directory?](#how-to-make-minimal-emacsd-use-an-environment-variable-to-change-emacsd-to-another-directory)
+ - [Are post-early-init.el and pre-init.el the same file in terms of the logic?](#are-post-early-initel-and-pre-initel-the-same-file-in-terms-of-the-logic)
+ - [Why is the menu bar disabled by default?](#why-is-the-menu-bar-disabled-by-default)
+ - [Why did the author develop minimal-emacs.d?](#why-did-the-author-develop-minimal-emacsd)
+ - [How to keep minimal-emacs.d pre-\*.el and post-\*.el files in a separate directory?](#how-to-keep-minimal-emacsd-pre-el-and-post-el-files-in-a-separate-directory)
+ - [How to make *minimal-emacs.d* install packages in the early-init phase instead of the init phase?](#how-to-make-minimal-emacsd-install-packages-in-the-early-init-phase-instead-of-the-init-phase)
+ - [Minimal-emacs.d configurations from users](#minimal-emacsd-configurations-from-users)
+ - [Features](#features)
+ - [Fast Initialization and Performance](#fast-initialization-and-performance)
+ - [Native Compilation and Byte Compilation](#native-compilation-and-byte-compilation)
+ - [Interface Defaults](#interface-defaults)
+ - [Package and File Management](#package-and-file-management)
+ - [Precision Editing and UX Enhancements](#precision-editing-and-ux-enhancements)
+ - [Developer Experience](#developer-experience)
+ - [Buffer, Directory, and Window Management](#buffer-directory-and-window-management)
+ - [Security, Stability, and Customizable Initialization](#security-stability-and-customizable-initialization)
+ - [Author and license](#author-and-license)
+ - [Links](#links)
@@ -202,21 +226,19 @@ Always begin your `pre-init.el`, `post-init.el`, `post-early-init.el`, and `pre-
Replace `FILENAME.el` with the actual name and DESCRIPTION with a brief description of its purpose.
-*(Only if you know what you're doing: Removing `no-byte-compile: t;` from your init files allows Emacs to compile them, improving load and execution speed. However, if you do so, you may need to add required dependencies. For example, if you're using `use-package`, add `(require 'use-package)` at the top of `post-init.el` to ensure all necessary `use-package` variables and functions are loaded.)*
+*(Only if you know what you're doing: Removing `no-byte-compile: t;` from your init files allows Emacs to compile them, improving load and execution speed. However, if you do so, you may need to add required dependencies. For example, if you're using `use-package`, add `(require 'use-package)` at the top of `post-init.el` to ensure all necessary `use-package` variables and functions are loaded. **The only init file where `no-byte-compile: t` should never be removed is `early-init.el`**, because if this file is compiled, Emacs may load an outdated compiled version.)*
**Important:** The examples in this README reference pre/post init files in the `~/.emacs.d/` directory, but the files `pre-early-init.el`, `post-early-init.el`, `pre-init.el`, and `post-init.el` should be placed in the same directory as `init.el` and `early-init.el`, regardless of their location.
-## Debug on error
+## Recommendations
-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:
+### Always defer package loading
-```elisp
-(setq debug-on-error t)
-```
+**All `use-package` declarations in this README use deferred loading, so you can safely copy and paste them into your configuration.**
-Enabling `debug-on-error` at this stage allows you to catch errors that might otherwise cause Emacs to fail silently or behave unpredictably.
+To ensure your configuration remains fast and responsive, always defer package loading so that libraries are initialized only when they are needed. **The `use-package` macro makes this effortless; simply adding `:commands` or `:bind` to your package declarations automatically configures them for deferred loading.**
-## Customizations: UI (pre-early-init.el)
+## Customizations: UI (File: pre-early-init.el)
### How to enable the menu-bar, the tool-bar, dialogs, the contextual menu, and tooltips?
@@ -246,7 +268,7 @@ An alternative lightweight approach is to simply change the default `~/.emacs.d`
**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.
-## Customizations: Packages (post-init.el)
+## Customizations: Packages (File: post-init.el)
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.
@@ -258,7 +280,7 @@ Native compilation enhances Emacs performance by converting Elisp code into nati
```elisp
(native-comp-available-p)
```
- (A non-nil result indicates that native compilation is active.)
+ (A non-nil result indicates that native compilation is available.)
2. Ensure all libraries are byte-compiled and native-compiled using [compile-angel.el](https://github.com/jamescherti/compile-angel.el). To install compile-angel, add the following code to the `~/.emacs.d/post-init.el` file:
```emacs-lisp
@@ -270,13 +292,15 @@ Native compilation enhances Emacs performance by converting Elisp code into nati
;; of your `~/.emacs.d/post-init.el` file, before all other packages.
(use-package compile-angel
:demand t
- :ensure t
- :custom
- ;; Set `compile-angel-verbose` to nil to suppress output from compile-angel.
- ;; Drawback: The minibuffer will not display compile-angel's actions.
- (compile-angel-verbose t)
-
:config
+ ;; The following disables compilation of packages during installation;
+ ;; compile-angel will handle it.
+ (setq package-native-compile nil)
+
+ ;; Set `compile-angel-verbose' to nil to disable compile-angel messages.
+ ;; (When set to nil, compile-angel won't show which file is being compiled.)
+ (setq compile-angel-verbose t)
+
;; 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
@@ -300,7 +324,34 @@ Native compilation enhances Emacs performance by converting Elisp code into nati
(compile-angel-on-load-mode 1))
```
-### How to activate recentf, savehist, saveplace, and auto-revert?
+### Environment Variable Synchronization (Essential for macOS users)
+
+On macOS, GUI applications (launched from the Finder, Dock, or Spotlight) do not inherit the user's shell environment variables by default. This often causes errors where Emacs cannot find external tools like `git`, `grep`, `pip`, or language servers (LSP), even if they work perfectly in your terminal.
+
+To fix this, add **exec-path-from-shell** to `~/.emacs.d/post-init.el`:
+
+```elisp
+(use-package exec-path-from-shell
+ :if (and (or (display-graphic-p) (daemonp))
+ (eq system-type 'darwin)) ; macOS only
+ :demand t
+ :functions exec-path-from-shell-initialize
+ :config
+ (dolist (var '("TMPDIR"
+ "SSH_AUTH_SOCK" "SSH_AGENT_PID"
+ "GPG_AGENT_INFO"
+ ;; "FZF_DEFAULT_COMMAND" "FZF_DEFAULT_OPTS" ; fzf
+ ;; "VIRTUAL_ENV" ; Python
+ ;; "GOPATH" "GOROOT" "GOBIN" ; Go
+ ;; "CARGO_HOME" "RUSTUP_HOME" ; Rust
+ ;; "NVM_DIR" "NODE_PATH" ; Node/JS
+ "LANG" "LC_CTYPE"))
+ (add-to-list 'exec-path-from-shell-variables var))
+ ;; Initialize
+ (exec-path-from-shell-initialize))
+```
+
+### File Management & History: recentf, savehist, saveplace, and auto-revert?
The recentf, savehist, saveplace, and auto-revert built-in packages are already configured by *minimal-emacs.d*. All you need to do is activate them by adding the following to `~/.emacs.d/post-init.el`:
``` emacs-lisp
@@ -312,12 +363,12 @@ The recentf, savehist, saveplace, and auto-revert built-in packages are already
:commands (auto-revert-mode global-auto-revert-mode)
:hook
(after-init . global-auto-revert-mode)
- :custom
- (auto-revert-interval 3)
- (auto-revert-remote-files nil)
- (auto-revert-use-notify t)
- (auto-revert-avoid-polling nil)
- (auto-revert-verbose t))
+ :init
+ ;; (setq auto-revert-verbose t)
+ (setq auto-revert-interval 3)
+ (setq auto-revert-remote-files nil)
+ (setq auto-revert-use-notify t)
+ (setq auto-revert-avoid-polling nil))
;; Recentf is an Emacs package that maintains a list of recently
;; accessed files, making it easier to reopen files you have worked on
@@ -328,15 +379,15 @@ The recentf, savehist, saveplace, and auto-revert built-in packages are already
: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$"))
+ :init
+ (setq recentf-auto-cleanup (if (daemonp) 300 'never))
+ (setq 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
@@ -354,13 +405,9 @@ The recentf, savehist, saveplace, and auto-revert built-in packages are already
:commands (savehist-mode savehist-save)
:hook
(after-init . savehist-mode)
- :custom
- (savehist-autosave-interval 600)
- (savehist-additional-variables
- '(kill-ring ; clipboard
- register-alist ; macros
- mark-ring global-mark-ring ; marks
- search-ring regexp-search-ring)))
+ :init
+ (setq history-length 300)
+ (setq savehist-autosave-interval 600))
;; save-place-mode enables Emacs to remember the last location within a file
;; upon reopening. This feature is particularly beneficial for resuming work at
@@ -370,11 +417,11 @@ The recentf, savehist, saveplace, and auto-revert built-in packages are already
:commands (save-place-mode save-place-local-mode)
:hook
(after-init . save-place-mode)
- :custom
- (save-place-limit 400))
+ :init
+ (setq save-place-limit 400))
```
-### Activating autosave
+### Safety: Auto-Save
#### auto-save-mode (Prevent data loss in case of crashes)
@@ -387,7 +434,10 @@ To enable autosave, add the following to `~/.emacs.d/post-init.el`:
;; `recover-session' to restore unsaved changes.
(setq auto-save-default t)
+;; Trigger an auto-save after 300 keystrokes
(setq auto-save-interval 300)
+
+;; Trigger an auto-save 30 seconds of idle time.
(setq auto-save-timeout 30)
```
@@ -411,7 +461,7 @@ This is different from `auto-save-mode`: `auto-save-mode` periodically saves all
(auto-save-visited-mode 1)
```
-### Code completion with corfu
+### Completion System (Corfu, Vertico, Consult)
[Corfu](https://github.com/minad/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.
@@ -425,7 +475,6 @@ To configure `corfu` and `cape`, add the following to `~/.emacs.d/post-init.el`:
;; current candidates, positioned either below or above the point. Candidates
;; can be selected by navigating up or down.
(use-package corfu
- :ensure t
:commands (corfu-mode global-corfu-mode)
:hook ((prog-mode . corfu-mode)
@@ -447,7 +496,6 @@ To configure `corfu` and `cape`, add the following to `~/.emacs.d/post-init.el`:
;; in-buffer completion. It integrates with Corfu or the default completion UI,
;; by providing additional backends through completion-at-point-functions.
(use-package cape
- :ensure t
:commands (cape-dabbrev cape-file cape-elisp-block)
:bind ("C-c p" . cape-prefix-map)
:init
@@ -458,7 +506,7 @@ To configure `corfu` and `cape`, add the following to `~/.emacs.d/post-init.el`:
(add-hook 'completion-at-point-functions #'cape-elisp-block))
```
-### Configuring Vertico, Consult, and Embark
+### Vertico, Consult, Marginalia, and Embark
[Vertico](https://github.com/minad/vertico), [Consult](https://github.com/minad/consult), and [Embark](https://github.com/oantolin/embark) collectively enhance Emacs' completion and navigation capabilities.
@@ -476,7 +524,6 @@ Add the following to `~/.emacs.d/post-init.el` to set up Vertico, Consult, and E
;; 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.)
- :ensure t
:config
(vertico-mode))
@@ -484,7 +531,6 @@ Add the following to `~/.emacs.d/post-init.el` to set up Vertico, Consult, and E
;; to input multiple patterns separated by spaces, which Orderless then
;; matches in any order against the candidates.
(use-package orderless
- :ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
@@ -494,7 +540,6 @@ Add the following to `~/.emacs.d/post-init.el` to set up Vertico, Consult, and E
;; In addition to that, Marginalia also enhances Vertico by adding rich
;; annotations to the completion candidates displayed in Vertico's interface.
(use-package marginalia
- :ensure t
:commands (marginalia-mode marginalia-cycle)
:hook (after-init . marginalia-mode))
@@ -506,7 +551,6 @@ Add the following to `~/.emacs.d/post-init.el` to set up Vertico, Consult, and E
;; Embark is an Emacs package that acts like a context menu, allowing
;; users to perform context-sensitive actions on selected items
;; directly from the completion interface.
- :ensure t
:commands (embark-act
embark-dwim
embark-export
@@ -529,14 +573,12 @@ Add the following to `~/.emacs.d/post-init.el` to set up Vertico, Consult, and E
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
- :ensure t
: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
- :ensure t
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
@@ -628,72 +670,46 @@ Add the following to `~/.emacs.d/post-init.el` to set up Vertico, Consult, and E
(setq consult-narrow-key "<"))
```
-### Code folding
+### Enhancing undo/redo
-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.
+The [undo-fu](https://codeberg.org/ideasman42/emacs-undo-fu) package is a lightweight wrapper around Emacs' built-in undo system, providing more convenient undo/redo functionality while preserving access to the full undo history. The [undo-fu-session](https://codeberg.org/ideasman42/emacs-undo-fu-session) package complements undo-fu by enabling the saving and restoration of undo history across Emacs sessions, even after restarting.
-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.
+The default undo system in Emacs has two main issues that undo-fu fixes:
-For example, to enable `outline-minor-mode` in Emacs Lisp:
+1. **Redo requires two steps**: To redo an action after undoing, you need to press a key twice, which can be annoying and inefficient.
+2. **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.
-``` 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
- :ensure nil
- :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) (ash 1 22)))
- (value (vconcat (mapcar (lambda (c) (+ face-offset c)) " ▼"))))
- (set-display-table-slot display-table 'selective-display value)
- (setq buffer-display-table display-table))))))
+To install and configure these packages, add the following to `~/.emacs.d/post-init.el`:
+```emacs-lisp
+;; The undo-fu package is a lightweight wrapper around Emacs' built-in undo
+;; system, providing more convenient undo/redo functionality.
+(use-package undo-fu
+ :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
+ :commands undo-fu-session-global-mode
+ :hook (after-init . undo-fu-session-global-mode))
```
-For folding based on indentation levels, the **[outline-indent](https://github.com/jamescherti/outline-indent.el)** Emacs package provides a minor mode that enables folding according to the indentation structure:
-```elisp
-;; 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
- :ensure t
- :commands outline-indent-minor-mode
-
- :custom
- (outline-indent-ellipsis " ▼")
-
- :init
- ;; The minor mode can also be automatically activated for a certain modes.
- (add-hook 'python-mode-hook #'outline-indent-minor-mode)
- (add-hook 'python-ts-mode-hook #'outline-indent-minor-mode)
-
- (add-hook 'yaml-mode-hook #'outline-indent-minor-mode)
- (add-hook 'yaml-ts-mode-hook #'outline-indent-minor-mode))
-```
-
-
-
### Changing the default theme
For instance, to switch to a another theme than the default one, add the following to the `~/.emacs.d/post-init.el` file:
```emacs-lisp
-(mapc #'disable-theme custom-enabled-themes) ; Disable all active themes
-(load-theme 'modus-operandi t) ; Load the built-in theme
+(let ((inhibit-redisplay t))
+ ;; Disable all active themes
+ (mapc #'disable-theme custom-enabled-themes)
+ ;; Load the built-in theme
+ (load-theme 'modus-operandi t))
```
(If you prefer dark themes, replace `modus-operandi` with `modus-vivendi`.)
@@ -731,74 +747,6 @@ If you're interested in exploring third-party Emacs themes, consider the followi
- `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.)
-### Automatic removal of trailing whitespace on save
-
-**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.
-
-The [stripspace](https://github.com/jamescherti/stripspace.el) 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.
-
-To enable **stripspace** and automatically delete trailing whitespace, add the following configuration to `~/.emacs.d/post-init.el`:
-```elisp
-;; 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
- :ensure t
- :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-clean nil)
-
- ;; 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-column t))
-```
-
-### Enhancing undo/redo
-
-The [undo-fu](https://codeberg.org/ideasman42/emacs-undo-fu) package is a lightweight wrapper around Emacs' built-in undo system, providing more convenient undo/redo functionality while preserving access to the full undo history. The [undo-fu-session](https://codeberg.org/ideasman42/emacs-undo-fu-session) package complements undo-fu by enabling the saving and restoration of undo history across Emacs sessions, even after restarting.
-
-The default undo system in Emacs has two main issues that undo-fu fixes:
-
-1. **Redo requires two steps**: To redo an action after undoing, you need to press a key twice, which can be annoying and inefficient.
-2. **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`:
-```emacs-lisp
-;; The undo-fu package is a lightweight wrapper around Emacs' built-in undo
-;; system, providing more convenient undo/redo functionality.
-(use-package undo-fu
- :ensure t
- :commands (undo-fu-only-undo
- undo-fu-only-redo
- undo-fu-only-redo-all
- undo-fu-disable-checkpoint)
- :config
- (global-unset-key (kbd "C-z"))
- (global-set-key (kbd "C-z") 'undo-fu-only-undo)
- (global-set-key (kbd "C-S-z") 'undo-fu-only-redo))
-
-;; The undo-fu-session package complements undo-fu by enabling the saving
-;; and restoration of undo history across Emacs sessions, even after restarting.
-(use-package undo-fu-session
- :ensure t
- :commands undo-fu-session-global-mode
- :hook (after-init . undo-fu-session-global-mode))
-```
-
### Configuring Vim keybindings using Evil?
Configuring Vim keybindings in Emacs can greatly enhance your editing efficiency if you are accustomed to Vim's modal editing style. Add the following to `~/.emacs.d/post-init.el` to set up [Evil mode](https://github.com/emacs-evil/evil):
@@ -809,7 +757,6 @@ Configuring Vim keybindings in Emacs can greatly enhance your editing efficiency
;; Vim emulation
(use-package evil
- :ensure t
:commands (evil-mode evil-define-key)
:hook (after-init . evil-mode)
@@ -850,19 +797,26 @@ Configuring Vim keybindings in Emacs can greatly enhance your editing efficiency
(use-package evil-collection
:after evil
- :ensure t
:init
;; It has to be defined before evil-colllection
(setq evil-collection-setup-minibuffer t)
:config
(evil-collection-init))
+
+;; The goto-chg package is useful with Evil to jump directly to the most recent
+;; edit location. This mirrors Vim's change navigation, allowing fast return to
+;; where text was last modified without relying on the jump list or search.
+;;
+;; The goto-chg commands are bound to g; and g,
+(use-package goto-chg
+ :commands (goto-last-change
+ goto-last-change-reverse))
```
You can also install the [vim-tab-bar](https://github.com/jamescherti/vim-tab-bar.el) 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, the *vim-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:
``` emacs-lisp
;; Give Emacs tab-bar a style similar to Vim's
(use-package vim-tab-bar
- :ensure t
:commands vim-tab-bar-mode
:hook (after-init . vim-tab-bar-mode))
```
@@ -880,7 +834,6 @@ The `evil-surround` package simplifies handling surrounding characters, such as
;; using S" or gS".
(use-package evil-surround
:after evil
- :ensure t
:commands global-evil-surround-mode
:custom
(evil-surround-pairs-alist
@@ -909,6 +862,506 @@ You can also add the following code to enable commenting and uncommenting by pre
(evil-define-key 'normal 'global (kbd "gc") 'my-evil-comment-or-uncomment))
```
+### Persisting and Restoring all buffers, windows/split, tab-bar, frames...
+
+The [easysession](https://github.com/jamescherti/easysession.el) package provides a comprehensive session management for Emacs. It is capable of persisting and restoring file-visiting buffers, indirect buffers (clones), buffer narrowing, Dired buffers, window configurations, the built-in tab-bar (including tabs, their buffers, and associated windows), as well as entire Emacs frames.
+
+With **easysession**, your Emacs setup is restored automatically when you restart. All files, Dired buffers, and window layouts come back as they were, so you can continue working right where you left off. While editing, you can also switch to another session, switch back, rename sessions, or delete them, giving you full control over multiple work environments.
+
+Easysession also supports extensions, enabling the restoration of Magit buffers and the scratch buffer. Custom extensions can also be created to extend its functionality.
+
+To configure **easysession**, add the following to `~/.emacs.d/post-init.el`:
+``` emacs-lisp
+;; 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
+ :commands (easysession-switch-to
+ easysession-save-as
+ easysession-save-mode
+ easysession-load-including-geometry)
+
+ :custom
+ (easysession-mode-line-misc-info t) ; Display the session in the modeline
+ (easysession-save-interval (* 10 60)) ; Save every 10 minutes
+
+ :init
+ ;; Key mappings
+ (global-set-key (kbd "C-c ss") #'easysession-save)
+ (global-set-key (kbd "C-c sl") #'easysession-switch-to)
+ (global-set-key (kbd "C-c sL") #'easysession-switch-to-and-restore-geometry)
+ (global-set-key (kbd "C-c sr") #'easysession-rename)
+ (global-set-key (kbd "C-c sR") #'easysession-reset)
+ (global-set-key (kbd "C-c sd") #'easysession-delete)
+
+ (if (fboundp 'easysession-setup)
+ ;; The `easysession-setup' function adds hooks:
+ ;; - To enable automatic session loading during `emacs-startup-hook', or
+ ;; `server-after-make-frame-hook' when running in daemon mode.
+ ;; - To automatically save the session at regular intervals, and when
+ ;; Emacs exits.
+ (easysession-setup)
+ ;; Legacy
+ ;; The depth 102 and 103 have been added to to `add-hook' to ensure that the
+ ;; session is loaded after all other packages. (Using 103/102 is
+ ;; particularly useful for those using minimal-emacs.d, where some
+ ;; optimizations restore `file-name-handler-alist` at depth 101 during
+ ;; `emacs-startup-hook`.)
+ (add-hook 'emacs-startup-hook #'easysession-load-including-geometry 102)
+ (add-hook 'emacs-startup-hook #'easysession-save-mode 103)))
+```
+
+### Configuring markdown-mode (e.g., README.md syntax)
+
+The [markdown-mode](https://github.com/jrblevin/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).
+
+To configure **markdown-mode**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+;; 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 up `markdown-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`, or `README.md` files. Files named `README.md` are specifically associated with `gfm-mode`, which is for GitHub Flavored Markdown syntax. The `markdown-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 in `markdown-mode-map` to invoke `markdown-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`:
+```elisp
+;; Automatically generate a table of contents when editing Markdown files
+(use-package markdown-toc
+ :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:
+
+- To **insert a table of contents** for the first time, run: `M-x markdown-toc-generate-toc`
+- To **update an existing table of contents**, run: `M-x markdown-toc-generate-or-refresh-toc`
+- To **remove 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)](https://www.jamescherti.com/emacs-markdown-table-of-contents-update-before-save/).
+
+### Code folding
+
+#### Kirigami: A unified interface for opening and closing folds
+
+The [kirigami](https://github.com/jamescherti/kirigami.el) package provides a unified method to fold and unfold text in Emacs across a diverse set of Emacs modes.
+
+**Supported modes include:** `outline-mode`, `outline-minor-mode`, `outline-indent-minor-mode`, `org-mode`, `markdown-mode`, `gfm-mode`, `vdiff-mode`, `vdiff-3way-mode`, `hide-ifdef-mode`, `vimish-fold-mode`, `TeX-fold-mode` (AUCTeX), `fold-this-mode`, `origami-mode`, `yafolding-mode`, `folding-mode`, `ts-fold-mode`, `treesit-fold-mode`, and `hs-minor-mode` (hideshow).
+
+With Kirigami, folding key bindings only need to be configured **once**. After that, the same keys work consistently across all supported major and minor modes, providing a unified and predictable experience for opening and closing folds. The available commands include:
+
+* `kirigami-open-fold`: Open the fold at point.
+* `kirigami-open-fold-rec`: Open the fold at point recursively.
+* `kirigami-close-fold`: Close the fold at point.
+* `kirigami-open-folds`: Open all folds in the buffer.
+* `kirigami-close-folds`: Close all folds in the buffer.
+* `kirigami-toggle-fold`: Toggle the fold at point.
+
+To configure **kirigami**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+(use-package kirigami
+ :commands (kirigami-open-fold
+ kirigami-open-fold-rec
+ kirigami-close-fold
+ kirigami-toggle-fold
+ kirigami-open-folds
+ kirigami-close-folds-except-current
+ kirigami-close-folds)
+
+ :bind
+ (("C-c z o" . kirigami-open-fold) ; Open fold at point
+ ("C-c z O" . kirigami-open-fold-rec) ; Open fold recursively
+ ("C-c z r" . kirigami-open-folds) ; Open all folds
+ ("C-c z c" . kirigami-close-fold) ; Close fold at point
+ ("C-c z m" . kirigami-close-folds) ; Close all folds
+ ("C-c z " . kirigami-toggle-fold))) ; Toggle fold at point
+
+;; Uncomment the following if you are an `evil-mode' user:
+;; (with-eval-after-load 'evil
+;; (define-key evil-normal-state-map "zo" 'kirigami-open-fold)
+;; (define-key evil-normal-state-map "zO" 'kirigami-open-fold-rec)
+;; (define-key evil-normal-state-map "zc" 'kirigami-close-fold)
+;; (define-key evil-normal-state-map "za" 'kirigami-toggle-fold)
+;; (define-key evil-normal-state-map "zr" 'kirigami-open-folds)
+;; (define-key evil-normal-state-map "zm" 'kirigami-close-folds))
+```
+
+With Kirigami, folding key bindings only need to be configured **once**. After that, the same keys work consistently across all supported major and minor modes, providing a unified and predictable experience for opening and closing folds.
+
+In addition to unified interface for opening and closing folds, the **kirigami** package:
+- **Enhances Visual Stability on Fold Opening and Closing:** Preserves the cursor's exact vertical position when expanding or collapsing headings, maintaining a constant relative distance between the cursor and the window start. This Kirigami enhancement avoids the disruptive window jump or forced re-centering commonly observed during bulk folding operations.
+- **Enhances outline:** Kirigami improves folding behavior in `outline-mode`, `outline-minor-mode`, `markdown-mode`, `gfm-mode`, and `org-mode`. It ensures that deep folds open reliably and permits closing folds even when the cursor is positioned within the content body. Additionally, it maintains window-start heading stability by automatically adjusting the scroll position to keep folded headings visible, preventing the context from disappearing when closing a fold that is partially scrolled off-screen.
+- **Hooks for Folding Actions:** Two hooks, `kirigami-pre-action-predicates` and `kirigami-post-action-functions`, let external code run before and after every folding operation. The pre-action hook runs just before a fold is opened or closed and can allow or block the action. The post-action hook runs once the change is complete and can be used to update UI elements or keep external packages in sync with the new folding state.
+
+#### outline-minor-mode and hs-minor-mode
+
+One of the modes that provide code folding is `outline-minor-mode` provides structured code folding in modes such as Emacs Lisp and Python, allowing users to collapse and expand sections based on headings or indentation levels. This feature enhances navigation and improves the management of large files with hierarchical structures.
+
+Alternatively, `hs-minor-mode` offers basic code folding for blocks defined by curly braces, functions, or other language-specific delimiters. However, for more flexible folding that supports multiple nested levels, `outline-minor-mode` is generally the preferred choice, as it enables finer control over section visibility in deeply structured code.
+
+For example, to enable `outline-minor-mode` in Emacs Lisp:
+
+``` 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
+ :ensure nil
+ :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) (ash 1 22)))
+ (value (vconcat (mapcar (lambda (c) (+ face-offset c)) " ▼"))))
+ (set-display-table-slot display-table 'selective-display value)
+ (setq buffer-display-table display-table))))))
+```
+
+#### outline-indent-minor-mode: Folding based on indentation levels
+
+For folding based on indentation levels, the **[outline-indent](https://github.com/jamescherti/outline-indent.el)** Emacs package provides a minor mode that enables folding according to the indentation structure:
+```elisp
+;; 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
+ :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))
+```
+
+
+
+#### treesit-fold
+
+It is also recommended to install [treesit-fold](https://github.com/emacs-tree-sitter/treesit-fold), which provides intelligent code folding by leveraging the structural understanding of the built-in tree-sitter parser. Unlike traditional folding methods that rely on regular expressions or indentation, treesit-fold uses the actual syntax tree of the code to accurately identify foldable regions such as functions, classes, comments, and documentation strings. This allows for faster and more precise folding behavior that respects the grammar of the programming language, ensuring that fold boundaries are always syntactically correct even in complex or nested code structures.
+```elisp
+;; Intelligent code folding by leveraging the structural understanding of the
+;; built-in tree-sitter parser. Unlike traditional folding methods that rely on
+;; regular expressions or indentation, treesit-fold uses the actual syntax tree
+;; of the code to accurately identify foldable regions such as functions,
+;; classes, comments, and documentation strings. This allows for faster and more
+;; precise folding behavior that respects the grammar of the programming
+;; language, ensuring that fold boundaries are always syntactically correct even
+;; in complex or nested code structures.
+(use-package treesit-fold
+ :commands (treesit-fold-close
+ treesit-fold-close-all
+ treesit-fold-open
+ treesit-fold-toggle
+ treesit-fold-open-all
+ treesit-fold-mode
+ global-treesit-fold-mode
+ treesit-fold-open-recursively
+ treesit-fold-line-comment-mode)
+
+ :custom
+ (treesit-fold-line-count-show t)
+ (treesit-fold-line-count-format " ▼")
+
+ :config
+ (set-face-attribute 'treesit-fold-replacement-face nil
+ :foreground "#808080"
+ :box nil
+ :weight 'bold))
+```
+
+The `treesit-fold` mode can be enabled using `treesit-fold-mode` or a hook such as:
+```elisp
+(add-hook 'python-ts-mode-hook #'treesit-fold-mode)
+```
+
+### Asynchronous code formatting without cursor disruption
+
+[Apheleia](https://github.com/radian-software/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 an `after-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 configure **apheleia**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+;; 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
+ :commands (apheleia-mode
+ apheleia-global-mode)
+ :hook ((prog-mode . apheleia-mode)))
+```
+
+### Context-aware 'go to definition' functionality for 50+ programming languages
+
+The [dumb-jump](https://github.com/jacktasia/dumb-jump) package provides context-aware 'go to definition' functionality for 50+ programming languages without requiring a language server. It works by using simple heuristics and regular expression searches to locate the definitions of functions, variables, and symbols across project files.
+
+Unlike more sophisticated language-aware tools (e.g., eglot or lsp-mode), `dumb-jump' does not parse code semantically, which makes it lightweight and fast, but sometimes less precise. It integrates with popular navigation packages like `xref', allowing users to jump to definitions or references.
+
+To configure **dumb-jump**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+(use-package dumb-jump
+ :commands dumb-jump-xref-activate
+ :init
+ ;; Register `dumb-jump' as an xref backend so it integrates with
+ ;; `xref-find-definitions'. A priority of 90 ensures it is used only when no
+ ;; more specific backend is available.
+ (add-hook 'xref-backend-functions #'dumb-jump-xref-activate 90)
+
+ (setq dumb-jump-aggressive nil)
+ ;; (setq dumb-jump-quiet t)
+
+ ;; Number of seconds a rg/grep/find command can take before being warned to
+ ;; use ag and config.
+ (setq dumb-jump-max-find-time 3)
+
+ ;; Use `completing-read' so that selection of jump targets integrates with the
+ ;; active completion framework (e.g., Vertico, Ivy, Helm, Icomplete),
+ ;; providing a consistent minibuffer-based interface whenever multiple
+ ;; definitions are found.
+ (setq dumb-jump-selector 'completing-read)
+
+ ;; If ripgrep is available, force `dumb-jump' to use it because it is
+ ;; significantly faster and more accurate than the default searchers (grep,
+ ;; ag, etc.).
+ (when (executable-find "rg")
+ (setq dumb-jump-force-searcher 'rg)
+ (setq dumb-jump-prefer-searcher 'rg)))
+```
+
+### Efficient template expansion with snippets
+
+The [yasnippet](https://github.com/joaotavora/yasnippet) 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 as `if`. 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.
+
+The [yasnippet-snippets](https://github.com/AndreaCrotti/yasnippet-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 tool [ultyas](https://github.com/jamescherti/ultyas))
+
+
+```elisp
+;; The official collection of snippets for yasnippet.
+(use-package yasnippet-snippets
+ :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
+ :commands (yas-minor-mode
+ yas-global-mode)
+
+ :hook
+ (after-init . yas-global-mode)
+
+ :custom
+ (yas-also-auto-indent-first-line t) ; Indent first line of snippet
+ (yas-also-indent-empty-lines t)
+ (yas-snippet-revival nil) ; Setting this to t causes issues with undo
+ (yas-wrap-around-region nil) ; 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-verbosity 0))
+```
+
+### Spell checker
+
+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.
+
+To configure **flyspell**, add the following to `~/.emacs.d/post-init.el`:
+``` emacs-lisp
+;; 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
+ :ensure nil
+ :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
+ :ensure nil
+ :commands flyspell-mode
+ :hook
+ (; (prog-mode . flyspell-prog-mode)
+ (text-mode . (lambda()
+ (if (or (derived-mode-p 'yaml-mode)
+ (derived-mode-p 'yaml-ts-mode)
+ (derived-mode-p 'ansible-mode))
+ (flyspell-prog-mode 1)
+ (flyspell-mode 1)))))
+ :config
+ ;; Remove strings from Flyspell
+ (setq flyspell-prog-text-faces (delq 'font-lock-string-face
+ flyspell-prog-text-faces))
+
+ ;; Remove doc from Flyspell
+ (setq flyspell-prog-text-faces (delq 'font-lock-doc-face
+ flyspell-prog-text-faces)))
+```
+
+### Automatic removal of trailing whitespace on save
+
+**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.
+
+The [stripspace](https://github.com/jamescherti/stripspace.el) 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.
+
+To enable **stripspace** and automatically delete trailing whitespace, add the following configuration to `~/.emacs.d/post-init.el`:
+```elisp
+;; 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
+ :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-clean nil)
+
+ ;; 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-column t))
+```
+
+### Highlighting uncommitted changes in the buffer margin (e.g., Git changes)
+
+The [diff-hl](https://github.com/dgutov/diff-hl) package highlights uncommitted changes in the window margin, enabling navigation between them. Also known as source control gutter indicators, it displays added, modified, and deleted lines in real time. In Git-controlled buffers, changes can be staged and unstaged directly, providing a clear view of version-control changes without running `git diff`. By default, the module does not start `diff-hl-mode` automatically.
+
+
+
+To configure the *diff-hl* package, add the following to your `~/.emacs.d/post-init.el`:
+```elisp
+(use-package diff-hl
+ :commands (diff-hl-mode
+ global-diff-hl-mode)
+ :hook (prog-mode . diff-hl-mode)
+ :init
+ (setq diff-hl-flydiff-delay 0.4) ; Faster
+ (setq diff-hl-show-staged-changes nil) ; Realtime feedback
+ (setq diff-hl-update-async t) ; Do not block Emacs
+ (setq diff-hl-global-modes '(not pdf-view-mode image-mode)))
+```
+
+### Configuring org-mode
+
+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 configure **org-mode**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+;; 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-package org
+ :commands (org-mode org-version)
+ :mode
+ ("\\.org\\'" . org-mode)
+ :custom
+ (org-hide-leading-stars t)
+ (org-startup-indented t)
+ (org-adapt-indentation nil)
+ (org-edit-src-content-indentation 0)
+ ;; (org-fontify-done-headline t)
+ ;; (org-fontify-todo-headline t)
+ ;; (org-fontify-whole-heading-line t)
+ ;; (org-fontify-quote-and-verse-blocks t)
+ (org-startup-truncated t))
+```
+
+The `org-appear` package temporarily reveals normally hidden elements (such as emphasis markers, links, or entities) when the cursor enters them, and hides them again when the cursor leaves. To configure **org-appear**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+(use-package org-appear
+ :commands org-appear-mode
+ :hook (org-mode . org-appear-mode))
+```
+
### Configuring LSP Servers with Eglot (built-in)
To set up Language Server Protocol (LSP) servers using Eglot, you can configure it, add the following to `~/.emacs.d/post-init.el`:
@@ -947,143 +1400,6 @@ Here is an example of how to configure Eglot to enable or disable certain option
:rope_autoimport (:enabled :json-false)))))
```
-### Persisting and Restoring all buffers, windows/split, tab-bar, frames...
-
-The [easysession](https://github.com/jamescherti/easysession.el) Emacs package is a session manager for Emacs that can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, windows/splits, the built-in tab-bar (including tabs, their buffers, and windows), and Emacs frames. It offers a convenient and effortless way to manage Emacs editing sessions and utilizes built-in Emacs functions to persist and restore frames.
-
-To configure **easysession**, add the following to `~/.emacs.d/post-init.el`:
-``` emacs-lisp
-;; 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
- :ensure t
- :commands (easysession-switch-to
- easysession-save-as
- easysession-save-mode
- easysession-load-including-geometry)
-
- :custom
- (easysession-mode-line-misc-info t) ; Display the session in the modeline
- (easysession-save-interval (* 10 60)) ; Save every 10 minutes
-
- :init
- ;; Key mappings:
- ;; C-c l for switching sessions
- ;; and C-c s for saving the current session
- (global-set-key (kbd "C-c l") 'easysession-switch-to)
- (global-set-key (kbd "C-c s") 'easysession-save-as)
-
- ;; The depth 102 and 103 have been added to to `add-hook' to ensure that the
- ;; session is loaded after all other packages. (Using 103/102 is particularly
- ;; useful for those using minimal-emacs.d, where some optimizations restore
- ;; `file-name-handler-alist` at depth 101 during `emacs-startup-hook`.)
- (add-hook 'emacs-startup-hook #'easysession-load-including-geometry 102)
- (add-hook 'emacs-startup-hook #'easysession-save-mode 103))
-```
-
-### Configuring org-mode
-
-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 configure **org-mode**, add the following to `~/.emacs.d/post-init.el`:
-```elisp
-;; 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-package org
- :ensure t
- :commands (org-mode org-version)
- :mode
- ("\\.org\\'" . org-mode)
- :custom
- (org-hide-leading-stars t)
- (org-startup-indented t)
- (org-adapt-indentation nil)
- (org-edit-src-content-indentation 0)
- ;; (org-fontify-done-headline t)
- ;; (org-fontify-todo-headline t)
- ;; (org-fontify-whole-heading-line t)
- ;; (org-fontify-quote-and-verse-blocks t)
- (org-startup-truncated t))
-```
-
-### Configuring markdown-mode (e.g., README.md syntax)
-
-The [markdown-mode](https://github.com/jrblevin/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).
-
-To configure **markdown-mode**, add the following to `~/.emacs.d/post-init.el`:
-```elisp
-;; 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 up `markdown-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`, or `README.md` files. Files named `README.md` are specifically associated with `gfm-mode`, which is for GitHub Flavored Markdown syntax. The `markdown-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 in `markdown-mode-map` to invoke `markdown-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`:
-```elisp
-;; Automatically generate a table of contents when editing Markdown files
-(use-package markdown-toc
- :ensure t
- :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:
-
-- To **insert a table of contents** for the first time, run: `M-x markdown-toc-generate-toc`
-- To **update an existing table of contents**, run: `M-x markdown-toc-generate-or-refresh-toc`
-- To **remove 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)](https://www.jamescherti.com/emacs-markdown-table-of-contents-update-before-save/).
-
-### Tree-sitter Integration (Better Syntax Highlighting)
-
-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 the [treesit-auto](https://github.com/renzmann/treesit-auto) package. Setting `treesit-auto-add-to-auto-mode-alist` to `'all` ensures that all available Tree-sitter modes are automatically activated for their corresponding file types. Enabling `global-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`:
-
-```elisp
-;; 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
- :ensure t
- :custom
- (treesit-auto-install 'prompt)
- :config
- (treesit-auto-add-to-auto-mode-alist 'all)
- (global-treesit-auto-mode))
-```
-
### Auto upgrade Emacs packages
The [auto-package-update](https://github.com/rranelli/auto-package-update.el) automates the process of updating installed packages managed by *package.el*. Instead of requiring users to manually invoke `package-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.
@@ -1093,7 +1409,6 @@ To configure **auto-package-update**, add the following to `~/.emacs.d/post-init
```elisp
;; This automates the process of updating installed packages
(use-package auto-package-update
- :ensure t
:custom
;; Set the number of days between automatic updates.
;; Here, packages will only be updated if at least 7 days have passed
@@ -1138,7 +1453,6 @@ To configure **buffer-terminator**, add the following to `~/.emacs.d/post-init.e
```emacs-lisp
(use-package buffer-terminator
- :ensure t
:custom
;; Enable/Disable verbose mode to log buffer cleanup events
(buffer-terminator-verbose nil)
@@ -1170,7 +1484,6 @@ To configure **treemacs**, add the following to `~/.emacs.d/post-init.el`:
;; in the left window, providing a persistent view of files, projects, and
;; other elements.
(use-package treemacs
- :ensure t
:commands (treemacs
treemacs-select-window
treemacs-delete-other-windows
@@ -1270,191 +1583,17 @@ To configure **treemacs**, add the following to `~/.emacs.d/post-init.el`:
;; (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)
```
-### Inhibit the mouse
-
-The [inhibit-mouse](https://github.com/jamescherti/inhibit-mouse.el) package disables mouse input in Emacs.
-
-This package is useful for users who want to disable the mouse to:
-- Prevent accidental clicks or cursor movements that may unexpectedly change the cursor position.
-- Reinforce a keyboard-centric workflow by discouraging reliance on the mouse for navigation.
-
-To configure **inhibit-mouse**, add the following to `~/.emacs.d/post-init.el`:
-```emacs-lisp
-;; 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
- :ensure t
- :config
- (if (daemonp)
- (add-hook 'server-after-make-frame-hook #'inhibit-mouse-mode)
- (inhibit-mouse-mode 1)))
-```
-
-NOTE: `inhibit-mouse-mode` allows users to disable and re-enable mouse functionality, giving them the flexibility to use the mouse when needed.
-
-### Spell checker
-
-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.
-
-To configure **flyspell**, add the following to `~/.emacs.d/post-init.el`:
-``` emacs-lisp
-;; 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
- :ensure nil
- :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
- :ensure nil
- :commands flyspell-mode
- :hook
- (; (prog-mode . flyspell-prog-mode)
- (text-mode . (lambda()
- (if (or (derived-mode-p 'yaml-mode)
- (derived-mode-p 'yaml-ts-mode)
- (derived-mode-p 'ansible-mode))
- (flyspell-prog-mode 1)
- (flyspell-mode 1)))))
- :config
- ;; Remove strings from Flyspell
- (setq flyspell-prog-text-faces (delq 'font-lock-string-face
- flyspell-prog-text-faces))
-
- ;; Remove doc from Flyspell
- (setq flyspell-prog-text-faces (delq 'font-lock-doc-face
- flyspell-prog-text-faces)))
-```
-
-### Efficient jumps for enhanced productivity
-
-The [avy](https://github.com/abo-abo/avy) package is a navigation framework designed for jumping directly to any visible text on the screen with minimal keystrokes. The primary benefit of *avy* 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 command `avy-goto-char` or `avy-goto-char-2`, the user inputs a target character, and `avy` 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 configure **avy**, add the following to `~/.emacs.d/post-init.el`:
-```elisp
-(use-package avy
- :ensure t
- :commands (avy-goto-char
- avy-goto-char-2
- avy-next)
- :init
- (global-set-key (kbd "C-'") 'avy-goto-char-2))
-```
-
-The author recommends using `avy-goto-char-2` (typically bound to `C-'`). 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, and *avy* instantly transports the cursor to that specific occurrence.
-
-### Asynchronous code formatting without cursor disruption
-
-[Apheleia](https://github.com/radian-software/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 an `after-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 configure **apheleia**, add the following to `~/.emacs.d/post-init.el`:
-```elisp
-;; 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
- :ensure t
- :commands (apheleia-mode
- apheleia-global-mode)
- :hook ((prog-mode . apheleia-mode)))
-```
-
-### Efficient template expansion with snippets
-
-The [yasnippet](https://github.com/joaotavora/yasnippet) 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 as `if`. 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.
-
-The [yasnippet-snippets](https://github.com/AndreaCrotti/yasnippet-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 tool [ultyas](https://github.com/jamescherti/ultyas))
-
-
-```elisp
-;; The official collection of snippets for yasnippet.
-(use-package yasnippet-snippets
- :ensure t
- :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
- :ensure t
- :commands (yas-minor-mode
- yas-global-mode)
-
- :hook
- (after-init . yas-global-mode)
-
- :custom
- (yas-also-auto-indent-first-line t) ; Indent first line of snippet
- (yas-also-indent-empty-lines t)
- (yas-snippet-revival nil) ; Setting this to t causes issues with undo
- (yas-wrap-around-region nil) ; 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-verbosity 0))
-```
-
### A better Emacs *help* buffer
[Helpful](https://github.com/Wilfred/helpful) is an alternative to the built-in Emacs help that provides much more contextual information.
@@ -1464,7 +1603,6 @@ To configure **helpful**, 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
- :ensure t
:commands (helpful-callable
helpful-variable
helpful-key
@@ -1481,20 +1619,69 @@ To configure **helpful**, add the following to `~/.emacs.d/post-init.el`:
(helpful-max-buffers 7))
```
+### Efficient jumps
+
+The [avy](https://github.com/abo-abo/avy) package is a navigation framework designed for jumping directly to any visible text on the screen with minimal keystrokes. The primary benefit of *avy* 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 command `avy-goto-char` or `avy-goto-char-2`, the user inputs a target character, and `avy` 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 configure **avy**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+(use-package avy
+ :commands (avy-goto-char
+ avy-goto-char-2
+ avy-next)
+ :init
+ (global-set-key (kbd "C-'") 'avy-goto-char-2))
+```
+
+The author recommends using `avy-goto-char-2` (typically bound to `C-'`). 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, and *avy* instantly transports the cursor to that specific occurrence.
+
+### Renaming and deleting files
+
+This [bufferfile.el](https://github.com/jamescherti/bufferfile.el) package provides helper functions to delete, rename, or copy buffer files:
+- `bufferfile-rename`: Renames the file visited by the current buffer, ensures that the destination directory exists, and updates the buffer name for all associated buffers, including clones/indirect buffers. It also ensures that buffer-local features referencing the file, such as Eglot or dired buffers, are correctly updated to reflect the new file name.
+- `bufferfile-delete`: Delete the file associated with a buffer and kill all buffers visiting the file, including clones/indirect buffers.
+- `bufferfile-copy`: Ensures that the destination directory exists and copies the file visited by the current buffer to a new file.
+
+The functions above also ensures that any modified buffers are saved prior to executing operations like renaming, deleting, or copying.
+
+To configure **bufferfile**, add the following to `~/.emacs.d/post-init.el`:
+```elisp
+(use-package bufferfile
+ :commands (bufferfile-copy
+ bufferfile-rename
+ bufferfile-delete)
+ :custom
+ ;; If non-nil, display messages during file renaming operations
+ (bufferfile-verbose nil)
+
+ ;; If non-nil, enable using version control (VC) when available
+ (bufferfile-use-vc nil)
+
+ ;; Specifies the action taken after deleting a file and killing its buffer.
+ (bufferfile-delete-switch-to 'parent-directory))
+```
+
+**The *bufferfile* package overcomes limitations in Emacs' built-in functions:**
+
+* **Emacs built-in renaming:** While indirect buffers continue to reference the correct file path, their buffer names can become outdated.
+* **Emacs built-in deleting:** Indirect buffers are not automatically removed when the base buffer or another indirect buffer is deleted.
+
+**The bufferfile package resolves these issues** by updating buffer names when a file is renamed and removing all related buffers, including indirect ones, when a file is deleted.
+
### Enhancing the Elisp development experience
To enhance the Elisp development experience, add the following to `~/.emacs.d/post-init.el`:
```emacs-lisp
;; Enables automatic indentation of code while typing
(use-package aggressive-indent
- :ensure t
:commands aggressive-indent-mode
:hook
(emacs-lisp-mode . aggressive-indent-mode))
;; Highlights function and variable definitions in Emacs Lisp mode
(use-package highlight-defined
- :ensure t
:commands highlight-defined-mode
:hook
(emacs-lisp-mode . highlight-defined-mode))
@@ -1504,7 +1691,6 @@ Other optional packages that may be useful include:
```emacs-lisp
;; Prevent parenthesis imbalance
(use-package paredit
- :ensure t
:commands paredit-mode
:hook
(emacs-lisp-mode . paredit-mode)
@@ -1514,14 +1700,12 @@ Other optional packages that may be useful include:
;; 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
- :ensure t
:commands (page-break-lines-mode
global-page-break-lines-mode)
:hook
@@ -1530,7 +1714,6 @@ Other optional packages that may be useful include:
;; Provides functions to find references to functions, macros, variables,
;; special forms, and symbols in Emacs Lisp
(use-package elisp-refs
- :ensure t
:commands (elisp-refs-function
elisp-refs-macro
elisp-refs-variable
@@ -1538,6 +1721,30 @@ Other optional packages that may be useful include:
elisp-refs-symbol))
```
+### Inhibiting the mouse
+
+The [inhibit-mouse](https://github.com/jamescherti/inhibit-mouse.el) package disables mouse input in Emacs.
+
+This package is useful for users who want to disable the mouse to:
+- Prevent accidental clicks or cursor movements that may unexpectedly change the cursor position.
+- Reinforce a keyboard-centric workflow by discouraging reliance on the mouse for navigation.
+
+To configure **inhibit-mouse**, add the following to `~/.emacs.d/post-init.el`:
+```emacs-lisp
+;; 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
+ :config
+ (if (daemonp)
+ (add-hook 'server-after-make-frame-hook #'inhibit-mouse-mode)
+ (inhibit-mouse-mode 1)))
+```
+
+NOTE: `inhibit-mouse-mode` allows users to disable and re-enable mouse functionality, giving them the flexibility to use the mouse when needed.
+
### Showing the tab-bar
Configure the `tab-bar-show` variable to 1 to display the tab bar exclusively when multiple tabs are open:
@@ -1547,6 +1754,31 @@ Configure the `tab-bar-show` variable to 1 to display the tab bar exclusively wh
(setopt tab-bar-show 1)
```
+### Offline Dictionary
+
+The [quick-sdcv.el](https://github.com/jamescherti/quick-sdcv.el) package serves as a lightweight Emacs interface for the `sdcv` command-line interface, which is the console version of the StarDict dictionary application.
+
+This package enables Emacs to function as an offline dictionary.
+
+To enable *quick-sdcv*, add the following to your `~/.emacs.d/post-init.el`:
+
+```emacs-lisp
+(use-package quick-sdcv
+ :custom
+ (quick-sdcv-unique-buffers t)
+ (quick-sdcv-dictionary-prefix-symbol "►")
+ (quick-sdcv-ellipsis " ▼"))
+```
+
+Here are the main interactive functions:
+- `M-x quick-sdcv-search-at-point`: Searches the word around the cursor and displays the result in a buffer.
+- `M-x quick-sdcv-search-input`: Searches the input word and displays the result in a buffer.
+
+Prerequisite:
+
+- The [sdcv](https://github.com/Dushistov/sdcv) command. (On Linux systems, it can usually be installed by using the system's package manager to install the `sdcv` package.)
+- Download dictionaries from: http://download.huzheng.org/ . Once the dictionaries are downloaded, extract them into `/usr/share/stardict/dic/`, or configure the variable `quick-sdcv-dictionary-data-dir` in the Emacs configuration to specify an alternative dictionary path.
+
### Changing the Default Font
To customize the default font, add the following expression to your `~/.emacs.d/post-init.el`:
@@ -1566,7 +1798,7 @@ On Linux, you can display a comprehensive list of all installed font families by
fc-list : family | sed 's/,/\n/g' | sort -u
```
-### Persist Text Scale
+### Persisting and Restoring Text Scale
The [persist-text-scale](https://github.com/jamescherti/persist-text-scale.el) Emacs package provides `persist-text-scale-mode`, which ensures that all adjustments made with `text-scale-increase` and `text-scale-decrease` are persisted and restored across sessions. As a result, the text size in each buffer remains consistent, even after restarting Emacs.
@@ -1589,6 +1821,57 @@ To configure the *persist-text-scale* package, add the following to your `~/.ema
(text-scale-mode-step 1.07))
```
+### A Faster Terminal Emulator
+
+**NOTE:** The vterm package requires external system dependencies, specifically `cmake` (>= 3.11), `libtool-bin`, and `libvterm`. Because it contains a C component, Emacs will prompt you to compile the module the first time you run it. Ensure your environment variables are correctly configured so Emacs can locate your C compiler and build tools.
+
+The [vterm](https://github.com/akermu/emacs-libvterm) package provides is an Emacs terminal emulator that provides a fully interactive shell experience within Emacs, supporting features such as color, cursor movement, and advanced terminal capabilities.
+
+Unlike standard Emacs terminal modes, `vterm` utilizes the libvterm C library for high-performance emulation. This ensures accurate terminal behavior when running shell programs, text-based applications, and REPLs.
+
+To configure the *vterm* package, add the following to your `~/.emacs.d/post-init.el`:
+```elisp
+;; `vterm' is an Emacs terminal emulator that provides a fully interactive shell
+;; experience within Emacs, supporting features such as color, cursor movement,
+;; and advanced terminal capabilities. Unlike standard Emacs terminal modes,
+;; `vterm' utilizes the libvterm C library for high-performance emulation. This
+;; ensures accurate terminal behavior when running shell programs, text-based
+;; applications, and REPLs.
+(use-package vterm
+ :if (bound-and-true-p module-file-suffix)
+ :commands (vterm
+ vterm-send-string
+ vterm-send-return
+ vterm-send-key
+ vterm-module-compile)
+
+ :preface
+ (when noninteractive
+ ;; vterm unnecessarily triggers compilation of vterm-module.so upon loading.
+ ;; This prevents that during byte-compilation (`use-package' eagerly loads
+ ;; packages when compiling).
+ (advice-add #'vterm-module-compile :override #'ignore))
+
+ (defun my-vterm--setup ()
+ ;; Hide the mode-line
+ (setq mode-line-format nil)
+
+ ;; Inhibit early horizontal scrolling
+ (setq-local hscroll-margin 0)
+
+ ;; Suppress prompts for terminating active processes when closing vterm
+ (setq-local confirm-kill-processes nil))
+
+ :init
+ (add-hook 'vterm-mode-hook #'my-vterm--setup)
+
+ (setq vterm-timer-delay 0.05) ; Faster vterm
+ (setq vterm-kill-buffer-on-exit t)
+ (setq vterm-max-scrollback 5000))
+```
+
+The `vterm` terminal emulator can be started with `M-x vterm`.
+
### Loading the custom.el file
**NOTE:** The author advises against loading `custom.el`. Users are instead encouraged to define their configuration programmatically in files such as `post-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.
@@ -1609,6 +1892,15 @@ In Emacs, customization variables modified via the UI (e.g., `M-x customize`) ar
2. You can also add the following to `~/.emacs.d/post-init.el`:
```emacs-lisp
+;;; Enable automatic insertion and management of matching pairs of characters
+;;; (e.g., (), {}, "") globally using `electric-pair-mode'.
+(use-package elec-pair
+ :ensure nil
+ :commands (electric-pair-mode
+ electric-pair-local-mode
+ electric-pair-delete-pair)
+ :hook (after-init . electric-pair-mode))
+
;; Allow Emacs to upgrade built-in packages, such as Org mode
(setq package-install-upgrade-built-in t)
@@ -1658,6 +1950,21 @@ In Emacs, customization variables modified via the UI (e.g., `M-x customize`) ar
;; Track changes in the window configuration, allowing undoing actions such as
;; closing windows.
+(setq winner-boring-buffers '("*Completions*"
+ "*Minibuf-0*"
+ "*Minibuf-1*"
+ "*Minibuf-2*"
+ "*Minibuf-3*"
+ "*Minibuf-4*"
+ "*Compile-Log*"
+ "*inferior-lisp*"
+ "*Fuzzy Completions*"
+ "*Apropos*"
+ "*Help*"
+ "*cvs*"
+ "*Buffer List*"
+ "*Ibuffer*"
+ "*esh command on file*"))
(add-hook 'after-init-hook #'winner-mode)
(use-package uniquify
@@ -1740,7 +2047,159 @@ It is also recommended to read the following articles:
- [Maintaining proper indentation in indentation-sensitive programming languages](https://www.jamescherti.com/elisp-code-and-emacs-packages-for-maintaining-proper-indentation-in-indentation-sensitive-languages-such-as-python-or-yaml/)
-## Customizations: pre-early-init.el
+### File types (Yaml, Dockerfile, Lua, Jinja2, CSV, Vimrc...)
+
+The following additional file types may be enabled to extend language support beyond the core set.
+
+These modes are optional and can be added selectively to `~/.emacs.d/post-init.el`, depending on the languages and formats commonly encountered in a given workflow.
+```elisp
+;; Support for Git files (.gitconfig, .gitignore, .gitattributes...)
+(use-package git-modes
+ :commands (gitattributes-mode
+ gitconfig-mode
+ gitignore-mode)
+ :mode (("/\\.gitignore\\'" . gitignore-mode)
+ ("/info/exclude\\'" . gitignore-mode)
+ ("/git/ignore\\'" . gitignore-mode)
+ ("/.gitignore_global\\'" . gitignore-mode) ; jc-dotfiles
+
+ ("/\\.gitconfig\\'" . gitconfig-mode)
+ ("/\\.git/config\\'" . gitconfig-mode)
+ ("/modules/.*/config\\'" . gitconfig-mode)
+ ("/git/config\\'" . gitconfig-mode)
+ ("/\\.gitmodules\\'" . gitconfig-mode)
+ ("/etc/gitconfig\\'" . gitconfig-mode)
+
+ ("/\\.gitattributes\\'" . gitattributes-mode)
+ ("/info/attributes\\'" . gitattributes-mode)
+ ("/git/attributes\\'" . gitattributes-mode)))
+
+;; Configure built-in sgml-mode to automatically enable
+;; `sgml-electric-tag-pair-mode' in `html-mode' and `mhtml-mode', providing
+;; automatic insertion of matching closing tags.
+(use-package sgml-mode
+ :ensure nil
+ :commands (sgml-mode sgml-electric-tag-pair-mode)
+ :hook ((html-mode mhtml-mode) . sgml-electric-tag-pair-mode))
+
+;; Support for YAML files.
+;;
+;; NOTE: Prefer the tree-sitter-based yaml-ts-mode over yaml-mode when
+;; available, as it provides more accurate syntax parsing and enhanced editing
+;; features.
+(use-package yaml-mode
+ :commands yaml-mode
+ :mode (("\\.yaml\\'" . yaml-mode)
+ ("\\.yml\\'" . yaml-mode)))
+
+;; Support for Dockerfile files.
+;;
+;; NOTE: Prefer the tree-sitter-based dockerfile-ts-mode over dockerfile-mode
+;; when available, as it provides more accurate syntax parsing and enhanced
+;; editing features.
+(use-package dockerfile-mode
+ :commands dockerfile-mode
+ :mode ("Dockerfile\\'" . dockerfile-mode))
+
+;; Support for Gnuplot files
+(use-package gnuplot
+ :commands gnuplot-mode
+ :mode ("\\.gp\\'" . gnuplot-mode))
+
+;; Support for *.lua files.
+;;
+;; Prefer the tree-sitter-based lua-ts-mode over lua-mode when available, as it
+;; provides more accurate syntax parsing and enhanced editing features.
+(use-package lua-mode
+ :commands lua-mode
+ :mode ("\\.lua\\'" . lua-mode))
+
+;; Jinja2 template support for files commonly used in configuration management
+;; systems and web frameworks. This mode enables syntax highlighting and basic
+;; editing facilities for templates written using the Jinja2 templating
+;; language.
+(use-package jinja2-mode
+ :commands jinja2-mode
+ :mode ("\\.j2\\'" . jinja2-mode))
+
+;; CSV file support with automatic column alignment. This configuration enables
+;; csv-align-mode whenever a CSV file is opened, improving readability by
+;; keeping columns visually aligned according to a configurable maximum width
+;; and a set of recognized field separators.
+(use-package csv-mode
+ :commands (csv-mode
+ csv-align-mode
+ csv-guess-set-separator)
+ :mode ("\\.csv\\'" . csv-mode)
+ :hook ((csv-mode . csv-align-mode)
+ (csv-mode . csv-guess-set-separator))
+ :custom
+ (csv-align-max-width 100)
+ (csv-separators '("," ";" " " "|" "\t")))
+
+;; Support for Go
+;;
+;; NOTE: Prefer the tree-sitter-based go-ts-mode over go-mode
+;; when available, as it provides more accurate syntax parsing and enhanced
+;; editing features.
+(use-package go-mode
+ :commands go-mode
+ :mode ("\\.go\\'" . go-mode))
+
+;; Support for Rust
+(use-package rust-mode
+ :commands rust-mode
+ :mode ("\\.rs\\'" . rust-mode)
+ :custom
+ (rust-indent-offset 2))
+
+;; Major mode for editing crontab files
+(use-package crontab-mode
+ :commands crontab-mode
+ :mode ("/crontab\\(\\.X*[[:alnum:]]+\\)?\\'" . crontab-mode))
+
+;; Major mode for editing Nginx configuration files
+(use-package nginx-mode
+ :commands nginx-mode
+ :mode (("nginx\\.conf\\'" . nginx-mode)
+ ("/nginx/.+\\.conf\\'" . nginx-mode)))
+
+;; Major mode for HashiCorp Configuration Language (HCL) files
+(use-package hcl-mode
+ :commands hcl-mode
+ :mode ("\\.hcl\\'" . hcl-mode))
+
+;; Major mode for Nix expression language files
+(use-package nix-mode
+ :commands nix-mode
+ :mode ("\\.nix\\'" . nix-mode))
+
+;; Major mode for editing Fish shell scripts
+(use-package fish-mode
+ :commands fish-mode
+ :mode ("\\.fish\\'" . fish-mode))
+
+;; Vim configuration file support. This mode provides syntax highlighting and
+;; editing support for various Vim configuration files, including vimrc, gvimrc,
+;; local overrides, and project-specific configuration files.
+(use-package vimrc-mode
+ :commands vimrc-mode
+ :mode ("\\.vim\\(rc\\)?\\'" . vimrc-mode))
+
+;; Support for Jenkinsfile files
+(use-package jenkinsfile-mode
+ :commands jenkinsfile-mode
+ :mode ("Jenkinsfile\\'" . jenkinsfile-mode))
+
+;; Support for Haskell
+;; (use-package haskell-mode
+;; :commands haskell-mode
+;; :mode ("\\.hs\\'" . haskell-mode))
+```
+
+## Customizations: Before init (File: pre-init.el)
+
+NOTE: Using `straight.el` or Elpaca is **optional**. Emacs already has a built-in package manager.
### Configuring straight.el
@@ -1764,6 +2223,8 @@ The `straight.el` package is a declarative package manager for Emacs that aims t
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
+
+(setq straight-use-package-by-default t)
```
### Configuring Elpaca (package manager)
@@ -1822,17 +2283,29 @@ And [add the Elpaca bootstrap code](https://github.com/progfolio/elpaca?tab=read
(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))
+;; Enable 'elpaca-no-symlink-mode' on Windows, as symlink creation
+;; often fails without Administrator privileges or Developer Mode.
+(when (eq system-type 'windows-nt)
+ (elpaca-no-symlink-mode 1))
+
+;; Install use-package support
+(elpaca elpaca-use-package
+ ;; Enable use-package :ensure support for Elpaca.
+ (elpaca-use-package-mode))
```
## Frequently asked questions
+### How to debug my configuration?
+
+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:
+
+```elisp
+(setq debug-on-error t)
+```
+
+Enabling `debug-on-error` at this stage allows you to catch errors that might otherwise cause Emacs to fail silently or behave unpredictably.
+
### Customizing Scroll Recentering
By default, minimal-emacs.d sets `scroll-conservatively` to `20`:
@@ -1877,6 +2350,46 @@ Add the following to your `~/.emacs.d/pre-early-init.el` file:
(Alternatively, you may use the built-in `M-x emacs-init-time` command to obtain the startup duration. However, `emacs-init-time` does not account for the portion of the startup process that occurs after `after-init-time`.)
+### Optimization: Disabling `site-run-file` and `inhibit-default-init`
+
+Emacs performs a multi-stage initialization sequence that may include system-level configuration before and after user configuration. For a minimal and fully deterministic setup, these stages can be disabled.
+
+Emacs can load two optional system-wide files:
+
+1. **`site-start.el`**: Executed before the user configuration. Controlled by the variable `site-run-file`.
+2. **`default.el`**: Executed after the user configuration. Controlled by the variable `inhibit-default-init`.
+
+Both files are typically maintained by operating systems or system administrators to provide global defaults, package path adjustments, or distribution-specific behavior.
+
+#### Disable `site-start.el` (Pre-Initialization Stage)
+
+By default, Emacs evaluates `site-start.el` early in the startup process. While useful in managed environments, this introduces two disadvantages for a minimal configuration:
+
+* **Startup overhead**: Additional I/O and evaluation during the earliest phase of initialization.
+* **Loss of determinism**: External configuration may modify variables, alter `load-path`, or introduce behavior that differs across machines.
+
+To ensure a clean and reproducible startup, disable this stage in `~/.emacs.d/pre-early-init.el`:
+
+```elisp
+(setq site-run-file nil)
+```
+
+This guarantees that no system-level configuration executes before the user configuration.
+
+Note: On conventional GNU/Linux distributions such as Ubuntu, Fedora, or Arch Linux, `site-start.el` is often optional and may only introduce distribution defaults. However, on functional systems such as NixOS or Guix System, it may be required to populate essential `load-path` entries. Disabling it in such environments can prevent Emacs from locating required libraries.
+
+#### Disable `default.el` (Post-Initialization Stage)
+
+After loading the user configuration, Emacs may evaluate `default.el`. This file can override user-defined settings or introduce additional global behavior.
+
+To prevent any system configuration from executing after the user initialization, add the following to `pre-early-init.el`:
+
+```elisp
+(setq inhibit-default-init t)
+```
+
+Disabling both `site-run-file` and `default.el` removes system-level interference, reduces startup variability, and establishes a fully controlled initialization environment suitable for minimal and reproducible configurations.
+
### How to get the latest version of all packages? (unstable)
By default, *minimal-emacs.d* is configured to prioritize packages from [GNU ELPA](https://elpa.gnu.org/) and [NonGNU ELPA](https://elpa.nongnu.org/) repositories over [MELPA](https://melpa.org/), ensuring greater stability.
@@ -1945,9 +2458,7 @@ Here is a comprehensive `package-pinned-packages` configuration to guarantee tha
(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")
@@ -2137,9 +2648,29 @@ Keep in mind that if you change the `minimal-emacs-user-directory`, *minimal-ema
### How to make *minimal-emacs.d* install packages in the early-init phase instead of the init phase?
+NOTE: Running package initialization and installation during the early-init phase is **NOT RECOMMENDED** because this stage occurs before the GUI system, windowing, and comprehensive error-handling buffers are fully initialized. When package-install or `package-refresh-contents` triggers a failure—such as a TLS handshake error or a lost network connection—Emacs cannot yet render a graphical window to display the backtrace or warning. This results in a "silent" hang or a crash that provides no visual feedback to the user, forcing a pivot to a terminal to inspect standard output. Furthermore, many packages expect a fully functional frame and loaded user environment to configure themselves correctly; forcing them to load during early-init bypasses the intentional separation designed to let you set up UI-independent variables before the package system and GUI logic complicate the startup sequence.
+
To install and load packages during the early-init phase, add the following to `post-early-init.el`:
```elisp
+;; THIS IS NOT RECOMMENDED
+;;
+;; Running package initialization and installation during the early-init phase
+;; is NOT RECOMMENDED because this stage occurs before the GUI system,
+;; windowing, and comprehensive error-handling buffers are fully initialized.
+;; When package-install or `package-refresh-contents` triggers a failure—such as
+;; a TLS handshake error or a lost network connection—Emacs cannot yet render a
+;; graphical window to display the backtrace or warning. This results in a
+;; "silent" hang or a crash that provides no visual feedback to the user,
+;; forcing a pivot to a terminal to inspect standard output. Furthermore, many
+;; packages expect a fully functional frame and loaded user environment to
+;; configure themselves correctly; forcing them to load during early-init
+;; bypasses the intentional separation designed to let you set up UI-independent
+;; variables before the package system and GUI logic complicate the startup
+;; sequence.
+;;
+;; File: `post-early-init.el'
+
(setq minimal-emacs-package-initialize-and-refresh nil)
;; If you want to ignore the warning:
@@ -2148,20 +2679,18 @@ To install and load packages during the early-init phase, add the following to `
;; (setq warning-suppress-types '((package)))
;; Initialize packages in the early-init phase instead of init
-(progn
+(when (bound-and-true-p minimal-emacs-package-initialize-and-refresh)
+ ;; Initialize and refresh package contents again if needed
(package-initialize)
- (unless package-archive-contents
- (package-refresh-contents))
(unless (package-installed-p 'use-package)
+ (unless (seq-empty-p package-archive-contents)
+ (package-refresh-contents))
(package-install 'use-package))
- (eval-when-compile
- (require 'use-package)))
+ (require 'use-package))
-;; TODO: Add your use-package code here
+;; TODO: Add your use-package packages 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.
-
### Minimal-emacs.d configurations from users
- [Victor Dorneanu's minimal-emacs.d configuration](https://github.com/dorneanu/dotfiles/blob/master/minimal-emacs/config.org)
@@ -2172,55 +2701,68 @@ A drawback of using the early-init phase instead of init is that if a package fa
- [Mark Norton's minimal-emacs.d configuration](https://github.com/Remillard/minimal-emacs.d/tree/develop)
+- [ghostlou1043's emacs.d](https://github.com/ghostlou1043/emacs)
+
- [smahm006 minimal-emacs.d configuration](https://github.com/smahm006/minimal-emacs.d)
- [zendo: Emacs literate configuration](https://github.com/zendo/nsworld/blob/main/dotfiles/org/all-emacs.org)
## Features
-1. **Performance Improvements:**
- - Increases the amount read from processes in a single chunk.
- - Prefers loading newer compiled files.
- - Reduces startup screen and message noise, including removing the "For information about GNU Emacs..." message.
- - Configures Emacs to start with a scratch buffer in `fundamental-mode` to shave seconds off startup time.
- - Delays garbage collection during startup to improve performance and resets it to a more reasonable value once Emacs has started.
- - Customizes `file-name-handler-alist` for improved startup time and package load time (Special thanks to the Doom Emacs developers for the `file-name-handler-alist` optimizations; This function have been inspired by their project and will contribute to improving vanilla Emacs configurations.)
- - Reduces rendering workload by not rendering cursors or regions in non-focused windows.
- - Disables warnings from the legacy advice API and suppresses warnings about aliased variables.
- - Avoids unnecessary excessive UI updates.
- - Disables font compacting to avoid high memory usage.
- - Defer tool bar setup
- - Unset command line options irrelevant to the current OS
+The minimal-emacs.d base provides a sensible foundation for your personal configuration. It addresses common pain points in vanilla Emacs to provide a responsive and clean environment from the start, without forcing a specific workflow.
-2. **Native Compilation and Byte Compilation:**
- - Configures native compilation and byte compilation settings
- - Suppresses compiler warnings and errors during native compilation.
+### Fast Initialization and Performance
-4. **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.
+* **Optimized File Handlers:** Defers garbage collection during startup to reduce load times, restoring it to a standard threshold once Emacs is ready.
+* **Process Throughput:** Increases the chunk size for reading from processes to speed up external tool interactions.
+* **Compiled File Preference:** Instructs Emacs to prioritize loading newer byte-compiled files.
+* **Optimized Text Rendering:** Disables font compacting during startup to reduce memory usage and speed up initialization.
+* **Silent Boot Sequence:** Removes the GNU Emacs startup message, unsets OS-irrelevant command line options, and defers toolbar setup.
-5. **Package Management:**
- - Configures package archives and priorities for MELPA, ELPA, and other repositories.
+### Native Compilation and Byte Compilation
-6. **Customizable Initialization Files:**
- - Supports additional configuration files (`pre-init.el`, `post-init.el`, `pre-early-init.el`, and `post-early-init.el`) to allow further customization at different stages of the startup process.
+* **Out-of-the-Box Optimization:** Configures default settings for native and byte compilation.
+* **Quiet Compilation:** Suppresses warnings and errors during async native compilation to prevent popup interruptions.
-7. **File Management:**
- - Manages auto-save and backup files, including backup options and version control settings.
+### Interface Defaults
-8. **User Experience Enhancements:**
- - Configures user interface settings such as cursor behavior, scrolling, and response to prompts.
- - Disables beeping and blinking to avoid distractions.
+* **Minimal UI:** Disables the startup screen, menu bar, tool bar, and scroll bars by default to maximize screen space.
+* **Smart Rendering:** Stops rendering cursors and region highlights in non-focused windows. Prevents Emacs from automatically resizing frames on setting adjustments.
+* **Typographic Defaults:** Renders underlines at the descent line, replaces truncation markers with an ellipsis ("..."), and disables the visible bell.
+* **Focused Minibuffer:** Enables recursive minibuffers and restricts the cursor from entering read-only prompt areas.
-9. **Buffer and Window Configuration:**
- - Sets default fringe widths and buffer boundaries.
- - Configures smooth scrolling and cursor behavior for a more seamless editing experience.
+### Package and File Management
-10. **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
+* **Repository Prioritization:** Configures archives and sets explicit priorities for GNU ELPA, NonGNU ELPA, and MELPA.
+* **Centralized Artifacts:** Routes auto-save and backup files to dedicated subdirectories within the Emacs configuration folder. Enables versioned backups.
+* **Auto-Revert:** Refreshes buffers when the underlying file changes on disk. (Disabled by default.)
+* **Session Memory:** Saves cursor positions across sessions, maintains recent file history, and persists the minibuffer history. (Disabled by default.)
+
+### Precision Editing and UX Enhancements
+
+* **Predictable Scrolling:** Configures conservative scrolling to eliminate default half-screen jumps.
+* **Modern Formatting Standards:** Enforces a POSIX-compliant final newline on save, disables double-space sentence endings, and triggers smart indentation only on newlines and backspaces.
+* **Sensible Tab Management:** Defaults to spaces with a tab width. Configures the tab key to indent first, then complete.
+* **Fast Interactions:** Configures prompts to accept "y" or "n" instead of "yes" or "no".
+
+### Developer Experience
+
+* **Optional Built-in Package Defaults:** Configures optimized settings for built-in packages like Eglot, recentf, savehist, and auto-save without enabling them by default.
+* **Git Integration:** Sets version control to use the `--histogram` diff algorithm and automatically follow file renames in logs.
+
+### Buffer, Directory, and Window Management
+
+* **Modern Splits:** Favors vertical window splits over horizontal ones.
+* **Ediff Optimization:** Configures Ediff to use a single frame and split windows horizontally.
+* **Dired Mastery:** Enables `dired-dwim-target` for easier file operations between panes. Auto-updates Dired buffers and cleans up deleted directories silently.
+* **Window Dividers:** Uses minimalistic window dividers and sets default fringe widths.
+
+### Security, Stability, and Customizable Initialization
+
+* **Safety Checks:** Verifies successful configuration load and warns of conflicts with legacy `~/.emacs` files.
+* **Drop-In Customization:** Supports loading modular configuration files (`pre-early-init.el`, `post-early-init.el`, `pre-init.el`, and `post-init.el`) to hook into different stages of the startup process.
+* **Strict TLS Verification:** Enforces strict SSL/TLS certificate checks and raises the minimum encryption strength for GnuTLS.
+* **Encrypted Auth Sources:** Prefers GPG-encrypted authentication files (`~/.authinfo.gpg`) and directs the GPG agent to use the minibuffer for passphrase entry.
## Author and license
@@ -2258,4 +2800,4 @@ Other Emacs packages by the same author:
- [stripspace.el](https://github.com/jamescherti/stripspace.el): Ensure Emacs Automatically removes trailing whitespace before saving a buffer, with an option to preserve the cursor column.
- [persist-text-scale.el](https://github.com/jamescherti/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](https://github.com/jamescherti/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.
-- [kirigami.el](https://github.com/jamescherti/kirigami.el): The *kirigami* Emacs package offers a unified interface for opening and closing folds across a diverse set of major and minor modes in Emacs, including `outline-mode`, `outline-minor-mode`, `outline-indent-mode`, `org-mode`, `markdown-mode`, `vdiff-mode`, `vdiff-3way-mode`, `hs-minor-mode`, `hide-ifdef-mode`, `origami-mode`, `yafolding-mode`, `folding-mode`, and `treesit-fold-mode`. With Kirigami, folding key bindings only need to be configured **once**. After that, the same keys work consistently across all supported major and minor modes, providing a unified and predictable folding experience.
+- [kirigami.el](https://github.com/jamescherti/kirigami.el): The *kirigami* Emacs package offers a unified interface for opening and closing folds across a diverse set of major and minor modes in Emacs, including `outline-mode`, `outline-minor-mode`, `outline-indent-minor-mode`, `org-mode`, `markdown-mode`, `vdiff-mode`, `vdiff-3way-mode`, `hs-minor-mode`, `hide-ifdef-mode`, `origami-mode`, `yafolding-mode`, `folding-mode`, and `treesit-fold-mode`. With Kirigami, folding key bindings only need to be configured **once**. After that, the same keys work consistently across all supported major and minor modes, providing a unified and predictable folding experience.
diff --git a/early-init.el b/early-init.el
index fec14cc..910a79c 100644
--- a/early-init.el
+++ b/early-init.el
@@ -1,10 +1,10 @@
;;; early-init.el --- Early Init -*- lexical-binding: t; -*-
-;; Author: James Cherti
+;; Author: James Cherti
;; URL: https://github.com/jamescherti/minimal-emacs.d
;; Package-Requires: ((emacs "29.1"))
;; Keywords: maint
-;; Version: 1.3.1
+;; Version: 1.4.1
;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Commentary:
@@ -81,16 +81,6 @@ tradeoff is that the mode line is hidden during the startup phase.")
When set to non-nil, Emacs will automatically call `package-initialize' and
`package-refresh-contents' to set up and update the package system.")
-(defvar minimal-emacs-setup-native-compilation t
- "Controls whether native compilation settings are enabled during setup.
-When non-nil, the following variables are set to non-nil to enable
-native compilation features:
-- `native-comp-deferred-compilation'
-- `native-comp-jit-compilation'
-- `package-native-compile'
-If nil, these variables are left at their default values and are not
-modified during setup.")
-
(defvar minimal-emacs-inhibit-redisplay-during-startup nil
"Suppress redisplay during startup to improve performance.
This prevents visual updates while Emacs initializes. The tradeoff is that you
@@ -105,6 +95,18 @@ of the progress or any relevant activities during startup.")
"Directory beneath minimal-emacs.d files are placed.
Note that this should end with a directory separator.")
+(defvar minimal-emacs-load-pre-early-init t
+ "If non-nil, attempt to load `pre-early-init.el`.")
+
+(defvar minimal-emacs-load-post-early-init t
+ "If non-nil, attempt to load `post-early-init.el`.")
+
+(defvar minimal-emacs-load-pre-init t
+ "If non-nil, attempt to load `pre-init.el`.")
+
+(defvar minimal-emacs-load-post-init t
+ "If non-nil, attempt to load `post-init.el`.")
+
;;; Load pre-early-init.el
;; Prefer loading newer compiled files
@@ -122,8 +124,10 @@ Note that this should end with a directory separator.")
(error "Emacs ignored loading 'init.el'. Please ensure that files such as ~/.emacs or ~/.emacs.el do not exist, as they may be preventing Emacs from loading the 'init.el' file"))
(t
- (error "Configuration error. Debug by starting Emacs with: emacs --debug-init")))))
-(add-hook 'emacs-startup-hook #'minimal-emacs--check-success 102)
+ (error "Configuration error. Debug by starting Emacs with: --debug-init")))))
+
+(unless noninteractive
+ (add-hook 'emacs-startup-hook #'minimal-emacs--check-success 102))
(defvar minimal-emacs-load-compiled-init-files nil
"If non-nil, attempt to load byte-compiled .elc for init files.
@@ -153,7 +157,8 @@ pre-early-init.el, and post-early-init.el.")
(setq init-file (minimal-emacs--remove-el-file-suffix init-file))
(load init-file :no-error (not minimal-emacs-debug)))))
-(minimal-emacs-load-user-init "pre-early-init.el")
+(when minimal-emacs-load-pre-early-init
+ (minimal-emacs-load-user-init "pre-early-init.el"))
(setq custom-theme-directory
(expand-file-name "themes/" minimal-emacs-user-directory))
@@ -171,7 +176,9 @@ pre-early-init.el, and post-early-init.el.")
(defun minimal-emacs--restore-gc ()
"Restore garbage collection settings."
- (if (bound-and-true-p minimal-emacs-gc-cons-threshold-restore-delay)
+ (if (and (bound-and-true-p minimal-emacs-gc-cons-threshold-restore-delay)
+ ;; In noninteractive mode, the event loop does not run
+ (not noninteractive))
;; Defer garbage collection during initialization to avoid 2 collections.
(run-with-timer minimal-emacs-gc-cons-threshold-restore-delay nil
#'minimal-emacs--restore-gc-values)
@@ -187,12 +194,9 @@ pre-early-init.el, and post-early-init.el.")
;;; Native compilation and Byte compilation
-(if (and (featurep 'native-compile)
- (fboundp 'native-comp-available-p)
- (native-comp-available-p))
- (when minimal-emacs-setup-native-compilation
- ;; Activate `native-compile'
- (setq package-native-compile t))
+(unless (and (featurep 'native-compile)
+ (fboundp 'native-comp-available-p)
+ (native-comp-available-p))
;; Deactivate the `native-compile' feature if it is not available
(setq features (delq 'native-compile features)))
@@ -207,9 +211,6 @@ pre-early-init.el, and post-early-init.el.")
(set-language-environment "UTF-8")
-;; Set-language-environment sets default-input-method, which is unwanted.
-(setq default-input-method nil)
-
;; Increase how much is read from processes in a single chunk
(setq read-process-output-max (* 2 1024 1024)) ; 1024kb
@@ -238,7 +239,7 @@ pre-early-init.el, and post-early-init.el.")
;; icon fonts on Windows. This will increase memory usage.
(setq inhibit-compacting-font-caches t)
-(when (and (not (daemonp)) (not noninteractive))
+(when (not noninteractive)
;; Resizing the Emacs frame can be costly when changing the font. Disable this
;; to improve startup times with fonts larger than the system default.
(setq frame-resize-pixelwise t)
@@ -272,16 +273,6 @@ pre-early-init.el, and post-early-init.el.")
;; `inhibit-startup-screen', but it would still initialize anyway.
(advice-add 'display-startup-screen :override #'ignore)
- ;; The initial buffer is created during startup even in non-interactive
- ;; sessions, and its major mode is fully initialized. Modes like `text-mode',
- ;; `org-mode', or even the default `lisp-interaction-mode' load extra packages
- ;; and run hooks, which can slow down startup.
- ;;
- ;; Using `fundamental-mode' for the initial buffer to avoid unnecessary
- ;; startup overhead.
- (setq initial-major-mode 'fundamental-mode
- initial-scratch-message nil)
-
(unless minimal-emacs-debug
;; Unset command line options irrelevant to the current OS. These options
;; are still processed by `command-line-1` but have no effect.
@@ -315,7 +306,6 @@ this stage of initialization."
minimal-emacs--old-file-name-handler-alist))))
(when (and minimal-emacs-optimize-file-name-handler-alist
- (not (daemonp))
(not minimal-emacs-debug))
;; Determine the state of bundled libraries using calc-loaddefs.el. If
;; compressed, retain the gzip handler in `file-name-handler-alist`. If
@@ -347,7 +337,6 @@ this stage of initialization."
(remove-hook 'post-command-hook #'minimal-emacs--reset-inhibit-redisplay))
(when (and minimal-emacs-inhibit-redisplay-during-startup
- (not (daemonp))
(not noninteractive)
(not minimal-emacs-debug))
;; Suppress redisplay and redraw during startup to avoid delays and
@@ -363,7 +352,6 @@ this stage of initialization."
(remove-hook 'post-command-hook #'minimal-emacs--reset-inhibit-message))
(when (and minimal-emacs-inhibit-message-during-startup
- (not (daemonp))
(not noninteractive)
(not minimal-emacs-debug))
(setq-default inhibit-message t)
@@ -371,8 +359,10 @@ this stage of initialization."
;;; Performance: Disable mode-line during startup
+(defvar-local minimal-emacs--hidden-mode-line nil
+ "Store the buffer-local value of `mode-line-format' during startup.")
+
(when (and minimal-emacs-disable-mode-line-during-startup
- (not (daemonp))
(not noninteractive)
(not minimal-emacs-debug))
(put 'mode-line-format
@@ -380,7 +370,9 @@ this stage of initialization."
(setq-default mode-line-format nil)
(dolist (buf (buffer-list))
(with-current-buffer buf
- (setq mode-line-format nil))))
+ (when (local-variable-p 'mode-line-format)
+ (setq minimal-emacs--hidden-mode-line mode-line-format)
+ (setq mode-line-format nil)))))
;;; Restore values
@@ -399,7 +391,12 @@ this stage of initialization."
(when minimal-emacs-disable-mode-line-during-startup
(unless (default-toplevel-value 'mode-line-format)
(setq-default mode-line-format (get 'mode-line-format
- 'initial-value))))))
+ 'initial-value)))
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (local-variable-p 'minimal-emacs--hidden-mode-line)
+ (setq mode-line-format minimal-emacs--hidden-mode-line)
+ (kill-local-variable 'minimal-emacs--hidden-mode-line)))))))
(advice-add 'startup--load-user-init-file :around
#'minimal-emacs--startup-load-user-init-file)
@@ -429,8 +426,7 @@ this stage of initialization."
(when (bound-and-true-p tool-bar-mode)
(funcall 'tool-bar-setup))))
-(when (and (not (daemonp))
- (not noninteractive))
+(unless noninteractive
(when (fboundp 'tool-bar-setup)
;; Temporarily override the tool-bar-setup function to prevent it from
;; running during the initial stages of startup
@@ -463,21 +459,18 @@ this stage of initialization."
(setq tls-checktrust t) ; Ensure SSL/TLS connections undergo trust verification
(setq gnutls-min-prime-bits 3072) ; Stronger GnuTLS encryption
-;;; package.el
-(setq package-enable-at-startup nil)
-(setq use-package-compute-statistics minimal-emacs-debug)
+;; This results in a more compact output that emphasizes performance
+(setq use-package-expand-minimally t)
-;; Setting use-package-expand-minimally to (t) results in a more compact output
-;; that emphasizes performance over clarity.
-(setq use-package-expand-minimally (not noninteractive))
-
-(setq package-quickstart-file
- (expand-file-name "package-quickstart.el" user-emacs-directory))
(setq use-package-minimum-reported-time (if minimal-emacs-debug 0 0.1))
(setq use-package-verbose minimal-emacs-debug)
-(setq package-enable-at-startup nil) ; Let the init.el file handle this
-(setq use-package-always-ensure t)
+(setq use-package-always-ensure (not noninteractive))
(setq use-package-enable-imenu-support t)
+
+;; package.el
+(setq package-enable-at-startup nil) ; Let the init.el file handle this
+(setq package-quickstart-file
+ (expand-file-name "package-quickstart.el" user-emacs-directory))
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")
@@ -488,7 +481,9 @@ this stage of initialization."
("melpa-stable" . 50)))
;;; Load post-early-init.el
-(minimal-emacs-load-user-init "post-early-init.el")
+
+(when minimal-emacs-load-post-early-init
+ (minimal-emacs-load-user-init "post-early-init.el"))
;; Local variables:
;; byte-compile-warnings: (not obsolete free-vars)
diff --git a/init.el b/init.el
index 705136b..3b3c5e9 100644
--- a/init.el
+++ b/init.el
@@ -1,10 +1,10 @@
;;; init.el --- Init -*- lexical-binding: t; -*-
-;; Author: James Cherti
+;; Author: James Cherti
;; URL: https://github.com/jamescherti/minimal-emacs.d
;; Package-Requires: ((emacs "29.1"))
;; Keywords: maint
-;; Version: 1.3.1
+;; Version: 1.4.1
;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Commentary:
@@ -22,12 +22,27 @@
;;; Code:
;;; Load pre-init.el
+
(if (fboundp 'minimal-emacs-load-user-init)
- (minimal-emacs-load-user-init "pre-init.el")
- (error "The early-init.el file failed to loaded"))
+ (when minimal-emacs-load-pre-init
+ (minimal-emacs-load-user-init "pre-init.el"))
+ (error "The early-init.el file failed to load"))
;;; Before package
+;; The initial buffer is created during startup even in non-interactive
+;; sessions, and its major mode is fully initialized. Modes like `text-mode',
+;; `org-mode', or even the default `lisp-interaction-mode' load extra packages
+;; and run hooks, which can slow down startup.
+;;
+;; Using `fundamental-mode' for the initial buffer to avoid unnecessary
+;; startup overhead.
+(setq initial-major-mode 'fundamental-mode
+ initial-scratch-message nil)
+
+;; Set-language-environment sets default-input-method, which is unwanted.
+(setq default-input-method nil)
+
;; Ask the user whether to terminate asynchronous compilations on exit.
;; This prevents native compilation from leaving temporary files in /tmp.
(setq native-comp-async-query-on-exit t)
@@ -46,29 +61,29 @@
;;; package.el
-(when (bound-and-true-p minimal-emacs-package-initialize-and-refresh)
+(when (and (bound-and-true-p minimal-emacs-package-initialize-and-refresh)
+ (not (bound-and-true-p byte-compile-current-file))
+ (not (or (fboundp 'straight-use-package)
+ (fboundp 'elpaca))))
;; Initialize and refresh package contents again if needed
(package-initialize)
- ;; Install use-package if necessary
- (unless (package-installed-p 'use-package)
- (unless (seq-empty-p package-archive-contents)
- (package-refresh-contents))
+ (unless package-archive-contents
+ (package-refresh-contents))
+ (when (and (version< emacs-version "29.1")
+ (not (package-installed-p 'use-package)))
(package-install 'use-package))
-
- ;; Ensure use-package is available
(require 'use-package))
;;; Minibuffer
-;; Allow nested minibuffers
-(setq enable-recursive-minibuffers t)
+(setq enable-recursive-minibuffers t) ; Allow nested minibuffers
;; Keep the cursor out of the read-only portions of the.minibuffer
(setq minibuffer-prompt-properties
'(read-only t intangible t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
-;;; User interface
+;;; Display and user interface
;; By default, Emacs "updates" its ui more often than it needs to
(setq which-func-update-delay 1.0)
@@ -80,6 +95,13 @@
(setq visible-bell nil)
(setq ring-bell-function #'ignore)
+;; Position underlines at the descent line instead of the baseline.
+(setq x-underline-at-descent-line t)
+
+(setq truncate-string-ellipsis "…")
+
+(setq display-time-default-load-average nil) ; Omit load average
+
;;; Show-paren
(setq show-paren-delay 0.1
@@ -87,34 +109,10 @@
show-paren-when-point-inside-paren t
show-paren-when-point-in-periphery t)
-;;; Misc
+;;; Buffer management
(setq custom-buffer-done-kill t)
-(setq whitespace-line-column nil) ; Use the value of `fill-column'.
-
-;; Can be activated with `display-line-numbers-mode'
-(setq-default display-line-numbers-width 3)
-(setq-default display-line-numbers-widen t)
-
-(setq truncate-string-ellipsis "…")
-
-;; Disable truncation of printed s-expressions in the message buffer
-(setq eval-expression-print-length nil
- eval-expression-print-level nil)
-
-;; Position underlines at the descent line instead of the baseline.
-(setq x-underline-at-descent-line t)
-
-(setq remote-file-name-inhibit-cache 50)
-
-;; Automatically rescan the buffer for Imenu entries when `imenu' is invoked
-;; This ensures the index reflects recent edits.
-(setq imenu-auto-rescan t)
-
-;; Prevent truncation of long function names in `imenu' listings
-(setq imenu-max-item-length 160)
-
;; Disable auto-adding a new line at the bottom when scrolling.
(setq next-line-add-newlines nil)
@@ -122,10 +120,47 @@
;; Benefit: you never lose bookmarks if Emacs crashes.
(setq bookmark-save-flag 1)
-;;; tramp
+(setq uniquify-buffer-name-style 'forward)
+
+(setq remote-file-name-inhibit-cache 50)
+
+;; Disable fontification during user input to reduce lag in large buffers.
+;; Also helps marginally with scrolling performance.
+(setq redisplay-skip-fontification-on-input t)
+
+;;; Misc
+
+(setq whitespace-line-column nil) ; Use the value of `fill-column'.
+
+;; Disable ellipsis when printing s-expressions in the message buffer
+(setq eval-expression-print-length nil
+ eval-expression-print-level nil)
+
+;; This directs gpg-agent to use the minibuffer for passphrase entry
+(setq epg-pinentry-mode 'loopback)
+
+;; By default, Emacs stores sensitive authinfo credentials as unencrypted text
+;; in your home directory. Use GPG to encrypt the authinfo file for enhanced
+;; security.
+(setq auth-sources (list "~/.authinfo.gpg"))
+
+;;; `display-line-numbers-mode'
+
+(setq-default display-line-numbers-width 3)
+(setq-default display-line-numbers-widen t)
+
+;;; imenu
+
+;; Automatically rescan the buffer for Imenu entries when `imenu' is invoked
+;; This ensures the index reflects recent edits.
+(setq imenu-auto-rescan t)
+
+;; Prevent truncation of long function names in `imenu' listings
+(setq imenu-max-item-length 160)
+
+;;; Tramp
(setq tramp-verbose 1)
-(setq tramp-completion-reread-directory-timeout 50)
;;; Files
@@ -136,18 +171,16 @@
;; Ignoring this is acceptable since it will redirect to the buffer regardless.
(setq find-file-suppress-same-file-warnings t)
-;; Resolve symlinks so that operations are conducted from the file's directory
+;; Resolve symlinks to avoid duplicate buffers
(setq find-file-visit-truename t
+ ;; Automatically follow a symlink to its source if that source is managed
+ ;; by a version control system, rather than asking for permission.
vc-follow-symlinks t)
;; Prefer vertical splits over horizontal ones
(setq split-width-threshold 170
split-height-threshold nil)
-;;; Buffers
-
-(setq uniquify-buffer-name-style 'forward)
-
;;; comint (general command interpreter in a window)
(setq ansi-color-for-comint-mode t
@@ -165,8 +198,16 @@
;;; Backup files
-;; Avoid backups or lockfiles to prevent creating world-readable copies of files
+;; Disable the creation of lockfiles (e.g., .#filename).
+;; Modern workflows rely on `global-auto-revert-mode' to handle external file
+;; changes gracefully, making the restrictive nature of lockfiles unnecessary.
(setq create-lockfiles nil)
+
+;; Disable backup files (e.g., filename~). Note that `auto-save-default'
+;; remains enabled by default. Even with `make-backup-files' backups disabled,
+;; Emacs will still generate temporary recovery files (e.g., #filename#) for
+;; unsaved buffers. This protects your active work from sudden crashes while
+;; ensuring the file system is cleaned up immediately upon a successful save.
(setq make-backup-files nil)
(setq backup-directory-alist
@@ -182,7 +223,6 @@
;;; VC
(setq vc-git-print-log-follow t)
-(setq vc-make-backup-files nil) ; Do not backup version controlled files
(setq vc-git-diff-switches '("--histogram")) ; Faster algorithm for diffing.
;;; Auto save
@@ -190,9 +230,13 @@
;; Enable auto-save to safeguard against crashes or data loss. The
;; `recover-file' or `recover-session' functions can be used to restore
;; auto-saved data.
-(setq auto-save-default nil)
(setq auto-save-no-message t)
+(when noninteractive
+ ;; The command line interface
+ (setq enable-dir-local-variables nil)
+ (setq case-fold-search nil))
+
;; Do not auto-disable auto-save after deleting large chunks of
;; text.
(setq auto-save-include-big-deletions t)
@@ -202,6 +246,20 @@
(setq tramp-auto-save-directory
(expand-file-name "tramp-autosave/" user-emacs-directory))
+(setq auto-save-file-name-transforms
+ `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'"
+ ,(file-name-concat auto-save-list-file-prefix "tramp-\\2-") sha1)
+ ("\\`/\\([^/]+/\\)*\\([^/]+\\)\\'"
+ ,(file-name-concat auto-save-list-file-prefix "\\2-") sha1)))
+
+;; Ensure the directory for auto-save session logs exists with restricted
+;; permissions.
+(when auto-save-default
+ (let ((auto-save-dir (file-name-directory auto-save-list-file-prefix)))
+ (unless (file-exists-p auto-save-dir)
+ (with-file-modes #o700
+ (make-directory auto-save-dir t)))))
+
;; Auto save options
(setq kill-buffer-delete-auto-save-files t)
@@ -211,9 +269,6 @@
;;; Auto revert
;; Auto-revert in Emacs is a feature that automatically updates the contents of
;; a buffer to reflect changes made to the underlying file.
-(setq revert-without-query (list ".") ; Do not prompt
- auto-revert-stop-on-user-input nil
- auto-revert-verbose t)
;; Revert other buffers (e.g, Dired)
(setq global-auto-revert-non-file-buffers t)
@@ -225,7 +280,6 @@
(setq recentf-max-saved-items 300) ; default is 20
(setq recentf-max-menu-items 15)
(setq recentf-auto-cleanup 'mode)
-(setq recentf-exclude nil)
;;; saveplace
@@ -238,19 +292,13 @@
;; `savehist-mode' is an Emacs feature that preserves the minibuffer history
;; between sessions.
(setq history-length 300)
-(setq savehist-save-minibuffer-history t) ;; Default
(setq savehist-additional-variables
- '(kill-ring ; clipboard
- register-alist ; macros
+ '(register-alist ; macros
mark-ring global-mark-ring ; marks
search-ring regexp-search-ring)) ; searches
;;; Frames and windows
-;; However, do not resize windows pixelwise, as this can cause crashes in some
-;; cases when resizing too many windows at once or rapidly.
-(setq window-resize-pixelwise nil)
-
(setq resize-mini-windows 'grow-only)
;; The native border "uses" a pixel of the fringe on the rightmost
@@ -259,12 +307,6 @@
window-divider-default-places t
window-divider-default-right-width 1)
-;;; Fontification
-
-;; Disable fontification during user input to reduce lag in large buffers.
-;; Also helps marginally with scrolling performance.
-(setq redisplay-skip-fontification-on-input t)
-
;;; Scrolling
;; Enables faster scrolling. This may result in brief periods of inaccurate
@@ -286,20 +328,10 @@
;; 2. Resolving the issue of random half-screen jumps during scrolling.
(setq auto-window-vscroll nil)
-;; Number of lines of margin at the top and bottom of a window.
-(setq scroll-margin 0)
-
-;; Number of lines of continuity when scrolling by screenfuls.
-(setq next-screen-context-lines 0)
-
;; Horizontal scrolling
(setq hscroll-margin 2
hscroll-step 1)
-;;; Mouse
-
-(setq mouse-yank-at-point nil)
-
;; Emacs 29
(when (memq 'context-menu minimal-emacs-ui-features)
(when (and (display-graphic-p) (fboundp 'context-menu-mode))
@@ -315,12 +347,8 @@
;; Don't blink the paren matching the one at point, it's too distracting.
(setq blink-matching-paren nil)
-;; Do not extend the cursor to fit wide characters
-(setq x-stretch-cursor nil)
-
;; Reduce rendering/line scan work by not rendering cursors or regions in
;; non-focused windows.
-(setq-default cursor-in-non-selected-windows nil)
(setq highlight-nonselected-windows nil)
;;; Text editing, indent, font, and formatting
@@ -332,13 +360,6 @@
;; deletion, disrupting the flow of editing.
(setq delete-pair-blink-delay 0.03)
-(setq-default left-fringe-width 8)
-(setq-default right-fringe-width 8)
-
-;; Disable visual indicators in the fringe for buffer boundaries and empty lines
-(setq-default indicate-buffer-boundaries nil)
-(setq-default indicate-empty-lines nil)
-
;; Continue wrapped lines at whitespace rather than breaking in the
;; middle of a word.
(setq-default word-wrap t)
@@ -388,11 +409,6 @@
;; Eliminate delay before highlighting search matches
(setq lazy-highlight-initial-delay 0)
-;;; Modeline
-
-;; Makes Emacs omit the load average information from the mode line.
-(setq display-time-default-load-average nil)
-
;;; Filetype
;; Do not notify the user each time Python tries to guess the indentation offset
@@ -448,13 +464,14 @@
;;; Eglot
+(setq eglot-report-progress minimal-emacs-debug) ; Prevent minibuffer spam
+(setq eglot-autoshutdown t) ; Shut down after killing last managed buffer
+
;; A setting of nil or 0 means Eglot will not block the UI at all, allowing
;; Emacs to remain fully responsive, although LSP features will only become
;; available once the connection is established in the background.
(setq eglot-sync-connect 0)
-(setq eglot-autoshutdown t) ; Shut down server after killing last managed buffer
-
;; Activate Eglot in cross-referenced non-project files
(setq eglot-extend-to-xref t)
@@ -467,19 +484,14 @@
(setq eglot-events-buffer-size 0) ; Deprecated
(setq eglot-events-buffer-config '(:size 0 :format short)))
-(setq eglot-report-progress minimal-emacs-debug) ; Prevent minibuffer spam
-
;;; Flymake
(setq flymake-show-diagnostics-at-end-of-line nil)
-
-;; Disable wrapping around when navigating Flymake errors.
(setq flymake-wrap-around nil)
;;; hl-line-mode
-;; Restrict `hl-line-mode' highlighting to the current window, reducing visual
-;; clutter and slightly improving `hl-line-mode' performance.
+;; Highlighting the current window, reducing clutter and improving performance
(setq hl-line-sticky-flag nil)
(setq global-hl-line-sticky-flag nil)
@@ -491,11 +503,10 @@
;;; flyspell
-(setq flyspell-issue-welcome-flag nil)
-
;; Improves flyspell performance by preventing messages from being displayed for
;; each word when checking the entire buffer.
(setq flyspell-issue-message-flag nil)
+(setq flyspell-issue-welcome-flag nil)
;;; ispell
@@ -522,8 +533,8 @@
;;; abbrev
-;; Ensure `abbrev_defs` is stored in the correct location when
-;; `user-emacs-directory` is modified, as it defaults to ~/.emacs.d/abbrev_defs
+;; Ensure the abbrev_defs file is stored in the correct location when
+;; `user-emacs-directory' is modified, as it defaults to ~/.emacs.d/abbrev_defs
;; regardless of the change.
(setq abbrev-file-name (expand-file-name "abbrev_defs" user-emacs-directory))
@@ -553,8 +564,11 @@
(put cmd 'disabled nil))
;;; Load post init
-(when (fboundp 'minimal-emacs-load-user-init)
+
+(when (and minimal-emacs-load-post-init
+ (fboundp 'minimal-emacs-load-user-init))
(minimal-emacs-load-user-init "post-init.el"))
+
(setq minimal-emacs--success t)
;; Local variables: