new-ryuslash.org/emacs/package-based-configuration.org

4.3 KiB

Package-based Configuration

I've been using a configuration based on using package.el to manage loading, installing, and configuring packages.

Motivation

I've been configuring Emacs since around 2008. My configuration has grown quite a bit since I first started. I've been working in multiple languages, I've used multiple completion methods, and I've tried multiple ways of keeping my configuration in check.

For a long time I was using a git repository that contained all of my configuration. I tried my best to set everything up with autoloads and everything, and it worked well once everything was installed, but installing it on a new machine was a bit of a pain.

(Apologies if this is a terrible excuse for a flowchart, I don't usually make any) I would clone my git repository, run make to byte-compile my configurations. During byte-compilation it would complain about being unable to load a certain package. Then I'd start Emacs without my configuration and install the package, run make again until and repeat until make finished without errors. Then I'd start Emacs and it would complain about being unable to load other packages. I'd install this package, restart Emacs, and repeat this process until Emacs stopped complaining. That didn't necessarily mean that everything was fine, I might run into other packages that were missing later on.

This was frustrating. I wanted something more flexible and easier to install.

A New Configuration

I had this crazy thought one day that I could use package.el to manage my configuration and do fun things like run all kinds of tests on my configuration to make sure that everything still works as I expect it to. Even just for my configuration this has helped me prevent having to spend time during work to fix certain issues.

My new installation method consists of evaluating a little bit of code:

  (add-to-list 'package-archives '("oni" . "https://ryuslash.org/elpa/"))

Once this is done I install oni-package so that all the repositories that I use get added, and then I can just install each configuration as I want it. If I'm writing Python on this machine, I can install oni-python. This will install Yasnippet, Company, Flycheck, Lsp, etc.

It does this just through regular package dependencies. In the oni-python package definition I have just any old Package-Requires line:

  ;; Package-Requires: (oni-yasnippet oni-company oni-fci oni-flycheck oni-hydra oni-lsp rainbow-delimiters reformatter traad)

The oni- prefixed packages are my configuration for those particular modes. Because Company and friends are big enough projects that they'll have their own configuration that I want to include whenever I use that package.

Autoloading magic

In order to allow me to just download the package and have my configuration work, I abuse the autoloading mechanism. The autoload cookie will add whatever form you put after it into the package autoloads file. There are certain forms (like defun) that add a special form to the autoloads file which is just enough to get things set up if it's called, but most forms are just copied over.

  ;;;###autoload(with-eval-after-load 'python (require 'oni-python))