Plain elisp, split by domain. A flake pins the packages; nothing else.
This used to be one literate org file that tangled into a 6000-line
init.el. It is now 37 files that are the source, edited directly. Nix
supplies the package set and owns nothing else, so every file here stays
live-editable.
Build the package set and start Emacs against this directory:
nix build
result/bin/emacs --init-directory ~/git/emacsnix build .#packageNames writes the resolved package list without building
Emacs, which is the quick way to see what the parser made of a new
use-package form.
Cutover is repointing ~~/.emacs.d/init.el~ and early-init.el at this repo.
Rollback is pointing them back.
init.el loads every file below in a fixed order, the same order the old
literate config tangled into. Files resolve against wherever init.el really
lives, following the symlink, so they are found whether Emacs is started with
--init-directory or through ~~/.emacs.d~.
| settings.el | general editor settings |
| theme.el | fonts, Modus themes, per-project colours |
| cjk.el | CJK fonts per role, tagged onto Han text |
| keybindings.el | general.el and the leader-key map |
| agent-shell.el | agent-shell sessions, notifications, resume |
| ui.el | icons, ligatures, padding, scrolling |
| prog.el | language servers, formatting, treesit, modes |
| files.el | files, projects, history, shell helpers |
| text.el | prose, markup, search syntax |
| completion.el | vertico, corfu and the completion stack |
| d2.el | d2 diagrams and their previews |
| mermaid.el | mermaid diagrams and their previews |
| dired.el | Dired and Dirvish |
| modeline.el | doom-modeline and its indicators |
| vc.el | magit, ediff, git links |
| evil.el | evil and its companions |
| ghostel.el | ghostel terminal sessions |
| knockknock.el | knockknock notifications |
| toggl.el | time zones and toggl time tracking |
| platform.el | per-machine and per-system loading |
| org.el | core setup, tags, todo keywords, keybindings |
| agenda.el | org-agenda and its task frame |
| babel.el | org-babel languages and templates |
| capture.el | capture templates |
| appearance.el | org-modern, org-appear, org-tidy |
| extras.el | the smaller org add-ons |
| roam.el | org-roam and the roam helpers |
| timegrid.el | org-timegrid calendar |
| transclusion.el | org-transclusion |
The twelve sections that were tagged :custom:, which are code rather than
package configuration.
| gps-time.el | GPS time conversion |
| insert-variable-value.el | insert a variable value at point |
| org-reviews.el | morning, weekly, monthly reviews |
| org-latex-preview.el | LaTeX preview rendering |
| org-meetings.el | meetings and agenda notifications |
| org-prettify-symbols.el | prettified org keywords |
| org-block-brackets.el | SVG brackets beside org blocks |
| org-inbox-review.el | inbox review workflow |
| quartz.el | Quartz site publishing |
| read-only-directories.el | mark directories read-only |
| window-resize.el | window resizing commands |
early-init.el runs before the frame exists. mac.el, linux.el and
ms-windows.el are loaded by config/platform.el on the matching system.
Packages, and only packages. flake.nix reads every use-package form under
config/ and lisp/ and builds an Emacs carrying exactly those. There is no
elisp in the flake and nothing of this config goes into the store.
package.el still runs, since it is what loads the packages’ autoloads, but
package-user-dir points away from ~~/.emacs.d/elpa~ so the old tree cannot
get in front of the pinned set.
Six packages are installed from git rather than MELPA and are pinned by
revision in gitSources. Bumping one is a rev and a hash.
Every tree-sitter grammar nixpkgs ships comes from the store too, so no mode stops to ask for one.
- Install. Add a
use-packageform in the rightconfig/file, then checknix build .#packageNamesand the source it resolved. NotM-x package-install:package-user-diris pointed away from ~~/.emacs.d/elpa~. - Upgrade.
nix flake update, ornix flake update emacs-overlayfor the overlay alone, then rebuild and restart.flake.lockis the pin, so commit it.M-x package-upgradedoes nothing here. - Upgrade, git packages. A new rev, hash and version in
gitSources. - Rollback.
git checkout flake.lockand rebuild.
Things Nix does not pin here, each for a reason:
- Language servers.
lsp-modedownloads rust-analyzer and pyright on first use. Out of scope: they are system tools and belong to the machine config, not the editor’s package set. - ghostel’s native module. The flake takes the elisp from
lisp/and not the Zig terminal around it, soghostel-module.dylibis still whateverghostel-module-installput there.package-vcnever supplied it either, so this is unchanged rather than lost. - toggl. A private repo reached over SSH, which no pure evaluation can fetch. Making it public, or vendoring it, is what would close this.
- Emacs state.
custom.el,eln-cache, history, bookmarks and.org-id-locationsresolve againstuser-emacs-directoryand are ignored by git. They are per-machine by nature.
- Crafted Emacs
- Nicolas Rougier particularly NANO though everything he touches is gold
- Org Modern
- Progfolio’s .emacs.d