Switching to straight.el
Some time after first hearing about it, then ignoring it, then seeing it mentioned everywhere, then understanding why it was useful, and then wanting to use it, I finally switched to the straight.el package manager. The primary reason was to better handle packages directly loaded from Git. The secondary reason was the attraction of a reproducible configuration.
The immediate impetus for the switch was finding a pair of packages I wanted to use that aren’t available on MELPA. I’ve encountered such packages before, but this time I was predisposed towards making the switch.
I was already loading packages with use-package, so, once
I had straight.el installed, I replaced
:ensure t with
:straight t. That left about a dozen
packages being loaded from cloned Git repositories with a homegrown
:local keyword in the
use-package form. (
I have a vague memory of there being a way to do that directly with
use-package, but if such a thing does exist, I must not have not known about it at the
time. ) Before I updated those, I made sure I didn’t have
any uncommitted changes.
:straight t was in place, I restarted Emacs a few times, incrementally correcting the
order in which the packages were loaded as errors appeared. I had a bad habit of using nested
use-package forms to conditionally load packages, but straight.el requires that
your init-file must have the effect of running all of the same ,
so I updated all of those cases to use
instead of nesting. That seems like a more sensible approach in any case.
It took a few attempts to understand how to create the lockfile in my version-controlled Emacs
directory rather than the default application data directory. I ultimately needed to set
straight-profiles before bootstrapping straight.el (
unrelated helper functions that produce absolute paths):
(setf straight-build-dir (shiv/local-dir "straight") straight-profiles `((nil . ,(shiv/my-file "straight.lockfile.el")))) ; normal straight.el bootstrap process follows (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 5)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage))
It took 20–25 minutes to build all the packages in my configuration from source, which I had to do twice because of a misunderstanding, and it took another two minutes to update the cache before producing a lockfile, which I also had to do multiple times as I searched for the right way to change the path.
There were a few packages with less simple requirements, which I had heretofore been loading in a more ad hoc fashion. Even then, the most complex—capnp-mode for Cap’n Proto files—took very little to configure correctly. Cloning the repository, narrowing it down to the Emacs Lisp code in a subdirectory, loading it, and associating the mode with the file extension is trivial:
(use-package capnp-mode :straight (capnp-mode :host github :repo "capnproto/capnproto" :files ("highlighting/emacs/*.el")) :mode "\\.capnp\\'")
On the whole, I’m very pleased to have been able to remove significant amounts of custom code and create a more reliable configuration in the bargain. I’m disappointed that pinning packages to tags isn’t possible yet, but recording Git revisions in the lockfile somewhat mitigates the omission.