A script for generating config files using templates and xrdb: perfect for applications that disallows configuration through Xresources.
Being able to customize the look-and-feel of various applications in a single place is extremely convenient. For many Linux-users, that place is Xresources. However, not all applications read variables using the xrdb database. Instead, these applications have to be configured purely using their individual config files, which can be a hassle if you e.g want to achieve a coherent color scheme across your system.
This script resolves this issue. Create a template of your config file and indicate where you want to read values from the xrdb database. Run the script, and a new config file will be produced using the specified values.
Every time you edit Xresources or make changes in your template (which you should edit now, instead of your regular config file), run this script for your new changes to take effect.
Some applications requre restart for new settings to be used. This script also has support for running a reload script written by the user, that could be configured to restart the affected applications.
More under usage.
This is just a simple bash script. Getting started shouldn't be that complicated. To use the script correctly, please read usage.
I can't imagine that any of these utilities are not already part of your system, but here's a short list:
- xrdb
- grep
- sort
- sed
- cut
(Unfortunately, the script is not POSIX-compliant, partly due to the use of arrays.)
- Clone the repo
git clone https://github.com/palmdrop/xrdb-replace.git
- Enter the cloned repository
cd xrdb-replace
- Copy the
xrdb-replace
file to somewhere within your path, e.gor run thecp xrdb-replace /usr/local/bin/xrdb-replace
install.sh
scriptsource install.sh
This message is displayed when running xrdb-replace --help
:
usage: $(basename $0) [-options ...] [-f file_path] [-d delimiter] [-r reload_script] [target_file] [prefix]
-F, --from-default Read from default settings file. Usually ~/.config/xrdb-replace/files
-q, --quote Surround xrdb values with quotes in "target_file"
-R, --reload-default Run default reload script. Should be located in the same directory as "target_file" and named "reload.sh"
-g, --glob Use a glob ("*") instead of "prefix" if a specific xrdb value cannot be found
-b, --backup Create a backup of "target_file", named "target_file.bak"
-f, --from-file file_path Use "file_path" as settings file.
-d, --delimiter delimiter Indicates that "delimiter" surrounds every xrdb variable in the template file
-r, --reload reload_script Specifies the name of the reload script to be used
-h, --help Prints this message
target_file The target file to apply the script to. Only used if "-f" or "-F" is not passed
prefix The xrdb prefix used to identify xrdb variables in the template
An example of basic usage:
xrdb-replace ~/.config/app/apprc app
This tells the script to look for a template in the same directory as apprc
. The template should be called apprc.in
, and be identical to your regular config file, except for the values you want to read from the xrdb database. These should be prefixed with app
and surrounded by %
, e.g %app.background%
or %app.foreground%
. These variables will be searched for in the xrdb database.
If this is your regular apprc
# ~/.config/app/apprc
set background #222222
set foreground #dddddd
set borderpx 10
this is a possible template:
# ~/.config/app/apprc.in
set background %app.background%
set foreground %app.foreground%
set borderpx %app.borderpx%
The delimiter %
prevents the script from matching unwanted values. For some config files, this particular symbol might not be optimal. Therefore, the -d
flag can be used to change the delimiter.
After running the script, a temporary copy of the template file will be created, i.e apprc.in.tmp
. The script will then replace all the xrdb variables with the corresponding values read from the xrdb database. Then the script will overwrite the target file (apprc
) with this temporary file. The template will remain untouched. If the script for some reason fails, neither the template nor the target file will be altered.
NOTE: When you want to edit your config file, edit the template instead, otherwise the changes will be overwritten the next time you run the script. My suggested workflow is to create a keybinding or other shortcut for easily running the script whenever needed.
If the -r
(or -R
) flag is passed, the script will attempt to run a user-specified reload script located in the same directory as the target file. This script can be anything, but I suggest using it to restart applications that need to be restarted before new changes to their config files can take effect.
Here's an example of a possible reload script for dunst:
#!/bin/bash
# ~/.config/dunst/reload.sh
killall dunst
notify-send -u low "Testing low"
notify-send -u normal "Testing normal"
notify-send -u critical "Testing critical"
Dunst is automatically started again whenever a notification is sent. Three notifications are immediately sent to observe the effect of the changes.
You often want to apply xrdb changes to many config files at once. This can be done using a settings file. Calling the script using such a file can be done as follows:
xrdb-replace -f ~/.config/xrdb-replace/files
Each line in this file should follow the same structure as the arguments you wish to pass to xrdb-replace, i.e
# ~/.config/xrdb-replace/files
$XDG_CONFIG_HOME/rofi/colors.rasi rofi
$XDG_CONFIG_HOME/dunst/dunstrc dunst -R
$XDG_CONFIG_HOME/zathura/zathurarc zathura -d "#"
For each line, xrdb-replace will be called with that line as its arguments. It's important to note that the arguments defined in the line read from the file takes precedence over the arguments initially passed to the script. E.g, if the script is called as follows,
xrdb-replace -d "!" -f ~/.config/xrdb-replace/files
then !
will be used as a delimiter for all files except the zathurarc, where #
will still be used.
I recommend creating a settings file and putting all the files you'd want to apply the script to there. I then suggest setting up an easy way of calling the script every time you reload xrdb. If you are using vim, an autocommand can be used for this purpose:
autocmd BufWritePost *Xresources,*Xdefaults !xrdb %; xrdb-replace -g -f $HOME/.config/xrdb-replace/files
Place this in your vimrc, and every time you write to your Xresources or Xdefaults file, xrdb will be reloaded and xrdb-replace will be called with your settings file.
Suggestions are much appreciated. Make a fork and create a pull request, or message me directly. I'm still learning bash, so there are likely many things about the script that could be drastically improved.
Distributed under the MIT License. See LICENSE
for more information.
📬 Email (the most reliable way of reaching me)
📷 Instagram (where I showcase some of my artistic projects)
💻 Blog (where I occasionally write posts about generative art)
Some of this code is based on a comment by Reddit user KD2NYT.