Load machine-dependent settings in Emacs
Go to file
Case Duckworth 627f5d154c Add theme hooks back 2022-06-13 09:55:15 -05:00
LICENSE Update to 1.0 2022-06-12 23:01:48 -05:00
README.md Update to 1.0 2022-06-12 23:01:48 -05:00
machine.el Add theme hooks back 2022-06-13 09:55:15 -05:00



Easy per-machine configuration in Emacs

There are many solutions to loading machine-dependant code in Emacs. These include guarding forms behind system-type checks, system-name checks, and others. This library attempts to streamline and de-ad-hoc-ify that process, for an easier time of per-machine configuration.

I wrote this package largely to scratch my own itch, so it may be somewhat idiosyncratic. In particular, I have some ease-of-life defcustoms and functions for defining fonts (which I actually don't currently use). Of course, patches, issues, and requests are welcome.


Since this package isn't on Melpa or any other ELPA, you'll need to download it yourself. If you use straight.el, this recipe will work:

(straight-use-package '(machine :url "https://codeberg.org/acdw/machine.el"))

If you otherwise manage your packages, I'm assuming you know how to install one from a git repository.


Using machine is easy. Just call machine-settings-load in your init.el. This function will automatically figure out your machine's attributes, find files named after those attributes, and load them into your current Emacs.

Of course, for machine-settings-load to have any effect, you'll need machine-specific settings files to load. machine looks in machine-load-directory, which is the "machines" subdirectory of your emacs directory by default (e.g., "~/.emacs.d/machines").

These files are plain Emacs Lisp files; you can put any settings or functions or whatever in there that you want to load on only that specific machine.

Determining which files to load

Since there are many ways to differentiate machines, machine allows for multiple ways to segment per-machine functionality. It stores the current machine's attributes in the aptly-named variable machine--attributes, which is a plist with the following keys and values:

  • :type: system-type, which can be gnu/linux, windows-nt, or the like. The docstring for system-type has a list of what symbols it can be.
  • :name: system-name, which is the hostname of the current machine.
  • :user: user-login-name, which is the username of the effective UID (that is, if you're using sudo, it'll be "root").

machine-settings-load will look for files named after each of these values, sanitized to only contain legal filename characters, in the machine-load-directory. To allow for complete clarity in filenames, you can also prepend the attribute names with the name of the attribute.

An example will be illustrative here. Say you have a Windows laptop named "bob," and your username is "bob." machine--attributes will be (:type windows-nt :name "bob" :user "bob"), and machine-settings-load will look for the following files:

  • windows-nt.el
  • type-windows-nt.el
  • bob.el
  • name-bob.el
  • user-bob.el

Because both the username and the machine name are "bob," if you have settings you only want to load on the machine bob, instead of the user bob, you could put those in name-bob.el. This comes in handy if you also have a laptop named "larry" with the same username of "bob."

You can also customize the order of properties to load, using machine-load-order. The default order is more-general to more-specific: (:type :name :user). It's important to remember that files later in the list can override settings defined in earlier-loaded files, so the order here could matter. It hasn't yet, for me, but it might for you.


This work is distributed under the Fair License, the full text of which is below and in LICENSE:

Copyright (C) 2021--2022 C. Duckworth

Usage of the works is permitted provided that this instrument is retained with
the works, so that any entity that uses the works is notified of this