Over on the Fediverse, I shared a little story :
The current state of my GNU Emacs yak shaving:
; wc -l .emacs
1550 .emacsSome of that is comments. Some of that is personal functions that I should move out to other files so I can have only use-package stuff in my .emacs. And some of it is large blocks for lsp-mode and company and some other stuff I'm probably never going to use again, which I should drop.
I got into my .emacs situation despite using use-package , which is the usual way people recommend to tame your Emacs configuration. Today I dealt with the whole thing by splitting my .emacs up into separate files , which is much better in general even if it's a bit more annoying in some ways.
My .emacs had accumulated a number of things over time, probably like many long term Emacs users. Besides infrastructure for use-package, it also had general Emacs settings I want, little personal commands and functions, simple use-package declarations, and a number of large, complex use-package declarations for packages that I need to significantly customize and tweak (and where I had lots of comments about the situation, written for my future self). Plus it also had commented out remains of experiments with things like origami-mode.
Some of these things I could remove to cut down my .emacs size, but a lot of them are intrinsically large, especially various use-package declarations. Things like Eglot, Corfu , and Vertico aren't really small packages with little to configure and adjust; they touch core areas of my Emacs experience where I have some strong opinions that don't match their default configurations. Making them work how I want them to is not necessarily a tiny process of one or two customizations. Using use-package basically encourages putting those customizations inline, as part of the overall
use-package
declaration, including little helper functions.
(Plus, modern modular things like Eglot require a bunch of additional packages for the full experience , and a bunch of small use-package declarations add up, especially when I add comments about why I have them.)
I took two approaches in my split. For personal functions and key bindings, I set up a number of new personal packages in
~/share/elisp
and configured them in new
use-package
blocks (which also let me set hooks and establish key bindings). Then I took existing large use-package declarations (and small ones tied to them) and moved them all to a collection of separate files that I directly '
load-file
' in my .emacs. The separate files are organized by general purpose; I have one for LSP stuff, one for all aspects of completion , one for flymake and flycheck, and one for MH-E. I left unrelated small use-package declarations (many for small packages ) in my .emacs rather than try to push them to a 'miscellaneous' file where I'd probably forget about them.
(The resulting .emacs file has 18 use-package declarations left, five of which are for personal things and some of which are present purely so I can '
:diminish
' their modeline markers.)
What I take from this is that use-package is a perfectly good way to keep things organized but, somewhat obviously, it in no way guarantees that they will stay small or that I will refrain from adding packages.
Sidebar: use-package, load paths, load-file, and require
I don't have my ~/share/elisp directory tree on my Emacs load path, although maybe I should. For my collection of personal functions that I set up with use-package, I used '
:load-path
':
(use-package cks-misc :load-path "~/share/elisp" :commands (....) [...] )
(These things have no use-package usage inside themselves, they're just ELisp functions and so on.)
For the use-package declarations I moved to other files, I put them in ~/share/elisp/startup and did, eg:
(load-file "~/share/elisp/startup/lsp-startup.el")
It's probably more Emacs-proper to put things on my load path and then
require
the relevant name, but the load-file approach works, it directly expresses what I'm doing, and it hopefully makes it clear to future me that these aren't anything like normal packages.
Incidentally, as I discovered in the process of writing this entry but my readers may already know, when you use use-package's '
:load-path
', the directory is permanently added to '
load-path
'; it's not just used once for this use-package (this is sort of spelled out in the documentation if you read carefully). I'm still going to use '
:load-path
' on everything that 'needs' it, although now I'm more tempted than before to extend '
load-path
' to my ~/share/elisp in my .emacs setup code.