Keeping a tidy .emacs.d/ with no-littering.el
No-littering.el keeps your .emacs.d clean. I’ve been using it for years—in fact it’s one of the only third-party packages I first installed several years ago when I started using Emacs that I still have in my config today.
It establishes conventions for keeping files created from packages:
- The no-littering-etc-directory. The directory where packages place their configuration files.
- The no-littering-var-directory. The directory where packages place their persistent data files.
If every package followed this convention, then no files should litter (pun intended) your emacs configuration directory. Unfortunately, not every package does… fortunately, no-littering already sets the relevant option of dozens of packages to use these directories. But if you use a package that isn’t already set, you can easily use no-littering-expand-var-file-name and no-littering-expand-etc-file-name to change that. For example: (setopt cursory-latest-state-file (no-littering-expand-var-file-name “cursory/cursory-latest-state”)) sets cursory-latest-state-file
to ~/.emacs.d/var/cursory/cursory-latest-state
.
Here’s a look at my own directories.
- My no-littering-etc-directory, located at
~/.emacs.d/etc/
:1 2 3 4 5 6 7 8
$ tree -L 1 . ├── abbrev.el ├── custom.el ├── gnus └── transient 3 directories, 2 files
- My no-littering-var-directory, located at
~/.emacs.d/var/
:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
$ tree -L 1 . ├── abbrev-mode ├── amx-save.el ├── anaconda-mode ├── annotations.el ├── auto-save ├── backup ├── bookmark-default.el ├── citre ├── company ├── cursory ├── dap ├── dape-adapters ├── desktop ├── devdocs ├── diary ├── eaf ├── eafpdf ├── eglot-java ├── elfeed ├── emacs-gc-stats.eld.gz ├── emms ├── emojify ├── erc ├── eshell ├── eww ├── flycheck ├── fontaine ├── fontaine-latest-state.eld ├── forge ├── gamegrid-user-score ├── gdb-bp-session ├── .gitignore ├── .gitmodules ├── gnus ├── helm ├── ielm-history.eld ├── image-dired ├── irony ├── ispell ├── keyfreq.el ├── languagetool ├── ledger ├── logview-cache ├── lsp ├── mc-list.el ├── multisession ├── newsticker ├── nov-save-place.el ├── nsm-settings.el ├── org ├── org-remark ├── persist ├── popweb ├── prescient-save.el ├── projectile ├── project-list.el ├── project-x ├── psession ├── racket-mode ├── recentf-save.el ├── request ├── savehist.el ├── save-place.el ├── semantic ├── shadow ├── speed-type ├── spell-fu ├── srecode-map.el ├── svg-lib ├── tempel-templates ├── tramp ├── transient ├── trash ├── treemacs ├── treesit ├── tree-sitter ├── type-break.el ├── undohist ├── url ├── vimish-fold └── wombag 60 directories, 22 files
Without no-littering, I would either (i) have a ton of directories in my .emacs.d or (ii) have to define my own variables whose values are directories and manually, whenever I install a new package, set their options to write their files into these directories—basically what no-littering already does but without no-littering’s existing integrations. This way, my Emacs directory is neater.
Bonus: (no-littering-theme-backups)
No-littering also provides the little-known no-littering-theme-backups. The TL;DR is this: this function makes Emacs’s built-in auto-saving and backing up functions create files within no-littering’s directories so that sensitive data is not written to disk in unsecured locations. Calling this function sets the value of three variables:
- auto-save-file-name-transforms: Transforms to apply to buffer file name before making auto-save file name.
- backup-directory-alist: Similar to auto-save-file-name-transforms but for backup files.
- undo-tree-history-directory-alist (from undo-tree): Similar to auto-save-file-name-transforms but for backup files.
Its docstring elaborates the mechanism and purpose of this function in greater depth:
|
|