I like to track all of my Linux dotfiles in a single repository so that it’s easy to restore state, even when completely reinstalling the operating system. Recently, I migrated from Linux Mint running i3 desktop to Linux Arch running Hyprland. There was a fair amount of customization work which went pretty well and now that I have stable installs on my laptop and desktop computers I want to add the new dotfiles to my revision control. This is where the gotcha happened. Hyprland has no mechanism for conditionally including configuration, providing some unique challenges to my preferred revision control.
After mulling it over for a few weeks, I’ve come up with a passable approach to conditionally including Hyprland config based on the system hostname. My technique is roughly as follows:
- Source a non-existent
custom-by-hostname.conf
file. - Add a
custom-$HOSTNAME.conf
file for each of your computers. - Use Hyprland to create a symlink for the correct host at startup.
- Bonus: configure Hypridle for different host behavior.
Let’s jump in!
Tracking Hyprland Custom Config
I installed Hyprland using the excellent ml4w-dotfiles
project by Stephan Raabe. It’s a
one stop shop to begin your Hyprland experience with a well-tuned desktop
environment. The project even has customization in mind, including the
~/dotfiles/.config/hypr/conf/custom.conf
file for this very purpose.
Add a line to ~/dotfiles/.config/hypr/conf/custom.conf
to track a non-existent
configuration file.
# Import settings unique to this computer
# This file will be symlinked by Hyprland at start.
source = ~/.config/hypr/conf/custom-by-hostname.conf
Add Custom Config to Hostname-Specific Files
Now add custom config to files that use the hostname of each computer. For now you may simply leave them blank but they need to exist. Here I’ve created two files:
touch ~/dotfiles/.config/hypr/conf/custom-krusty.conf
touch ~/dotfiles/.config/hypr/conf/custom-nelson.conf
Use Hyprland to Create Symlinks
The key to pull it all together is to create a symbolic link using the non-existent filename. But we won’t crate the symlink, Hyprland will.
At the top of the ~/.config/hypr/hyprland.conf
file, add this directive
to create the symlink:
# Import Hyprland settings unique to this computer
# This automatically symlinks the correct file based on hostname
exec-once = ln -s "./custom-$HOSTNAME.conf" ~/dotfiles/.config/hypr/conf/custom-by-hostname.conf &> /dev/null
There are several things to note about the above command. First, Hyprland will
try to create the symbolic every time you login. There’s really no harm in this,
we’re piping both stout and sterr to null so that there are no error messages
when the symlink already exists. Second, the symlink source is relative to the
destination location, so we don’t need a full path. Third, $HOSTNAME
makes an
assumption that your shell has a matching environment variable. If bash is your
preferred shell this will work, it may not for other shells.
Bonus: Conditional config for Hypridle
I want my laptop to automatically suspend after a certain period of time, so it’s nice that ml4w-dotfiles sets this up to happen after 30 minutes. However, I don’t want my main desktop to ever suspend. This provides another unique conditional config challenge as hypridle configuration cannot be stored in the custom.conf file we used above.
The solution I found for this is to change the “listener” behavior based on the
hostname. Here’s the entire block from ~/.config/hypr/hypridle.conf
:
listener {
timeout = 1800
on-timeout = [ $HOSTNAME == "krusty" ] || systemctl suspend
}
The listener is still created with the same 30 minute timeout. However, the
command that is run on this timeout period changes based on the hostname of the
computer. I do not want to suspend my desktop (which is also a home server), so
I start off the command checking if the hostname is krusty
. If that evaluates
to true, the condition is satisfied and execution will end. However, any other
host name will evaluate to false, so execution will move on to the “or” part of
the command after the ||
operators. In this way, Krusty never suspends, but
Nelson does. Bob’s your uncle and my laptop battery life has never been better.
Check Out My dotfiles
Admittedly, ml4w-dotfiles uses a different approach to dotfile tracking than I
do. This setup is a bit less automatic than it used to be… I may need to do a
git restore
after installing an ml4w-dotfiles update. However, all my settings
are now under version control and they work for both of my machines.
If you’re wondering “where’s the code?”, it’s right here.