Unclutter Your Home Directory
Table of Contents
It's still a problem for many people: applications create directories and files directly under $HOME
, not even using the freedesktop XDG standard for user directories.
(My filemanager is always set to show hidden files. If yours isn't, try Ctrl-H, you might be surprised what you find.)
Manual cleanup is often required after removing software, but how can we get directories out of the way even for software that's in use?
Before you start ∆
None of the steps here will move existing files/directories, you will always need to do that manually. Whether you use environment variables or some other settings, often you will have to
- stop all graphical programs
- move existing directories to their new locations with terminal commands
- immediately log out/in to activate the new settings
- check if anything managed to write to the old location, if so, delete that
- log out/in again => all should be clean now.
- if it isn't, some apps/scripts are ignoring the new settings? Read on.
Environment variables ∆
Many tips here involve environment variables. There's many different ways to set them for one or all users. This article explains it well.
Mostly we'll need per user settings.
Personally, I start a simple window manager session from ~/.bash_profile
: XINITRC="$XDG_DATA_HOME/xorg/xinitrc" startx
;
therefore I don't know much about desktop environment or display manager specific things.
XDG User Directories ∆
These should be set first of all. Check with
$> env | grep XDG
XDG_DATA_HOME=/home/somebody/.local/share
XDG_CONFIG_HOME=/home/somebody/.config
XDG_SEAT=seat0
XDG_SESSION_TYPE=tty
XDG_CACHE_HOME=/home/somebody/.cache
XDG_SESSION_CLASS=user
XDG_VTNR=1
XDG_SESSION_ID=1
XDG_RUNTIME_DIR=/run/user/1000
Not all of these are set manually, you'll likely want to set those that aren't present when your run that command, e.g.:
# also see system directories in /etc/profile
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"
Move your diretories to their new destinations, then log out/in. This might already remove a lot of clutter.
These paths are the canonical defaults for XDG/freedesktop (but if you want to make sure software uses them you must still set them explicitely). If you want to change these paths, things get much trickier (for applications that use dbus). You will need to change them globally.
The fix is relatively simple but requires root privileges and a full reboot afterwards.
Add something like this to /etc/security/pam_env.conf
:
XDG_CONFIG_HOME DEFAULT=@{HOME}/.local/config
XDG_CACHE_HOME DEFAULT=@{HOME}/.local/cache
XDG_DATA_HOME DEFAULT=@{HOME}/.local/share
XDG_STATE_HOME DEFAULT=@{HOME}/.local/state
This moves the usual ~/.config
and ~/.cache
folders out of sight, inside ~/.local
.
@{HOME}
refers to the home directory of a user as set in/etc/passwd
.
Variables already set in/etc/security/pam_env.conf
can be referenced again with e.g.${XDG_CONFIG_HOME}
.
Apps ∆
gnupg ∆
Defaults to ~/.gnupg
.
export GNUPGHOME='/some/other/dir'
golang ∆
By default, after each compilation, you get a ~/go
folder.
# jetbrains.com/help/go/configuring-goroot-and-gopath.html
export GOPATH="/some/other/path/go"
Rust ∆
By default, after each compilation, you get a ~/.cargo
folder.
# doc.rust-lang.org/cargo/reference/environment-variables.html
export CARGO_HOME="/home/ssd256_data/user_homes/cargo"
npm ∆
export NPM_CONFIG_USERCONFIG='/some/other/dir/npm/rc'
This file (not a directory) should then also contain
cache = /some/other/dir/npm
which otherwise defaults to ~/.npm
Java applications ∆
There's a very simple trick to get all Java stuff out of the way via the user.home
option, which can be set permanently through
the _JAVA_OPTIONS
variable.
export _JAVA_OPTIONS='-Duser.home=/some/other/dir'
Further options can be added, space-separated. Example, including anti-aliasing for fonts and GTK look:
export _JAVA_OPTIONS='-Duser.home=/some/other/dir -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel swing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel'
(Source)
Gradle ∆
(Build system for the JVM) - defaults to ~/.gradle
.
export GRADLE_USER_HOME="/some/other/dir"
# or
export GRADLE_OPTS="$GRADLE_OPTS -Dgradle.user.home=/som/other/dir"
Possibly the last option could also be added to _JAVA_OPTIONS
.
Vim ∆
Vim will detect the config file "$XDG_CONFIG_HOME/vim/vimrc"
but it still tends to drop files
right in your home folder.
There are ways to change it, but I'm relatively new to vim and not sure I got it working 100%.
Wine ∆
By default, wine places itself in ~/.wine
but one can change that with the WINEPREFIX
environment variable. For example:
export WINEPREFIX="$XDG_DATA_HOME/wine"
calc ∆
A very nice interactive commandline calculator. Unfortunately it keeps dropping .calc_history
in my home folder.
Fix:
export CALCHISTFILE="$XDG_DATA_HOME/calc_history"
The sad rest ∆
Unfortunately there are still a lot of applications that cannot be configured in this way, or it's too much work to configure each and every one.
Most annoyingly Firefox (20 years!) and all its derivates. 😢
One can start an app with a different HOME directory, e.g.
$> HOME="$XDG_CONFIG_HOME/nameofgame" nameofgame
(this can have undesired side-effects)
Or write a wrapper script with specific command-line options as a drop-in replacement for the executable, e.g.:
~/.local/bin
is in PATH
. You can create an executable shell script therein named firefox
:
#!/bin/sh
/usr/bin/firefox --profile /path/to/profile "$@"
Since most .desktop
files don't call executables with their full path, this would override starting firefox from a menu, too. Check for yourself with grep Exec= /usr/share/applications/*.desktop
.
Games ∆
Many "classic" (old) games dump their configs and saves right in your home folder. Game managers can provide solutions. I chose to remove all "Games" categories from my graphical menu and use Lutris instead. It will find system-installed games.
It can be configured to override environment variables for all games. Overriding $HOME
only seems to have the pleasant side-effect that it does not affect games that do respect the XDG spec. Screencast (GIF).
lxappearance ∆
Still my favorite theme chooser (there are both gtk2 and gtk3 versions), but it insists on writing configuration to ~/.icons
and ~/.gtkrc-2.0
instead of $XDG_DATA_HOME/icons
and $GTK2_RC_FILES
respectively. GTK3 is OK though.
A wrapperscript is required:
#!/bin/sh
problem() {
notify-send -a lxappearance -i dialog-warning "Something went wrong" "$*"
}
/usr/bin/lxappearance
x=$?
[ -r ~/.gtkrc-2.0 ] && {
mv ~/.gtkrc-2.0 "$XDG_CONFIG_HOME/gtk-2.0/gtkrc" && \
sed -i "s#\.gtkrc-2\.0\.mine#$XDG_CONFIG_HOME/gtk-2.0/gtkrc.mine#" "$XDG_CONFIG_HOME/gtk-2.0/gtkrc" \
|| problem 'moving ~/.gtkrc-2.0'
}
[ -d ~/.icons/default ] && {
rm -rf "$XDG_DATA_HOME/icons/default" && \
mv ~/.icons/default "$XDG_DATA_HOME/icons/" && rmdir ~/.icons \
|| problem 'removing ~/.icons'
}
exit $x
dillo ∆
Fortunately the dillo browser does not object to changing the HOME
environment variable; if this is the only FLTK application you use, you can also move ~/.fltk
out of the way:
mkdir "$XDG_DATA_HOME/dillo"
mv ~/.{fltk,dillo} "$XDG_DATA_HOME/dillo/"
Now, in your personal bin
directory (e.g. $HOME/.local/bin
), create a dillo
executable with the following content:
#!/bin/sh
HOME="$XDG_CONFIG_HOME/dillo"
export HOME
exec /usr/bin/dillo "$@"
nss (~/.pki) ∆
The ~/.pki
directory belongs to nss
.
Long story short, it is possible to create the $XDG_DATA_HOME/pki
folder and hope applications
will use it, but not all of them do (notably chromium browsers).