Emacs from scratch again
I’ve been here before, but I find myself back here again. I think that many people who start off with one of the big frameworks (like Spacemacs or Doom Emacs) eventually circle around to thinking, “hey, why don’t I just build my own Emacs config that includes the best bits of Spacemacs/Doom?”. Usually, that is followed some time later (as happened in my case last time), by the realization that those frameworks are really well crafted, and getting anything like that degree of polish and sleekness yourself is very difficult without basically replicating the entirety of those projects. However, I’m playing with configuring from scratch again, just for kicks.
My reasons are nebulous and not very well defined, and can basically be boiled down to — I felt like it.
As I’ve got more comfortable with Doom, I’ve learned a lot more about which
packages work best for me, and how I like things configured, so it has helped me
to narrow down a comfortable setup without a lot of work on my part. There have
also been some new packages out recently, and updates to packages I was using
previously, which have enabled me to build a more streamlined system. The
constellation of what I suppose we might call completion-related packages
(Selectrum/Vertico, Consult, Orderless, Marginalia and Embark, some of which I
wrote about here) have become really sleek and capable, and much easier to
configure than they used to be. The built-in project.el
package handles a
significant subset of the capabilities of projectile
, without needing to load
an external package. projectile
is still a brilliant package, but if you (like
me) only use a small subset of its powers, then project.el
will probably work
well for you. Finally, chemacs has been around for a while, but the latest
version now handles including an early.init.el
in your configurations, which
is useful with more recent versions of Emacs. Chemacs, for those not familiar
with it, is a brilliant tool which enables you to keep several different
versions of Emacs configurations (including either Spacemacs or Doom Emacs)
around and choose to load any one of them. You can even open two versions of
Emacs, one running Doom and one running your new configuration. This makes it
much less disruptive to tinker with your Emacs configuration, because you can
continue to use your working version as normal, as well as editing your
new configuration with your usual Emacs configuration.
First things first, I decided to take the plunge and move to Emacs 28 with
native compilation (gccemacs). I used the d12frosted/emacs-plus formula from
Homebrew, specifying emacs-plus@28 --with-native-comp
as the formula. It took
quite a while for everything to compile, but once finished, it worked
beautifully. Natively compiled Emacs 28 feels a lot more snappy on my Macs, and
I haven’t yet found any problems with running it.
Doom uses a clever custom packaging system which is built on straight.el. I had
also got used to using Doom’s use-package
configuration, which made
everything a bit neater and more modular. When I looked into straight.el
more,
I found that it had a neat way of making configurations completely reproducible
by combining the init file and a versions lockfile. It also works with
use-package
: if you set it up with
(setq straight-use-package-by-default t)
, use-package
will use straight to
fetch and build packages by default. This also means that you are not limited to
packages on the main repositories (like ELPA and MELPA), but you can also
specify those on GitHub or local packages, which increases flexibility. Now that
I have got used to this system, I really like it. If you save a versions file
for a working configuration, you can update packages without worrying that it
will break your system, because you can always restore your system to the
version in the lockfile if things go wrong.
I haven’t finished building all the features I want into my scratch
configuration yet, but it is already comfortable enough to edit the
configuration (and this blog post) with, without having to resort to my Doom
Emacs configuration. I’m still using evil
bindings, and I have started to
build SPC
leader bindings using general.el
so that I have a custom menu of
options without having to remember all the built-in bindings. I’m also using
Vertico for completions which I have really come to like, Orderless for more
advanced completion styles, Marginalia for minibuffer annotations, Embark for
custom actions in the minibuffer and buffer, and Consult for some handy
commands which integrate well with the other packages. All of these packages
build on top of standard Emacs functions (like completing-read
), so
integration is tight and fairly seamless.
I could have just used doom-modeline
or configured my own modeline, but I
tried out telephone-line, really for no other reason that the name is based on a
great ELO song1, and because it’s pretty. I like it a lot, and it turned out to
be quite easy to configure to my liking.
I’m also trying out the new org-cite
framework which is built into Org 9.5,
along with the bibtex-actions package to make it easier to choose, insert and
act on citations. Now that org-cite
and pandoc
can use the same citation
format, it should be much more seamless when including references in documents.
bibtex-actions
is great now that I have it working, but I did get a bit stuck
initially trying to set up the example configuration for org-cite
that is
included in the README. It is probably some interaction with the way that
straight.el
defines packages, but I found that I had to set it up like this
to get it working with Zotero and org-cite
:
(defvar my/bibs '("~/Documents/bibtex/zotero.bib"))
(use-package citeproc)
(use-package bibtex-actions
:bind (("s-b" . org-cite-insert)
("M-o" . org-open-at-point)
:map minibuffer-local-map
("M-b" . bibtex-actions-insert-preset))
:after (embark oc)
:config
(setq bibtex-actions-bibliography my/bibs
org-cite-global-bibliography my/bibs
org-cite-insert-processor 'oc-bibtex-actions
org-cite-follow-processor 'oc-bibtex-actions
org-cite-activate-processor 'oc-bibtex-actions)
(setq org-cite-csl-styles-dir "~/Zotero/styles"))
;; Use consult-completing-read for enhanced interface.
(advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)
;; a hack to get bibtex-actions working
(load "~/.emacs-configs/scratch-emacs/straight/build/bibtex-actions/oc-bibtex-actions.el")
If I didn’t load the oc-bibtex-actions.el
file manually at the end, none of
the variables in the use-package
block got defined. I’m probably missing
something obvious, but this makes it work for me. I will try to remember to log
an issue on the GitHub project to ask what I’m doing wrong.
Anyway, I’m having fun. My custom Emacs config is working pretty well, and it is still snappy to load and run. I’ve learned more along the way about some of the packages that I was just loading blindly before, so it has been a useful process. I wouldn’t lay any bets with myself that I won’t have scurried back to the luxury of my Doom Emacs configuration within a couple of months, but for now I’m enjoying the process!
-
Every time I edit the
telephone-line
config, I sing “Oh, oh, telephone line, give me some time…” ↩︎