I'm using git to keep track of changes to my config files.
I additionally have a script called switch_theme.sh
that switches between dark and light variant of themes. For our purposes, this script goes through a list of files, and sed some lines. For example, for .vimrc, the script has
cfgfile_vim="$HOME/.config/vim/vimrc"
if [[ $switchto = light ]]; then
vimbg="light"
else # dark theme
vimbg="light"
fi
sed -i "s/^set background.*/set background=$vimbg/" "$cfgfile_vim"
However, since I switch quite often between light and dark variant of themes, I do not want to get those lines involved in the git diff.
That's why I thought of filters and clean/smudge. For this reason, in my .gitattributes, I added the line
.config/vim/vimrc filter=ignore-theme
And then I created the clean/smudge rules
dotfiles_mgmt config filter.ignore-theme.clean "$HOME/bin/git_theme_filter.sh clean"
dotfiles_mgmt config filter.ignore-theme.smudge "$HOME/bin/git_theme_filter.sh smudge"
My git_theme_filter.sh
looks like this.
#!/bin/bash -
# Expand $HOME and $XDG_CONFIG correctly
HOME="${HOME:-/home/simone}" # Use $HOME if set, fallback to a default
XDG_CONFIG="${XDG_CONFIG:-$HOME/.config}"
# Declare a global associative array
declare -A config_patterns
# Populate the dictionary with file paths as keys and patterns as values
# ... other config files
config_patterns["$XDG_CONFIG/vim/vimrc"]="^set background="
# Function to process each pattern and apply it to the files
clean() {
for file in "${!config_patterns[@]}"; do
pattern="${config_patterns[$file]}"
# Replace the part after the pattern with THEME_PLACEHOLDER
sed -i -E "s/($pattern).*/\1THEME_PLACEHOLDER/g" "$file"
done
}
smudge() {
"$HOME"/bin/switch_theme.sh dark
}
# Dispatch based on argument
case "$1" in
clean) clean ;;
smudge) smudge ;;
*) echo "Usage: $0 {clean|smudge}" >&2; exit 1 ;;
esac
However, on git-diff -- .config/vim/vimrc
, it seems like all the lines of the file were deleted.
diff --git a/.config/vim/vimrc b/.config/vim/vimrc
index b9c6b45..e69de29 100644
--- a/.config/vim/vimrc
+++ b/.config/vim/vimrc
@@ -1,142 +0,0 @@
-set nocompatible " be iMproved, required
-set encoding=utf-8
-filetype off " required
-set shell=/bin/zsh
-...
Question What am I doing wrong?
I'm using git to keep track of changes to my config files.
I additionally have a script called switch_theme.sh
that switches between dark and light variant of themes. For our purposes, this script goes through a list of files, and sed some lines. For example, for .vimrc, the script has
cfgfile_vim="$HOME/.config/vim/vimrc"
if [[ $switchto = light ]]; then
vimbg="light"
else # dark theme
vimbg="light"
fi
sed -i "s/^set background.*/set background=$vimbg/" "$cfgfile_vim"
However, since I switch quite often between light and dark variant of themes, I do not want to get those lines involved in the git diff.
That's why I thought of filters and clean/smudge. For this reason, in my .gitattributes, I added the line
.config/vim/vimrc filter=ignore-theme
And then I created the clean/smudge rules
dotfiles_mgmt config filter.ignore-theme.clean "$HOME/bin/git_theme_filter.sh clean"
dotfiles_mgmt config filter.ignore-theme.smudge "$HOME/bin/git_theme_filter.sh smudge"
My git_theme_filter.sh
looks like this.
#!/bin/bash -
# Expand $HOME and $XDG_CONFIG correctly
HOME="${HOME:-/home/simone}" # Use $HOME if set, fallback to a default
XDG_CONFIG="${XDG_CONFIG:-$HOME/.config}"
# Declare a global associative array
declare -A config_patterns
# Populate the dictionary with file paths as keys and patterns as values
# ... other config files
config_patterns["$XDG_CONFIG/vim/vimrc"]="^set background="
# Function to process each pattern and apply it to the files
clean() {
for file in "${!config_patterns[@]}"; do
pattern="${config_patterns[$file]}"
# Replace the part after the pattern with THEME_PLACEHOLDER
sed -i -E "s/($pattern).*/\1THEME_PLACEHOLDER/g" "$file"
done
}
smudge() {
"$HOME"/bin/switch_theme.sh dark
}
# Dispatch based on argument
case "$1" in
clean) clean ;;
smudge) smudge ;;
*) echo "Usage: $0 {clean|smudge}" >&2; exit 1 ;;
esac
However, on git-diff -- .config/vim/vimrc
, it seems like all the lines of the file were deleted.
diff --git a/.config/vim/vimrc b/.config/vim/vimrc
index b9c6b45..e69de29 100644
--- a/.config/vim/vimrc
+++ b/.config/vim/vimrc
@@ -1,142 +0,0 @@
-set nocompatible " be iMproved, required
-set encoding=utf-8
-filetype off " required
-set shell=/bin/zsh
-...
Question What am I doing wrong?
Share Improve this question asked Feb 15 at 12:15 tigerjacktigerjack 1,1783 gold badges22 silver badges42 bronze badges 2 |1 Answer
Reset to default 2Switching themes is a deployment step, Git can be pressed into service for this by constructing your deployment in a post-checkout hook. The idea is, track a template file and branch-specific inclusions/alterations, the hook applies the changes to the template and produces your (untracked) deployed file.
https://stackoverflow/a/20087076/1290731 has a fairly simple inclusions processor, you could use .vimrc.@branch
, inclusions named .vimrc.light-theme
etc with branches named light-theme and dark-theme that are just attached to your main history, they aren't separate histories, they're just there for post-checkout. git symbolic-ref refs/heads/light-theme refs/heads/main
and such.
smudge
command is specified, the command is fed the blob object from its standard input, and its standard output is used to update the worktree file. Similarly, theclean
command is used to convert the contents of worktree file upon checkin. By default these commands process only a single blob…" — emph. mine – phd Commented Feb 15 at 13:25