Unclutter Your Home Directory

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.

Source

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}.

Source

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).