Spring Cleaning $HOME

Introduction

Files, which name begins with a dot are called ‘dotfiles’ or ‘hidden files’ and usually are used for programs configuration. The fun fact is that they never meant to exist and originally was a bug, which was introduced in ls rewrite from Assembly to C. There was a feature to hide . and .. dirs, because they are current and up ones and are in every dir anyway. But this was done with poor check if filename starts with a dot or not, making a dozen of other files “hidden”.

Later this started tendency of every program dumping hidden (or sometimes not!) files in users home dirs without a way to remove them, which is very messy way to do configuration. This post will demonstrate how I got rid of the most dotfiles in my $HOME dir.

Clean-up

First step is to (re)move all files and dirs, which does not need to be in home to respective xdg locations such as documents or pictures. I prefer to have only documents, pictures and music dirs, because it’s all I need. Aside from that I keep all source code in ~/.local/src/ and scripts in ~/.local/bin/. Also I have ~/ set as downloads dir, which helps with putting files to appropriate places (or delete them) instead of having them laying forever in a place where they don’t belong.

Next step is moving dotfiles. Some programs support xdg out of the box and their configs simply can be moved, others have support via environmental variables, and for others you will have to create alias to start them with config in xdg location. Very useful resources for that are:

After all of this, you will still have some dotfiles, that are hardcoded and ‘won’t get fixed’. It probably will be browser dir be it .mozilla or .librewolf for gecko-based or .pki for chromium-based ones. Ssh and dbus dirs are also hardcoded but this is not a big deal, because I cleaned all that was possible and at the end I have 9 directories and 0 files in my ~/.

Unusual tips

I use zsh as my shell and it allows to set $ZDOTDIR to move all it’s files to that dir, but these variable need to be set either in ~/.zshenv or ~/.zprofile or system-wide. I have it set in ~/.config/shell/profile and sourced from /etc/zsh/zprofile line that:

[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/profile" ] &&
	. "${XDG_CONFIG_HOME:-$HOME/.config}/shell/profile"

Another annoyance with zsh is interactive helper, which rans on every shell startup if there is no ~/.z* file(s) in ~/ (even if $ZDOTDIR is set). To disable it you will need to redefine it in /etc/zsh/zshenv:

zsh-newuser-install() { :; }

Another one that needed some work was ~/.git/. I have it, because I use git to track my dotfiles, but this method has some pitfalls, so I killed two birds with one stone. I moved ~/.git/ to ~/.local/src/dotfiles/ and wrote git wrapper to have all my git aliases work with normal repos and dotfiles one.

git() {
	command git rev-parse --is-inside-work-tree >/dev/null 2>&1 ||
		set -- --git-dir="$HOME/.local/src/dotfiles" --work-tree="$HOME" "$@"
	command git "$@"
}