about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>1970-01-01 03:00:00 +0300
committerAzat Bahawi <azat@bahawi.net>2022-09-20 11:51:54 +0300
commit38bab29776950ac2364ed64195b89887717c33de (patch)
treeedaaf366a55dbe96d268019124536bc504c64e87
chore: init HEAD master
-rw-r--r--LICENSE14
-rw-r--r--ack/.ackrc52
-rwxr-xr-xack/@install7
-rw-r--r--aria2/.local/etc/aria2/aria2.conf18
-rwxr-xr-xaria2/@install10
-rw-r--r--aspell/.aspell.conf2
-rwxr-xr-xaspell/@install7
-rw-r--r--bash/.bash.d/10_options.bash14
-rw-r--r--bash/.bash.d/20_history.bash10
-rw-r--r--bash/.bash.d/30_completion.bash3
-rw-r--r--bash/.bash.d/60_prompt.bash3
-rw-r--r--bash/.bash_logout6
-rw-r--r--bash/.bash_profile11
-rw-r--r--bash/.bashrc11
-rwxr-xr-xbash/@install10
-rw-r--r--bat/.local/etc/bat/config4
-rwxr-xr-xbat/@install10
-rw-r--r--beets/.local/etc/beets/config.yaml22
-rwxr-xr-xbeets/@install10
-rw-r--r--brittany/.local/etc/brittany/config.yaml49
-rwxr-xr-xbrittany/@install10
-rw-r--r--ccache/.ccache/ccache.conf1
-rwxr-xr-xccache/@install10
-rw-r--r--clang-format/.clang-format80
-rwxr-xr-xclang-format/@install7
-rw-r--r--cmake-format/.cmake-format18
-rwxr-xr-xcmake-format/@install7
-rw-r--r--cppman/.local/etc/cppman/cppman.cfg5
-rwxr-xr-xcppman/@install10
-rw-r--r--ctags/.ctags4
-rwxr-xr-xctags/@install7
-rw-r--r--curl/.curlrc5
-rwxr-xr-xcurl/@install7
-rw-r--r--dhex/.dhexrc43
-rwxr-xr-xdhex/@install7
-rw-r--r--dig/.digrc3
-rwxr-xr-xdig/@install7
-rw-r--r--editorconfig/.editorconfig89
-rwxr-xr-xeditorconfig/@install7
-rw-r--r--fish/.local/etc/fish/conf.d/00_language.fish1
-rw-r--r--fish/.local/etc/fish/conf.d/10_xdg.fish36
-rw-r--r--fish/.local/etc/fish/conf.d/30_path.fish12
-rw-r--r--fish/.local/etc/fish/conf.d/50_browser.fish21
-rw-r--r--fish/.local/etc/fish/conf.d/50_diff.fish16
-rw-r--r--fish/.local/etc/fish/conf.d/50_editor.fish16
-rw-r--r--fish/.local/etc/fish/conf.d/50_pager.fish18
-rw-r--r--fish/.local/etc/fish/conf.d/bear.fish22
-rw-r--r--fish/.local/etc/fish/conf.d/beet.fish9
-rw-r--r--fish/.local/etc/fish/conf.d/ccache.fish11
-rw-r--r--fish/.local/etc/fish/conf.d/doom.fish7
-rw-r--r--fish/.local/etc/fish/conf.d/dotnet.fish14
-rw-r--r--fish/.local/etc/fish/conf.d/fzf.fish4
-rw-r--r--fish/.local/etc/fish/conf.d/git.fish7
-rw-r--r--fish/.local/etc/fish/conf.d/gnupg.fish3
-rw-r--r--fish/.local/etc/fish/config.fish0
-rw-r--r--fish/.local/etc/fish/fish_variables32
-rw-r--r--fish/.local/etc/fish/functions/ag.fish3
-rw-r--r--fish/.local/etc/fish/functions/disk.fish5
-rw-r--r--fish/.local/etc/fish/functions/ram.fish5
-rw-r--r--fish/.local/etc/fish/functions/sudo.fish5
-rwxr-xr-xfish/@install19
-rw-r--r--fontconfig/.local/etc/fontconfig/fonts.conf257
-rwxr-xr-xfontconfig/@install10
-rw-r--r--gdb/.gdbinit43
-rwxr-xr-xgdb/@install7
-rw-r--r--ghc/.ghc/ghci.conf39
-rwxr-xr-xghc/@install10
-rw-r--r--git/.gitconfig84
-rw-r--r--git/.gitignore37
-rwxr-xr-xgit/@install7
-rw-r--r--gnupg/.gnupg/dirmngr.conf1
-rw-r--r--gnupg/.gnupg/gpg-agent.conf6
-rw-r--r--gnupg/.gnupg/gpg.conf38
-rwxr-xr-xgnupg/@install10
-rw-r--r--gtk/.local/etc/gtk-2.0/settings.ini19
-rw-r--r--gtk/.local/etc/gtk-3.0/settings.ini19
-rwxr-xr-xgtk/@install12
-rw-r--r--hackport/.hackport/repositories4
-rwxr-xr-xhackport/@install10
-rw-r--r--haskeline/.haskeline3
-rwxr-xr-xhaskeline/@install7
-rw-r--r--htop/.local/etc/htop/htoprc40
-rwxr-xr-xhtop/@install10
-rw-r--r--httpie/.httpie/config.json7
-rwxr-xr-xhttpie/@install10
-rw-r--r--imv/.local/etc/imv/config3
-rwxr-xr-ximv/@install10
-rw-r--r--lftp/.local/etc/lftp/rc14
-rwxr-xr-xlftp/@install10
-rw-r--r--lldb/.lldbinit1
-rwxr-xr-xlldb/@install7
-rw-r--r--mksh/.mkshrc17
-rwxr-xr-xmksh/@install9
-rw-r--r--mpd/.local/etc/mpd/mpd.conf54
-rwxr-xr-xmpd/@install20
-rw-r--r--mpv/.local/etc/mpv/input.conf16
-rw-r--r--mpv/.local/etc/mpv/mpv.conf100
-rw-r--r--mpv/.local/etc/mpv/scripts/autoload.lua129
-rw-r--r--mpv/.local/etc/mpv/scripts/autosub.lua27
-rwxr-xr-xmpv/@install12
-rw-r--r--ncmpcpp/.local/etc/ncmpcpp/bindings393
-rw-r--r--ncmpcpp/.local/etc/ncmpcpp/config124
-rwxr-xr-xncmpcpp/@install14
-rw-r--r--nix/.local/etc/nixpkgs/home.nix577
-rw-r--r--nix/.nix-channels2
-rwxr-xr-xnix/@install10
-rw-r--r--nuget/.nuget/NuGet/NuGet.Config6
-rwxr-xr-xnuget/@install10
-rw-r--r--picom/.local/etc/picom.conf80
-rwxr-xr-xpicom/@install10
-rw-r--r--pip/.local/etc/pip/pip.conf2
-rwxr-xr-xpip/@install10
-rw-r--r--postgres/.psqlrc16
-rwxr-xr-xpostgres/@install7
-rw-r--r--profile/.profile26
-rw-r--r--profile/.profile.d/00_lang.sh4
-rw-r--r--profile/.profile.d/10_xdg.sh39
-rw-r--r--profile/.profile.d/20_history.sh4
-rw-r--r--profile/.profile.d/30_manpath.sh17
-rw-r--r--profile/.profile.d/30_path.sh19
-rw-r--r--profile/.profile.d/40_nix.sh19
-rw-r--r--profile/.profile.d/50_browser.sh28
-rw-r--r--profile/.profile.d/50_diff.sh22
-rw-r--r--profile/.profile.d/50_editor.sh26
-rw-r--r--profile/.profile.d/50_pager.sh24
-rw-r--r--profile/.profile.d/60_devtoolset.sh5
-rw-r--r--profile/.profile.d/60_dotnet.sh16
-rw-r--r--profile/.profile.d/60_go.sh8
-rw-r--r--profile/.profile.d/60_haskell.sh5
-rw-r--r--profile/.profile.d/60_java.sh12
-rw-r--r--profile/.profile.d/60_lisp.sh25
-rw-r--r--profile/.profile.d/60_ocaml.sh8
-rw-r--r--profile/.profile.d/60_python.sh19
-rw-r--r--profile/.profile.d/60_rust.sh8
-rw-r--r--profile/.profile.d/90_alias.sh34
-rw-r--r--profile/.profile.d/90_functions.sh57
-rw-r--r--profile/.profile.d/ag.sh5
-rw-r--r--profile/.profile.d/bat.sh9
-rw-r--r--profile/.profile.d/bear.sh23
-rw-r--r--profile/.profile.d/beet.sh13
-rw-r--r--profile/.profile.d/ccache.sh10
-rw-r--r--profile/.profile.d/df.sh5
-rw-r--r--profile/.profile.d/docker.sh12
-rw-r--r--profile/.profile.d/doom.sh5
-rw-r--r--profile/.profile.d/free.sh5
-rw-r--r--profile/.profile.d/fzf.sh6
-rw-r--r--profile/.profile.d/git.sh12
-rw-r--r--profile/.profile.d/gnupg.sh20
-rw-r--r--profile/.profile.d/grep.sh17
-rw-r--r--profile/.profile.d/hledger.sh5
-rw-r--r--profile/.profile.d/jot.sh7
-rw-r--r--profile/.profile.d/less.sh6
-rw-r--r--profile/.profile.d/llvm.sh12
-rw-r--r--profile/.profile.d/ls.sh25
-rw-r--r--profile/.profile.d/man.sh7
-rw-r--r--profile/.profile.d/mpd.sh5
-rw-r--r--profile/.profile.d/nnn.sh18
-rw-r--r--profile/.profile.d/open.sh19
-rw-r--r--profile/.profile.d/pass.sh16
-rw-r--r--profile/.profile.d/rsync.sh12
-rw-r--r--profile/.profile.d/shellcheck.sh5
-rw-r--r--profile/.profile.d/svn.sh5
-rw-r--r--profile/.profile.d/torrentinfo.sh5
-rw-r--r--profile/.profile.d/uim.sh12
-rw-r--r--profile/.profile.d/units.sh6
-rw-r--r--profile/.profile.d/urxvt.sh6
-rw-r--r--profile/.profile.d/vi.sh17
-rw-r--r--profile/.profile.d/wakatime.sh8
-rw-r--r--profile/.profile.d/wget.sh6
-rw-r--r--profile/.profile.d/wine.sh13
-rwxr-xr-xprofile/@install10
-rw-r--r--pulseaudio/.local/etc/pulse/client.conf37
-rw-r--r--pulseaudio/.local/etc/pulse/daemon.conf89
-rw-r--r--pulseaudio/.local/etc/pulse/default.pa130
-rwxr-xr-xpulseaudio/@install10
-rw-r--r--pylint/.pylintrc570
-rwxr-xr-xpylint/@install7
-rw-r--r--python/.pystartup128
-rwxr-xr-xpython/@install7
-rw-r--r--qutebrowser/.local/etc/qutebrowser/config.py1225
-rwxr-xr-xqutebrowser/@install10
-rw-r--r--r/.Rprofile71
-rwxr-xr-xr/@install7
-rw-r--r--radare2/.radare2rc3
-rwxr-xr-xradare2/@install7
-rw-r--r--readline/.inputrc65
-rwxr-xr-xreadline/@install7
-rw-r--r--readme.org2
-rw-r--r--rhash/.rhashrc2
-rwxr-xr-xrhash/@install7
-rw-r--r--ripgrep/.rgrc50
-rwxr-xr-xripgrep/@install7
-rw-r--r--sbcl/.sbclrc15
-rwxr-xr-xsbcl/@install7
-rw-r--r--sqlite/.sqliterc3
-rwxr-xr-xsqlite/@install7
-rw-r--r--ssh/.ssh/config17
-rwxr-xr-xssh/@install10
-rw-r--r--stack/.stack/config.yaml6
-rw-r--r--stack/.stack/global-project/stack.yaml2
-rwxr-xr-xstack/@install10
-rw-r--r--stow/.stow-global-ignore2
-rwxr-xr-xstow/@install7
-rw-r--r--streamlink/.local/etc/streamlink/config3
-rwxr-xr-xstreamlink/@install10
-rw-r--r--subversion/.subversion/config175
-rwxr-xr-xsubversion/@install10
-rwxr-xr-xsx/.local/etc/sx/sxrc74
-rwxr-xr-xsx/@install10
-rw-r--r--tmux/.tmux.conf66
-rwxr-xr-xtmux/@install10
-rw-r--r--uim/.uim143
-rwxr-xr-xuim/@install12
-rw-r--r--vim/.vim/vimrc236
-rwxr-xr-xvim/@install16
-rw-r--r--wget/.wgetrc13
-rwxr-xr-xwget/@install7
-rw-r--r--xbindkeys/.xbindkeysrc69
-rwxr-xr-xxbindkeys/@install7
-rw-r--r--xdg/.local/etc/user-dirs.conf2
-rw-r--r--xdg/.local/etc/user-dirs.dirs12
-rw-r--r--xdg/.local/etc/user-dirs.locale1
-rwxr-xr-xxdg/@install10
-rw-r--r--xresources/.Xresources4
-rw-r--r--xresources/.Xresources.d/color38
-rw-r--r--xresources/.Xresources.d/font6
-rw-r--r--xresources/.Xresources.d/xcursor5
-rw-r--r--xresources/.Xresources.d/xft9
-rwxr-xr-xxresources/@install10
-rw-r--r--youtube-dl/.local/etc/youtube-dl/config15
-rwxr-xr-xyoutube-dl/@install10
-rw-r--r--zsh/.zlogin28
-rw-r--r--zsh/.zlogout12
-rw-r--r--zsh/.zprofile6
-rw-r--r--zsh/.zsh.d/00_terminfo.zsh16
-rw-r--r--zsh/.zsh.d/10_options.zsh17
-rw-r--r--zsh/.zsh.d/20_history.zsh20
-rw-r--r--zsh/.zsh.d/30_completion.zsh77
-rw-r--r--zsh/.zsh.d/40_keybindings.zsh3
-rw-r--r--zsh/.zsh.d/50_colors.zsh3
-rw-r--r--zsh/.zsh.d/60_prompt.zsh6
-rw-r--r--zsh/.zsh.d/80_plugins.zsh32
-rw-r--r--zsh/.zsh.d/90_external.zsh6
-rw-r--r--zsh/.zshenv18
-rw-r--r--zsh/.zshrc12
-rwxr-xr-xzsh/@install10
246 files changed, 7814 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ee7d6a5
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,14 @@
+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE

+                    Version 2, December 2004

+

+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

+

+ Everyone is permitted to copy and distribute verbatim or modified

+ copies of this license document, and changing it is allowed as long

+ as the name is changed.

+

+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE

+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

+  0. You just DO WHAT THE FUCK YOU WANT TO.

+

diff --git a/ack/.ackrc b/ack/.ackrc
new file mode 100644
index 0000000..4ef2413
--- /dev/null
+++ b/ack/.ackrc
@@ -0,0 +1,52 @@
+--color
+--flush
+--follow
+--ignore-directory=is:.bzr
+--ignore-directory=is:.cabal-sandbox
+--ignore-directory=is:.ccls-cache
+--ignore-directory=is:.git
+--ignore-directory=is:.github
+--ignore-directory=is:.hg
+--ignore-directory=is:.idea
+--ignore-directory=is:.stack-work
+--ignore-directory=is:.svn
+--ignore-directory=is:.vs
+--ignore-directory=is:.vscode
+--ignore-directory=is:CMakeFiles
+--ignore-directory=is:__pycache__
+--ignore-directory=is:autom4te.cache
+--ignore-directory=is:bin/Debug
+--ignore-directory=is:bin/Release
+--ignore-directory=is:build
+--ignore-directory=is:dist
+--ignore-directory=is:dist-newstyle
+--ignore-directory=is:obj
+--ignore-file=ext:P
+--ignore-file=ext:Po
+--ignore-file=ext:crt
+--ignore-file=ext:d
+--ignore-file=ext:in
+--ignore-file=ext:log
+--ignore-file=ext:m4
+--ignore-file=ext:pem
+--ignore-file=is:.clang-format
+--ignore-file=is:.gdb_history
+--ignore-file=is:.nupkg.metadata
+--ignore-file=is:.sublime-settings
+--ignore-file=is:CMakeCache.txt
+--ignore-file=is:CODE_OF_CONDUCT.md
+--ignore-file=is:LICENSE
+--ignore-file=is:cmake_install.cmake
+--ignore-file=is:compile_commands.json
+--ignore-file=is:config.status
+--ignore-file=is:configure
+--ignore-file=is:depcomp
+--ignore-file=is:install-sh
+--ignore-file=is:ltmain.sh
+--ignore-file=is:missing
+--ignore-file=is:stamp-h1
+--ignore-file=match:/\.ghc\.environment\..*/
+--ignore-file=match:/cabal\.project\..*/
+--nobreak
+--smart-case
+--sort-files
diff --git a/ack/@install b/ack/@install
new file mode 100755
index 0000000..8eb8e02
--- /dev/null
+++ b/ack/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ack
diff --git a/aria2/.local/etc/aria2/aria2.conf b/aria2/.local/etc/aria2/aria2.conf
new file mode 100644
index 0000000..7e15303
--- /dev/null
+++ b/aria2/.local/etc/aria2/aria2.conf
@@ -0,0 +1,18 @@
+bt-max-peers=128
+bt-save-metadata=true
+continue=true
+disable-ipv6=true
+enable-dht=true
+enable-peer-exchange=true
+enable-rpc=false
+follow-torrent=true
+log-level=info
+max-connection-per-server=16
+max-overall-upload-limit=1K
+max-tries=5
+max-upload-limit=1K
+min-split-size=1M
+seed-ratio=0.1
+seed-time=0.1
+stream-piece-selector=default
+timeout=60
diff --git a/aria2/@install b/aria2/@install
new file mode 100755
index 0000000..4e3a8bb
--- /dev/null
+++ b/aria2/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/aria2" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/aria2"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    aria2
diff --git a/aspell/.aspell.conf b/aspell/.aspell.conf
new file mode 100644
index 0000000..a6cbe6c
--- /dev/null
+++ b/aspell/.aspell.conf
@@ -0,0 +1,2 @@
+personal /dev/null
+repl /dev/null
diff --git a/aspell/@install b/aspell/@install
new file mode 100755
index 0000000..d8880b7
--- /dev/null
+++ b/aspell/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    aspell
diff --git a/bash/.bash.d/10_options.bash b/bash/.bash.d/10_options.bash
new file mode 100644
index 0000000..fac4943
--- /dev/null
+++ b/bash/.bash.d/10_options.bash
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+[[ $- == *i* ]] && stty -ixon
+
+set -b +H
+
+set -o notify
+
+shopt -s extglob
+shopt -s globstar
+
+shopt -s autocd 2>/dev/null
+shopt -s dirspell 2>/dev/null
+shopt -s cdspell 2>/dev/null
diff --git a/bash/.bash.d/20_history.bash b/bash/.bash.d/20_history.bash
new file mode 100644
index 0000000..942b884
--- /dev/null
+++ b/bash/.bash.d/20_history.bash
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+shopt -s histappend
+shopt -s histreedit
+shopt -s histverify
+
+[[ ${HISTFILE} =~ (_bash)+$ ]] && HISTFILE="${HISTFILE}_bash"
+HISTCONTROL=erasedups:ignorespace
+HISTFILESIZE=$HISTSIZE
+HISTTIMEFORMAT="[%F %T] "
diff --git a/bash/.bash.d/30_completion.bash b/bash/.bash.d/30_completion.bash
new file mode 100644
index 0000000..9ea2fb0
--- /dev/null
+++ b/bash/.bash.d/30_completion.bash
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+complete -A directory cd
diff --git a/bash/.bash.d/60_prompt.bash b/bash/.bash.d/60_prompt.bash
new file mode 100644
index 0000000..c404206
--- /dev/null
+++ b/bash/.bash.d/60_prompt.bash
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+PS1="\[\033[0;32m\]\w\[\033[0m\] \[\033[0;33m\]λ\[\033[0m\] "
diff --git a/bash/.bash_logout b/bash/.bash_logout
new file mode 100644
index 0000000..4ad2227
--- /dev/null
+++ b/bash/.bash_logout
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+if [ -f "${HOME}/.bin/logout-hook" ]; then
+    # shellcheck disable=SC1091
+    source "${HOME}/.bin/logout-hook"
+fi
diff --git a/bash/.bash_profile b/bash/.bash_profile
new file mode 100644
index 0000000..2691445
--- /dev/null
+++ b/bash/.bash_profile
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+if [ -z "${PROFILE_SOURCED}" ] && [ -f "${HOME}"/.profile ]; then
+    # shellcheck disable=SC1091
+    source "${HOME}/.profile"
+fi
+
+if [ -f "${HOME}/.bashrc" ]; then
+    # shellcheck disable=SC1091
+    source "${HOME}/.bashrc"
+fi
diff --git a/bash/.bashrc b/bash/.bashrc
new file mode 100644
index 0000000..2a5ac92
--- /dev/null
+++ b/bash/.bashrc
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+if [ -z "${PROFILE_SOURCED}" ] && [ -f "${HOME}"/.profile ]; then
+    # shellcheck disable=SC1091
+    source "${HOME}/.profile"
+fi
+
+for i in "${HOME}"/.bash.d/*.bash; do
+    # shellcheck disable=SC1090
+    [[ -r "${i}" ]] && source "${i}"
+done
diff --git a/bash/@install b/bash/@install
new file mode 100755
index 0000000..4b99750
--- /dev/null
+++ b/bash/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.bash.d" ] &&
+    mkdir -p "${HOME}/.bash.d"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    bash
diff --git a/bat/.local/etc/bat/config b/bat/.local/etc/bat/config
new file mode 100644
index 0000000..60365dd
--- /dev/null
+++ b/bat/.local/etc/bat/config
@@ -0,0 +1,4 @@
+--style=plain
+--tabs=4
+--theme=base16
+--wrap=never
diff --git a/bat/@install b/bat/@install
new file mode 100755
index 0000000..40c83a4
--- /dev/null
+++ b/bat/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/bat" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/bat"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    bat
diff --git a/beets/.local/etc/beets/config.yaml b/beets/.local/etc/beets/config.yaml
new file mode 100644
index 0000000..63a51a5
--- /dev/null
+++ b/beets/.local/etc/beets/config.yaml
@@ -0,0 +1,22 @@
+---
+library: ~/.local/var/lib/beets/library.db
+directory: ~/music
+plugins: badfiles edit fetchart info mbsync scrub
+import:
+    write: yes
+    copy: yes
+    move: no
+    bell: yes
+match:
+    preferred:
+        countries: [ 'JP', 'GB|UK', 'AU', 'US', 'RU', 'XE' ]
+edit:
+    albumfields: album artist albumartist
+    itemfields: track title album artist albumartist day month year genre
+fetchart:
+    auto: yes
+    cautious: yes
+    cover_names: cover Cover folder Folder art Art album Album front Front
+    sources: filesystem coverart itunes amazon albumart wikipedia
+scrub:
+    auto: yes
diff --git a/beets/@install b/beets/@install
new file mode 100755
index 0000000..f3d0c78
--- /dev/null
+++ b/beets/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/beets" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/beets"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    beets
diff --git a/brittany/.local/etc/brittany/config.yaml b/brittany/.local/etc/brittany/config.yaml
new file mode 100644
index 0000000..1750ae1
--- /dev/null
+++ b/brittany/.local/etc/brittany/config.yaml
@@ -0,0 +1,49 @@
+conf_disable_formatting: false
+conf_debug:
+  dconf_roundtrip_exactprint_only: false
+  dconf_dump_bridoc_simpl_par: false
+  dconf_dump_ast_unknown: false
+  dconf_dump_bridoc_simpl_floating: false
+  dconf_dump_config: true
+  dconf_dump_bridoc_raw: false
+  dconf_dump_bridoc_final: false
+  dconf_dump_bridoc_simpl_alt: false
+  dconf_dump_bridoc_simpl_indent: false
+  dconf_dump_annotations: false
+  dconf_dump_bridoc_simpl_columns: false
+  dconf_dump_ast_full: false
+conf_forward:
+  options_ghc: []
+conf_errorHandling:
+  econf_ExactPrintFallback: ExactPrintFallbackModeInline
+  econf_Werror: false
+  econf_omit_output_valid_check: false
+  econf_produceOutputOnErrors: false
+conf_preprocessor:
+  ppconf_CPPMode: CPPModeAbort
+  ppconf_hackAroundIncludes: false
+conf_obfuscate: false
+conf_roundtrip_exactprint_only: false
+conf_version: 1
+conf_layout:
+  lconfig_reformatModulePreamble: true
+  lconfig_altChooser:
+    tag: AltChooserBoundedSearch
+    contents: 3
+  lconfig_allowSingleLineExportList: false
+  lconfig_importColumn: 50
+  lconfig_hangingTypeSignature: false
+  lconfig_importAsColumn: 50
+  lconfig_alignmentLimit: 30
+  lconfig_allowHangingQuasiQuotes: true
+  lconfig_indentListSpecial: true
+  lconfig_indentAmount: 2
+  lconfig_alignmentBreakOnMultiline: true
+  lconfig_experimentalSemicolonNewlines: false
+  lconfig_cols: 80
+  lconfig_indentPolicy: IndentPolicyFree
+  lconfig_indentWhereSpecial: true
+  lconfig_columnAlignMode:
+    tag: ColumnAlignModeMajority
+    contents: 0.7
+
diff --git a/brittany/@install b/brittany/@install
new file mode 100755
index 0000000..eb27905
--- /dev/null
+++ b/brittany/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/brittany" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/brittany"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    brittany
diff --git a/ccache/.ccache/ccache.conf b/ccache/.ccache/ccache.conf
new file mode 100644
index 0000000..41ceb8d
--- /dev/null
+++ b/ccache/.ccache/ccache.conf
@@ -0,0 +1 @@
+max_size = 4.0G
diff --git a/ccache/@install b/ccache/@install
new file mode 100755
index 0000000..4c90d4f
--- /dev/null
+++ b/ccache/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.ccache" ] && \
+    mkdir -p "${HOME}/.ccache"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ccache
diff --git a/clang-format/.clang-format b/clang-format/.clang-format
new file mode 100644
index 0000000..05ceba4
--- /dev/null
+++ b/clang-format/.clang-format
@@ -0,0 +1,80 @@
+---
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: Consecutive
+AlignConsecutiveBitFields: Consecutive
+AlignConsecutiveDeclarations: Consecutive
+AlignConsecutiveMacros: Consecutive
+AlignEscapedNewlines: Right
+AlignOperands: Align
+AlignTrailingComments: false
+AllowAllArgumentsOnNextLine: false
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: Inline
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: All
+AlwaysBreakAfterReturnType: AllDefinitions
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: false
+BinPackParameters: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Allman
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeComma
+BreakInheritanceList: BeforeComma
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DeriveLineEnding: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+IncludeBlocks: Regroup
+IndentCaseBlocks: false
+IndentCaseLabels: false
+IndentExternBlock: NoIndent
+IndentGotoLabels: false
+IndentPPDirectives: None
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: false
+Language: Cpp
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+PointerAlignment: Left
+ReflowComments: false
+SortIncludes: CaseSensitive
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInContainerLiterals: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Latest
+TabWidth: 4
+UseTab: Always
+...
diff --git a/clang-format/@install b/clang-format/@install
new file mode 100755
index 0000000..26e0182
--- /dev/null
+++ b/clang-format/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    clang-format
diff --git a/cmake-format/.cmake-format b/cmake-format/.cmake-format
new file mode 100644
index 0000000..c3a5c9b
--- /dev/null
+++ b/cmake-format/.cmake-format
@@ -0,0 +1,18 @@
+---
+format:
+  disable: false
+  line_width: 80
+  tab_size: 4
+  use_tabchars: false
+  fractional_tab_policy: use-space
+  separate_ctrl_name_with_space: false
+  separate_fn_name_with_space: false
+  dangle_parens: false
+  dangle_align: prefix
+  line_ending: unix
+  command_case: lower
+  keyword_case: upper
+  enable_sort: true
+  autosort: false
+...
+# vim: filetype=yaml
diff --git a/cmake-format/@install b/cmake-format/@install
new file mode 100755
index 0000000..d3b4820
--- /dev/null
+++ b/cmake-format/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    cmake-format
diff --git a/cppman/.local/etc/cppman/cppman.cfg b/cppman/.local/etc/cppman/cppman.cfg
new file mode 100644
index 0000000..c47ee76
--- /dev/null
+++ b/cppman/.local/etc/cppman/cppman.cfg
@@ -0,0 +1,5 @@
+[Settings]
+source = cppreference.com
+updatemanpath = true
+pager = system
+
diff --git a/cppman/@install b/cppman/@install
new file mode 100755
index 0000000..9e76255
--- /dev/null
+++ b/cppman/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/cppman" ] &&
+    mkdir -p "${XDG_CONFIG_HOME}/cppman"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    cppman
diff --git a/ctags/.ctags b/ctags/.ctags
new file mode 100644
index 0000000..e6c8d82
--- /dev/null
+++ b/ctags/.ctags
@@ -0,0 +1,4 @@
+--exclude=.*
+--recurse=yes
+--tag-relative=yes
+--totals=yes
diff --git a/ctags/@install b/ctags/@install
new file mode 100755
index 0000000..ebb447d
--- /dev/null
+++ b/ctags/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ctags
diff --git a/curl/.curlrc b/curl/.curlrc
new file mode 100644
index 0000000..9df54c4
--- /dev/null
+++ b/curl/.curlrc
@@ -0,0 +1,5 @@
+connect-timeout = 60
+progress-bar
+referer = ";auto"
+remote-time
+show-error
diff --git a/curl/@install b/curl/@install
new file mode 100755
index 0000000..1bcb15a
--- /dev/null
+++ b/curl/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    curl
diff --git a/dhex/.dhexrc b/dhex/.dhexrc
new file mode 100644
index 0000000..c7209c0
--- /dev/null
+++ b/dhex/.dhexrc
@@ -0,0 +1,43 @@
+#DHEXCOLORSCHEME
+#VERSION 0
+#possible colors are: BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITE
+#possible extra flags are: UNDERLINE,REVERSE,BLINK,DIM,BOLD
+
+BRACKETS:       FG=BLACK,BG=BLACK,BOLD
+HEXFIELD:       FG=WHITE,BG=BLACK
+INPUT:          FG=WHITE,BG=RED,BOLD
+CURSOR:         FG=WHITE,BG=BLACK
+TEXT:           FG=LIGHTCYAN,BG=BLACK,BOLD
+MENU_NORMAL:    FG=LIGHTBLUE,BG=BLACK
+MENU_HIGHLIGHT: FG=LIGHTBLUE,BG=BLUE
+MENU_HOTKEY:    FG=CYAN,BG=BLACK
+MENU_HOTKEY_HI: FG=CYAN,BG=BLUE
+FRAME:          FG=BLUE,BG=BLACK
+NORMAL_DIFF:    FG=YELLOW,BG=BLACK,BOLD
+CURSOR_DIFF:    FG=YELLOW,BG=WHITE,BOLD
+HEADLINE:       FG=BLUE,BG=BLACK
+HEADER:         FG=BLACK,BG=CYAN
+
+KEYESC:1b
+KEYF1:1b 4f 50
+KEYF2:1b 4f 51
+KEYF3:1b 4f 52
+KEYF4:1b 4f 53
+KEYF5:1b 5b 31 35 7e
+KEYF6:1b 5b 31 37 7e
+KEYF7:1b 5b 31 38 7e
+KEYF8:1b 5b 31 39 7e
+KEYF9:1b 5b 32 30 7e
+KEYF10:1b 5b 32 31 7e
+KEYBACKSPACE:7f
+KEYDEL:1b 5b 50
+KEYENTER:0a
+KEYTAB:09
+KEYUP:1b 5b 41
+KEYDOWN:1b 5b 42
+KEYRIGHT:1b 5b 43
+KEYLEFT:1b 5b 44
+KEYPGUP:1b 5b 35 7e
+KEYPGDOWN:1b 5b 36 7e
+KEYHOME:1b 5b 48
+KEYEND:1b 5b 34 7e
diff --git a/dhex/@install b/dhex/@install
new file mode 100755
index 0000000..83bc7f9
--- /dev/null
+++ b/dhex/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    dhex
diff --git a/dig/.digrc b/dig/.digrc
new file mode 100644
index 0000000..7bb28ce
--- /dev/null
+++ b/dig/.digrc
@@ -0,0 +1,3 @@
++answer
++multiline
++recurse
diff --git a/dig/@install b/dig/@install
new file mode 100755
index 0000000..5af6092
--- /dev/null
+++ b/dig/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    dig
diff --git a/editorconfig/.editorconfig b/editorconfig/.editorconfig
new file mode 100644
index 0000000..0bb0c6e
--- /dev/null
+++ b/editorconfig/.editorconfig
@@ -0,0 +1,89 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# Assembly
+[*.{asm,s,S}]
+indent_style = tab
+
+# C/C++
+[*.{c,h,cc,hh,cpp,hpp,cxx,hxx}]
+indent_style = tab
+max_line_length = 80
+trim_trailing_whitespace = false
+insert_final_newline = false
+
+# C#
+[*.cs]
+indent_style = tab
+
+# Go
+[*.go]
+indent_style = tab
+
+# Python
+[*.py]
+max_line_length = 80
+
+# Haskell
+[*.{hs,lhs}]
+indent_size = 2
+
+# Emacs Lisp
+[*.el]
+indent_size = 2
+
+# Common Lisp
+[*.{lisp,cl}]
+indent_size = 2
+
+# Scheme
+[*.scm]
+indent_size = 2
+
+# Make
+[{Makefile,*.mk}]
+indent_style = tab
+
+# CMake
+[{CMakeLists.txt,*.cmake}]
+indent_style = tab
+
+# Autotools
+[*.{ac,am}]
+indent_style = tab
+
+# Shell
+[*.{sh,bash}]
+indent_style = tab
+insert_final_newline = false
+trim_trailing_whitespace = false
+
+# Gentoo
+[*.ebuild]
+indent_style = tab
+
+# RPM Spec
+[*.spec]
+insert_final_newline = false
+trim_trailing_whitespace = false
+
+# Nix
+[*.nix]
+indent_size = 2
+
+# XML
+[*.xml]
+indent_style = tab
+insert_final_newline = false
+trim_trailing_whitespace = false
+
+# Git
+[*.git*]
+indent_style = tab
diff --git a/editorconfig/@install b/editorconfig/@install
new file mode 100755
index 0000000..8c0622f
--- /dev/null
+++ b/editorconfig/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    editorconfig
diff --git a/fish/.local/etc/fish/conf.d/00_language.fish b/fish/.local/etc/fish/conf.d/00_language.fish
new file mode 100644
index 0000000..5779887
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/00_language.fish
@@ -0,0 +1 @@
+set -x LC_COLLATE C
diff --git a/fish/.local/etc/fish/conf.d/10_xdg.fish b/fish/.local/etc/fish/conf.d/10_xdg.fish
new file mode 100644
index 0000000..dfe4125
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/10_xdg.fish
@@ -0,0 +1,36 @@
+#!/bin/fish
+
+set -x XDG_CACHE_HOME       "$HOME/.local/var/cache"
+set -x XDG_CONFIG_HOME      "$HOME/.local/etc"
+set -x XDG_DATA_HOME        "$HOME/.local/var/lib"
+set -x XDG_DESKTOP_DIR      "$HOME/documents"
+set -x XDG_DOCUMENTS_DIR    "$HOME/documents"
+set -x XDG_DOWNLOAD_DIR     "$HOME/downloads"
+set -x XDG_MUSIC_DIR        "$HOME/music"
+set -x XDG_PICTURES_DIR     "$HOME/pictures"
+set -x XDG_PUBLICSHARE_DIR  "$HOME/documents"
+set -x XDG_RUNTIME_DIR      "$HOME/.local/var/run"
+set -x XDG_TEMPLATES_DIR    "$HOME/documents"
+set -x XDG_VIDEOS_DIR       "$HOME/videos"
+
+set xdg_dirs
+set -a xdg_dirs $XDG_CACHE_HOME
+set -a xdg_dirs $XDG_CONFIG_HOME
+set -a xdg_dirs $XDG_DATA_HOME
+set -a xdg_dirs $XDG_DESKTOP_DIR
+set -a xdg_dirs $XDG_DOCUMENTS_DIR
+set -a xdg_dirs $XDG_DOWNLOAD_DIR
+set -a xdg_dirs $XDG_MUSIC_DIR
+set -a xdg_dirs $XDG_PICTURES_DIR
+set -a xdg_dirs $XDG_PUBLICSHARE_DIR
+set -a xdg_dirs $XDG_RUNTIME_DIR
+set -a xdg_dirs $XDG_TEMPLATES_DIR
+set -a xdg_dirs $XDG_VIDEOS_DIR
+
+for i in $xdg_dirs
+    if ! test -d $i
+        mkdir -p $i
+    end
+end
+
+set -e xdg_dirs
diff --git a/fish/.local/etc/fish/conf.d/30_path.fish b/fish/.local/etc/fish/conf.d/30_path.fish
new file mode 100644
index 0000000..b8b6bfa
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/30_path.fish
@@ -0,0 +1,12 @@
+set -e PATH
+
+set PATH
+set -a PATH "/sbin"
+set -a PATH "/bin"
+set -a PATH "/usr/sbin"
+set -a PATH "/usr/bin"
+set -a PATH "/usr/local/bin"
+set -a PATH "$HOME/.bin"
+set -a PATH "$HOME/.local/bin"
+
+set -x PATH
diff --git a/fish/.local/etc/fish/conf.d/50_browser.fish b/fish/.local/etc/fish/conf.d/50_browser.fish
new file mode 100644
index 0000000..0e79ba6
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/50_browser.fish
@@ -0,0 +1,21 @@
+set alts
+set -a alts qutebrowser
+set -a alts librewolf
+set -a alts firefox
+set -a alts chromium
+set -a alts chromium-browser
+set -a alts surf
+set -a alts w3m
+set -a alts lynx
+set -a alts elinks
+set -a alts links
+
+for i in $alts
+    if command -s $i &>/dev/null
+        set -x BROWSER $i
+        alias b $i
+        break
+    end
+end
+
+set -e alts
diff --git a/fish/.local/etc/fish/conf.d/50_diff.fish b/fish/.local/etc/fish/conf.d/50_diff.fish
new file mode 100644
index 0000000..000c93b
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/50_diff.fish
@@ -0,0 +1,16 @@
+set alts
+set -a alts batdiff
+set -a alts colordiff
+set -a alts cwdiff
+set -a alts wdiff
+set -a alts diff
+
+for i in $alts
+    if command -s $i &>/dev/null
+        set -x DIFF $i
+        alias d $i
+        break
+    end
+end
+
+set -e alts
diff --git a/fish/.local/etc/fish/conf.d/50_editor.fish b/fish/.local/etc/fish/conf.d/50_editor.fish
new file mode 100644
index 0000000..a240123
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/50_editor.fish
@@ -0,0 +1,16 @@
+set alts
+set -a alts nvim
+set -a alts vim
+set -a alts vi
+set -a alts nano
+set -a alts ed
+
+for i in $alts
+    if command -s $i &>/dev/null
+        set -x EDITOR $i
+        alias e $i
+        break
+    end
+end
+
+set -e alts
diff --git a/fish/.local/etc/fish/conf.d/50_pager.fish b/fish/.local/etc/fish/conf.d/50_pager.fish
new file mode 100644
index 0000000..dd643b5
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/50_pager.fish
@@ -0,0 +1,18 @@
+set alts
+set -a alts
+set -a alts slit
+set -a alts moar
+set -a alts most
+set -a alts less
+set -a alts more
+set -a alts cat
+
+for i in $alts
+    if command -s $i &>/dev/null
+        set -x PAGER $i
+        alias p $i
+        break
+    end
+end
+
+set -e alts
diff --git a/fish/.local/etc/fish/conf.d/bear.fish b/fish/.local/etc/fish/conf.d/bear.fish
new file mode 100644
index 0000000..096ba44
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/bear.fish
@@ -0,0 +1,22 @@
+if command -s bear &>/dev/null
+    set alts
+    set -a remake
+    set -a make
+
+    for i in $alts
+        if command -s $i &>/dev/null
+            set bear_base="bear --include=./include --include=../include $i"
+            if command -s nproc &>/dev/null
+                alias m "$bear_base --jobs=(math (nproc) + 1)"
+            else
+                alias m "$bear_base"
+            end
+            set -e bear_base
+
+            alias mc "m clean"
+
+            break
+        end
+    end
+    set -e alts
+end
diff --git a/fish/.local/etc/fish/conf.d/beet.fish b/fish/.local/etc/fish/conf.d/beet.fish
new file mode 100644
index 0000000..0882aba
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/beet.fish
@@ -0,0 +1,9 @@
+if command -s beet &>/dev/null
+    set -x BEETSDIR $XDG_DATA_HOME/beets
+
+    set beets_config $XDG_CONFIG_HOME/beets/config.yaml
+    if test -e $beets_config
+        alias beet "beet -c $beets_config"
+    end
+    set -e beets_config
+end
diff --git a/fish/.local/etc/fish/conf.d/ccache.fish b/fish/.local/etc/fish/conf.d/ccache.fish
new file mode 100644
index 0000000..d973e03
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/ccache.fish
@@ -0,0 +1,11 @@
+if command -s ccache &>/dev/null
+    set -x CCACHE_DIR $HOME/.ccache
+
+    set ccache_bin "/usr/lib/ccache/bin"
+    if test -d $ccache_bin
+        set -x CCACHE_PATH $ccache_bin:$PATH
+    else
+        set -x CCACHE_PATH $PATH
+    end
+    set -e ccache_bin
+end
diff --git a/fish/.local/etc/fish/conf.d/doom.fish b/fish/.local/etc/fish/conf.d/doom.fish
new file mode 100644
index 0000000..44cb0c8
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/doom.fish
@@ -0,0 +1,7 @@
+set doom_bin $HOME/.emacs.d/bin
+
+if test -x $doom_bin/doom
+    set -a PATH $doom_bin
+end
+
+set -e doom_bin
diff --git a/fish/.local/etc/fish/conf.d/dotnet.fish b/fish/.local/etc/fish/conf.d/dotnet.fish
new file mode 100644
index 0000000..282aa60
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/dotnet.fish
@@ -0,0 +1,14 @@
+if command -s dotnet &>/dev/null
+    set -a PATH $HOME/.dotnet/tools
+
+    set -x DOTNET_CLI_TELEMETRY_OPTOUT 1
+    set -x DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1
+
+    if command -s nuget &>/dev/null
+        set -x NUGET_CERT_REVOCATION_MODE online
+        set -x NUGET_PERSIST_DG false
+        set -x NUGET_RESTORE_MSBUILD_VERBOSITY normal
+        set -x NUGET_SHOW_STACK true
+        set -x NUGET_XMLDOC_MODE skip
+    end
+end
diff --git a/fish/.local/etc/fish/conf.d/fzf.fish b/fish/.local/etc/fish/conf.d/fzf.fish
new file mode 100644
index 0000000..5f11499
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/fzf.fish
@@ -0,0 +1,4 @@
+if command -s fzf &>/dev/null
+    set -x FZF_DEFAULT_COMMAND
+    set -x FZF_DEFAULT_OPTS "--height 20% --reverse --border"
+end
diff --git a/fish/.local/etc/fish/conf.d/git.fish b/fish/.local/etc/fish/conf.d/git.fish
new file mode 100644
index 0000000..f3c33f5
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/git.fish
@@ -0,0 +1,7 @@
+if command -s git &>/dev/null
+    if command -s hub &>/dev/null
+        alias git hub
+    end
+
+    alias g git
+end
diff --git a/fish/.local/etc/fish/conf.d/gnupg.fish b/fish/.local/etc/fish/conf.d/gnupg.fish
new file mode 100644
index 0000000..ccf9205
--- /dev/null
+++ b/fish/.local/etc/fish/conf.d/gnupg.fish
@@ -0,0 +1,3 @@
+if command -s gpg &>/dev/null
+    set -x GPG_TTY (tty)
+end
diff --git a/fish/.local/etc/fish/config.fish b/fish/.local/etc/fish/config.fish
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fish/.local/etc/fish/config.fish
diff --git a/fish/.local/etc/fish/fish_variables b/fish/.local/etc/fish/fish_variables
new file mode 100644
index 0000000..8fec0ec
--- /dev/null
+++ b/fish/.local/etc/fish/fish_variables
@@ -0,0 +1,32 @@
+# This file contains fish universal variable definitions.
+# VERSION: 3.0
+SETUVAR __fish_initialized:3100
+SETUVAR fish_color_autosuggestion:555\x1ebrblack
+SETUVAR fish_color_cancel:\x2dr
+SETUVAR fish_color_command:005fd7
+SETUVAR fish_color_comment:990000
+SETUVAR fish_color_cwd:green
+SETUVAR fish_color_cwd_root:red
+SETUVAR fish_color_end:009900
+SETUVAR fish_color_error:ff0000
+SETUVAR fish_color_escape:00a6b2
+SETUVAR fish_color_history_current:\x2d\x2dbold
+SETUVAR fish_color_host:normal
+SETUVAR fish_color_host_remote:yellow
+SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue
+SETUVAR fish_color_normal:normal
+SETUVAR fish_color_operator:00a6b2
+SETUVAR fish_color_param:00afff
+SETUVAR fish_color_quote:999900
+SETUVAR fish_color_redirection:00afff
+SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack
+SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack
+SETUVAR fish_color_status:red
+SETUVAR fish_color_user:brgreen
+SETUVAR fish_color_valid_path:\x2d\x2dunderline
+SETUVAR fish_greeting:\x1d
+SETUVAR fish_key_bindings:fish_default_key_bindings
+SETUVAR fish_pager_color_completion:\x1d
+SETUVAR fish_pager_color_description:B3A06D\x1eyellow
+SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
+SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan
diff --git a/fish/.local/etc/fish/functions/ag.fish b/fish/.local/etc/fish/functions/ag.fish
new file mode 100644
index 0000000..6c76e6b
--- /dev/null
+++ b/fish/.local/etc/fish/functions/ag.fish
@@ -0,0 +1,3 @@
+if command -s ag &>/dev/null
+    alias ag "ag --color --smart-case"
+end
diff --git a/fish/.local/etc/fish/functions/disk.fish b/fish/.local/etc/fish/functions/disk.fish
new file mode 100644
index 0000000..ae91056
--- /dev/null
+++ b/fish/.local/etc/fish/functions/disk.fish
@@ -0,0 +1,5 @@
+if command -v df &>/dev/null
+    function disk -w df
+        df --human-readable --exclude-type=tmpfs --exclude-type=devtmpfs $argv
+    end
+end
diff --git a/fish/.local/etc/fish/functions/ram.fish b/fish/.local/etc/fish/functions/ram.fish
new file mode 100644
index 0000000..720328f
--- /dev/null
+++ b/fish/.local/etc/fish/functions/ram.fish
@@ -0,0 +1,5 @@
+if command -v free &>/dev/null
+    function ram -w free
+        free --human --wide
+    end
+end
diff --git a/fish/.local/etc/fish/functions/sudo.fish b/fish/.local/etc/fish/functions/sudo.fish
new file mode 100644
index 0000000..ad84a67
--- /dev/null
+++ b/fish/.local/etc/fish/functions/sudo.fish
@@ -0,0 +1,5 @@
+if command -v doas &>/dev/null and not command -s sudo &>/dev/null
+    function sudo -w doas
+        doas $argv
+    end
+end
diff --git a/fish/@install b/fish/@install
new file mode 100755
index 0000000..63c8393
--- /dev/null
+++ b/fish/@install
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/fish" ] &&
+    mkdir -p "${XDG_CONFIG_HOME}/fish"
+
+[ ! -d "${XDG_CONFIG_HOME}/fish/completions" ] &&
+    mkdir -p "${XDG_CONFIG_HOME}/fish/completions"
+
+[ ! -d "${XDG_CONFIG_HOME}/fish/conf.d" ] &&
+    mkdir -p "${XDG_CONFIG_HOME}/fish/conf.d"
+
+[ ! -d "${XDG_CONFIG_HOME}/fish/functions" ] &&
+    mkdir -p "${XDG_CONFIG_HOME}/fish/functions"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    fish
diff --git a/fontconfig/.local/etc/fontconfig/fonts.conf b/fontconfig/.local/etc/fontconfig/fonts.conf
new file mode 100644
index 0000000..2dd0378
--- /dev/null
+++ b/fontconfig/.local/etc/fontconfig/fonts.conf
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+    <alias>
+        <family>Source Sans Pro</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>Source Code Pro</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <alias>
+        <family>Source Han Sans JP</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>Source Han Sans KR</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>Source Han Sans CN</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>Source Han Sans TW</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 2p</family>
+        <default>
+            <family>serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 2c</family>
+        <default>
+            <family>serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 2m</family>
+        <default>
+            <family>serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 1p</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 1c</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 1m</family>
+        <default>
+            <family>sans-serif</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 1mn</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <alias>
+        <family>M+ 2mn</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <alias>
+        <family>UW Ttyp0</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <!--
+    <match target="pattern">
+        <test qual="any" name="family">
+            <string>UW Ttyp0</string>
+        </test>
+        <test name="weight" compare="more">
+            <const>medium</const>
+        </test>
+        <edit name="weight" mode="assign" binding="same">
+            <const>medium</const>
+        </edit>
+    </match>
+    -->
+    <alias>
+        <family>Efont Biwidth</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <!--
+    <match target="pattern">
+        <test qual="any" name="family">
+            <string>Efont Biwidth</string>
+        </test>
+        <test name="weight" compare="more">
+            <const>medium</const>
+        </test>
+        <edit name="weight" mode="assign" binding="same">
+            <const>medium</const>
+        </edit>
+    </match>
+    -->
+    <alias>
+        <family>Efont Fixed</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <!--
+    <match target="pattern">
+        <test qual="any" name="family">
+            <string>Efont Fixed</string>
+        </test>
+        <test name="weight" compare="more">
+            <const>medium</const>
+        </test>
+        <edit name="weight" mode="assign" binding="same">
+            <const>medium</const>
+        </edit>
+    </match>
+    -->
+    <alias>
+        <family>Misc Batang Wide</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <!--
+    <match target="pattern">
+        <test qual="any" name="family">
+            <string>Misc Batang Wide</string>
+        </test>
+        <test name="weight" compare="more">
+            <const>medium</const>
+        </test>
+        <edit name="weight" mode="assign" binding="same">
+            <const>medium</const>
+        </edit>
+    </match>
+    -->
+    <alias>
+        <family>Misc Gulim Wide</family>
+        <default>
+            <family>monospace</family>
+        </default>
+    </alias>
+    <!--
+    <match target="pattern">
+        <test qual="any" name="family">
+            <string>Misc Gulim Wide</string>
+        </test>
+        <test name="weight" compare="more">
+            <const>medium</const>
+        </test>
+        <edit name="weight" mode="assign" binding="same">
+            <const>medium</const>
+        </edit>
+    </match>
+    -->
+    <match>
+        <test compare="eq" name="family">
+            <string>sans-serif</string>
+        </test>
+        <test compare="eq" name="family">
+            <string>monospace</string>
+        </test>
+        <edit mode="delete" name="family"/>
+    </match>
+    <match>
+        <test compare="eq" name="family">
+            <string>serif</string>
+        </test>
+        <test compare="eq" name="family">
+            <string>monospace</string>
+        </test>
+        <edit mode="delete" name="family"/>
+    </match>
+    <alias>
+        <family>sans-serif</family>
+        <prefer>
+            <family>Source Sans Pro</family>
+            <family>Source Han Sans CN</family>
+            <family>Source Han Sans JP</family>
+            <family>Source Han Sans KR</family>
+            <family>IPA Pゴシック</family>
+            <family>IPAGothic</family>
+            <family>백묵 돋움</family>
+            <family>Bakemuk Dotum</family>
+            <family>DejaVu Sans</family>
+            <family>Droid Sans</family>
+            <family>Noto Sans</family>
+        </prefer>
+    </alias>
+    <alias>
+        <family>serif</family>
+        <prefer>
+            <family>Source Serif Pro</family>
+            <family>Source Han Sans CN</family>
+            <family>Source Han Sans JP</family>
+            <family>Source Han Sans KR</family>
+            <family>IPA明朝</family>
+            <family>IPAMincho</family>
+            <family>백묵 돋움</family>
+            <family>Bakemuk Dotum</family>
+            <family>DejaVu Serif</family>
+            <family>Droid Serif</family>
+            <family>Noto Serif</family>
+        </prefer>
+    </alias>
+    <alias>
+        <family>monospace</family>
+        <prefer>
+            <family>Source Code Pro</family>
+            <family>IPA Pゴシック</family>
+            <family>IPAGothic</family>
+            <family>백묵 돋움</family>
+            <family>Bakemuk Dotum</family>
+            <family>DejaVu Sans Mono</family>
+            <family>Droid Mono</family>
+            <family>Noto Mono</family>
+        </prefer>
+    </alias>
+    <match>
+        <test name="family">
+            <string>UW Ttyp0</string>
+        </test>
+        <edit mode="prepend" name="family">
+            <string>Efont Biwidth</string>
+            <string>Efont Fixed</string>
+            <string>Bakemuk Gulim</string>
+            <string>Bakemuk Batang</string>
+        </edit>
+    </match>
+</fontconfig>
diff --git a/fontconfig/@install b/fontconfig/@install
new file mode 100755
index 0000000..bbfb862
--- /dev/null
+++ b/fontconfig/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/fontconfig" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/fontconfig"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    fontconfig
diff --git a/gdb/.gdbinit b/gdb/.gdbinit
new file mode 100644
index 0000000..f739e8d
--- /dev/null
+++ b/gdb/.gdbinit
@@ -0,0 +1,43 @@
+set confirm off
+set verbose off
+set editing off
+
+set history expansion on
+
+set height 0
+set width  0
+
+handle SIGALRM nostop print nopass
+handle SIGBUS    stop print nopass
+handle SIGPIPE nostop print nopass
+handle SIGSEGV   stop print nopass
+
+set python print-stack full
+
+set print address on
+set print elements 0
+set print object on
+set print pretty on
+set print repeats 0
+set print static-members on
+set print vtbl on
+
+set output-radix 10
+
+set demangle-style gnu-v3
+
+set disassembly-flavor intel
+
+alias iv=info variables
+
+alias da=disassemble
+
+define fs
+    finish
+    step
+end
+
+define btc
+    backtrace
+    continue
+end
diff --git a/gdb/@install b/gdb/@install
new file mode 100755
index 0000000..621a7dc
--- /dev/null
+++ b/gdb/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    gdb
diff --git a/ghc/.ghc/ghci.conf b/ghc/.ghc/ghci.conf
new file mode 100644
index 0000000..9cfcad1
--- /dev/null
+++ b/ghc/.ghc/ghci.conf
@@ -0,0 +1,39 @@
+:set -XBinaryLiterals
+:set -XFlexibleContexts
+:set -XNoMonomorphismRestriction
+
+:seti -XConstraintKinds
+:seti -XDataKinds
+:seti -XDeriveFunctor
+:seti -XFlexibleInstances
+:seti -XFunctionalDependencies
+:seti -XGADTs
+:seti -XLambdaCase
+:seti -XMagicHash
+:seti -XMultiParamTypeClasses
+:seti -XMultiWayIf
+:seti -XOverloadedLabels
+:seti -XPackageImports
+:seti -XPolyKinds
+:seti -XRankNTypes
+:seti -XScopedTypeVariables
+:seti -XStandaloneDeriving
+:seti -XTupleSections
+:seti -XTypeFamilies
+:seti -XTypeOperators
+:seti -XUndecidableInstances
+
+:set +c
+:set +m
+:set +r
+:set +s
+:set +t
+
+:set prompt      "\ESC[1;34mλ\ESC[m\STX \ESC[1;37m>\ESC[m\STX "
+:set prompt-cont "\ESC[1;34m    …\ESC[m\STX \ESC[1;37m>\ESC[m\STX "
+
+:def clear  \_ -> pure (":!clear")
+:def hoogle \x -> pure (":!hoogle --color --count=10 \"" ++ x ++ "\"")
+:def hinfo  \x -> pure (":!hoogle --color --info \""     ++ x ++ "\"")
+
+-- vim: filetype=haskell
diff --git a/ghc/@install b/ghc/@install
new file mode 100755
index 0000000..1ae2a70
--- /dev/null
+++ b/ghc/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.ghc" ] && \
+    mkdir -p "${HOME}/.ghc"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ghc
diff --git a/git/.gitconfig b/git/.gitconfig
new file mode 100644
index 0000000..0394754
--- /dev/null
+++ b/git/.gitconfig
@@ -0,0 +1,84 @@
+[user]
+	name = Azat Bahawi
+	email = azahi@teknik.io
+	signingkey = 0xB40FCB6608BBE3B6
+[core]
+	attributesfile = ~/.gitattributes
+	excludesfile = ~/.gitignore
+	whitespace = trailing-space
+[init]
+	defaultbranch = master
+[commit]
+	gpgsign = true
+[diff]
+	mnemonicprefix = true
+	renames = copies
+	submodule = log
+[branch]
+	autosetupmerge = always
+	autosetuprebase = always
+[merge]
+	conflictstyle = diff3
+	stat = true
+[rebase]
+	autosquash = true
+	autostash = true
+[fetch]
+	prune = true
+[push]
+	default = current
+	followtags = true
+[pull]
+	ff = only
+	rebase = true
+[status]
+	submodulesummary = true
+[rerere]
+	enabled = true
+[advice]
+	detachedhead = false
+	pushnonfastforwards = false
+	statushints = false
+[color]
+	ui = true
+[github]
+	user = azahi
+[alias]
+	ad = add
+	ada = add --all
+	al = config --get-regexp alias
+	br = branch --all
+	ch = checkout
+	cho = checkout --orphan
+	ci = commit
+	cia = commit --amend
+	cias = commit --amend --signoff
+	cl = clone
+	clr = clone --recurse-submodules
+	cls = clone --depth=1
+	cp = cherry-pick
+	di = !"git diff-index --quiet HEAD ; git diff --patch-with-stat"
+	dis = !"git diff-index --quiet HEAD ; git diff --patch-with-stat --staged"
+	fe = fetch
+	fer = fetch --all --recurse-submodules
+	fuck = reset --hard
+	gud = commit --message=\"git gud\"
+	hist = log --all --decorate --abbrev-commit --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
+	lo = log
+	ls = ls-files
+	me = merge
+	mei = merge --interactive
+	pl = pull
+	plr = pull --all --recurse-submodules
+	ps = push
+	rb = rebase
+	rbi = rebase --interactive
+	re = reset HEAD
+	ree = reset HEAD^
+	reee = reset HEAD^^
+	setup = !"git init && git commit --allow-empty -m Initial"
+	st = status --short
+	ui = update-index --assume-unchanged
+	uiu = update-index --un-assume-unchanged
+	wc = whatchanged -p --abbrev-commit --pretty=medium
+	wtc = !"curl -s whatthecommit.com/index.txt | git commit --file -"
diff --git a/git/.gitignore b/git/.gitignore
new file mode 100644
index 0000000..eefa962
--- /dev/null
+++ b/git/.gitignore
@@ -0,0 +1,37 @@
+# Vim
+.netrwhist
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-rt-v][a-z]
+[._]ss[a-gi-z]
+[._]sw[a-p]
+
+# Emacs
+*~
+.dir-locals.el
+\#*\#
+
+# JetBrains
+.idea/
+cmake-build-*/
+
+# VSCode
+.vscode/
+
+# Tags
+.[Tt][Aa][Gg][Ss]
+[Tt][Aa][Gg][Ss]
+![Tt][Aa][Gg][Ss]/
+
+# Misc
+*.bak
+*.tmp
+.ccls-cache/
+.clangd/
+.gdb_history
+.svn/
+.wakatime-project
+a.out
+compile_commands.json
+cscope.*
+vgcore.*
diff --git a/git/@install b/git/@install
new file mode 100755
index 0000000..677a6ab
--- /dev/null
+++ b/git/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    git
diff --git a/gnupg/.gnupg/dirmngr.conf b/gnupg/.gnupg/dirmngr.conf
new file mode 100644
index 0000000..f000ca5
--- /dev/null
+++ b/gnupg/.gnupg/dirmngr.conf
@@ -0,0 +1 @@
+hkp-cacert /usr/share/gnupg/sks-keyservers.netCA.pem
diff --git a/gnupg/.gnupg/gpg-agent.conf b/gnupg/.gnupg/gpg-agent.conf
new file mode 100644
index 0000000..c3b7562
--- /dev/null
+++ b/gnupg/.gnupg/gpg-agent.conf
@@ -0,0 +1,6 @@
+enable-ssh-support
+
+default-cache-ttl 999999
+default-cache-ttl-ssh 999999
+max-cache-ttl 999999
+max-cache-ttl-ssh 999999
diff --git a/gnupg/.gnupg/gpg.conf b/gnupg/.gnupg/gpg.conf
new file mode 100644
index 0000000..77a0bfb
--- /dev/null
+++ b/gnupg/.gnupg/gpg.conf
@@ -0,0 +1,38 @@
+display-charset utf-8
+enable-progress-filter
+fixed-list-mode
+keyid-format 0xlong
+no-comments
+no-emit-version
+no-greeting
+with-fingerprint
+
+armor
+
+use-agent
+
+list-options show-uid-validity show-usage
+verify-options show-uid-validity
+
+default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
+
+personal-cipher-preferences AES256 AES192 AES
+s2k-cipher-algo AES256
+
+personal-digest-preferences SHA512 SHA384 SHA256 SHA224
+digest-algo SHA512
+cert-digest-algo SHA512
+s2k-digest-algo SHA512
+
+personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
+
+no-random-seed-file
+
+keyserver hkps://hkps.pool.sks-keyservers.net
+keyserver hkps://keys.gnupg.net
+keyserver hkps://keys.openpgp.org
+keyserver hkps://pgp.mit.edu
+
+keyserver-options auto-key-retrieve
+keyserver-options no-include-revoked
+keyserver-options no-honor-keyserver-url
diff --git a/gnupg/@install b/gnupg/@install
new file mode 100755
index 0000000..16c43a8
--- /dev/null
+++ b/gnupg/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.gnupg" ] && \
+    mkdir -p "${HOME}/.gnupg"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    gnupg
diff --git a/gtk/.local/etc/gtk-2.0/settings.ini b/gtk/.local/etc/gtk-2.0/settings.ini
new file mode 100644
index 0000000..ff8e840
--- /dev/null
+++ b/gtk/.local/etc/gtk-2.0/settings.ini
@@ -0,0 +1,19 @@
+[Settings]
+gtk-application-prefer-dark-theme = true
+gtk-button-images = 0
+gtk-cursor-theme-name = default
+gtk-cursor-theme-size = 0
+gtk-enable-event-sounds = 0
+gtk-enable-input-feedback-sounds = 0
+gtk-font-name = Source Sans Pro
+gtk-icon-theme-name = Adwaita
+gtk-menu-images = 0
+gtk-recent-files-enabled = 0
+gtk-recent-files-enabled = 0
+gtk-theme-name = "Adwaita"
+gtk-toolbar-icon-size = GTK_ICON_SIZE_MENU
+gtk-toolbar-style = GTK_TOOLBAR_TEXT
+gtk-xft-antialias = 1
+gtk-xft-hinting = 1
+gtk-xft-hintstyle = hintslight
+gtk-xft-rgba = rgb
diff --git a/gtk/.local/etc/gtk-3.0/settings.ini b/gtk/.local/etc/gtk-3.0/settings.ini
new file mode 100644
index 0000000..5a26c09
--- /dev/null
+++ b/gtk/.local/etc/gtk-3.0/settings.ini
@@ -0,0 +1,19 @@
+[Settings]
+gtk-application-prefer-dark-theme = true
+gtk-button-images = 0
+gtk-cursor-theme-name = default
+gtk-cursor-theme-size = 0
+gtk-enable-event-sounds = 0
+gtk-enable-input-feedback-sounds = 0
+gtk-font-name = Source Sans Pro
+gtk-icon-theme-name = Adwaita
+gtk-menu-images = 0
+gtk-recent-files-enabled = 0
+gtk-recent-files-enabled = 0
+gtk-theme-name = Adwaita
+gtk-toolbar-icon-size = GTK_ICON_SIZE_MENU
+gtk-toolbar-style = GTK_TOOLBAR_TEXT
+gtk-xft-antialias = 1
+gtk-xft-hinting = 1
+gtk-xft-hintstyle = hintslight
+gtk-xft-rgba = rgb
diff --git a/gtk/@install b/gtk/@install
new file mode 100755
index 0000000..6b3e26e
--- /dev/null
+++ b/gtk/@install
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/gtk-2.0" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/gtk-2.0"
+[ ! -d "${XDG_CONFIG_HOME}/gtk-3.0" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/gtk-3.0"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    gtk
diff --git a/hackport/.hackport/repositories b/hackport/.hackport/repositories
new file mode 100644
index 0000000..a4a4df2
--- /dev/null
+++ b/hackport/.hackport/repositories
@@ -0,0 +1,4 @@
+Just LocalInfo { distfiles_dir = "/var/cache/distfiles"
+               , overlay_list = [ "/home/azahi/src/gentoo-haskell" ]
+               , portage_dir = "/var/db/repos/gentoo"
+               }
diff --git a/hackport/@install b/hackport/@install
new file mode 100755
index 0000000..e1fa1ff
--- /dev/null
+++ b/hackport/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.hackport" ] && \
+    mkdir -p "${HOME}/.hackport"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    hackport
diff --git a/haskeline/.haskeline b/haskeline/.haskeline
new file mode 100644
index 0000000..e13e210
--- /dev/null
+++ b/haskeline/.haskeline
@@ -0,0 +1,3 @@
+completionPaging: False
+editMode: Vi
+maxHistorySize: Nothing
diff --git a/haskeline/@install b/haskeline/@install
new file mode 100755
index 0000000..abfc135
--- /dev/null
+++ b/haskeline/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    haskeline
diff --git a/htop/.local/etc/htop/htoprc b/htop/.local/etc/htop/htoprc
new file mode 100644
index 0000000..124b34c
--- /dev/null
+++ b/htop/.local/etc/htop/htoprc
@@ -0,0 +1,40 @@
+# Beware! This file is rewritten by htop when settings are changed in the interface.
+# The parser is also very primitive, and not human-friendly.
+fields=0 48 6 17 18 38 39 40 2 46 47 49 1
+sort_key=47
+sort_direction=1
+tree_sort_key=0
+tree_sort_direction=1
+hide_kernel_threads=1
+hide_userland_threads=1
+shadow_other_users=1
+show_thread_names=1
+show_program_path=0
+highlight_base_name=1
+highlight_megabytes=1
+highlight_threads=1
+highlight_changes=1
+highlight_changes_delay_secs=1
+find_comm_in_cmdline=0
+strip_exe_from_cmdline=0
+show_merged_command=0
+tree_view=1
+tree_view_always_by_pid=1
+header_margin=1
+detailed_cpu_time=1
+cpu_count_from_one=0
+show_cpu_usage=1
+show_cpu_frequency=1
+show_cpu_temperature=1
+degree_fahrenheit=0
+update_process_names=1
+account_guest_in_cpu_meter=1
+color_scheme=0
+enable_mouse=0
+delay=10
+left_meters=AllCPUs Memory Swap
+left_meter_modes=1 1 1
+right_meters=Hostname Clock Uptime Tasks LoadAverage Battery
+right_meter_modes=2 2 2 2 2 2
+hide_function_bar=0
+topology_affinity=1
diff --git a/htop/@install b/htop/@install
new file mode 100755
index 0000000..974ac80
--- /dev/null
+++ b/htop/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/htop" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/htop"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    htop
diff --git a/httpie/.httpie/config.json b/httpie/.httpie/config.json
new file mode 100644
index 0000000..4ce0345
--- /dev/null
+++ b/httpie/.httpie/config.json
@@ -0,0 +1,7 @@
+{
+    "default_options": [
+        "--style=default",
+        "--pretty=all",
+        "--sorted"
+    ]
+}
diff --git a/httpie/@install b/httpie/@install
new file mode 100755
index 0000000..503f1d7
--- /dev/null
+++ b/httpie/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.httpie" ] && \
+    mkdir -p "${HOME}/.httpie"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    httpie
diff --git a/imv/.local/etc/imv/config b/imv/.local/etc/imv/config
new file mode 100644
index 0000000..29f576c
--- /dev/null
+++ b/imv/.local/etc/imv/config
@@ -0,0 +1,3 @@
+[options]
+background = 161719
+overlay = false
diff --git a/imv/@install b/imv/@install
new file mode 100755
index 0000000..38e2d0a
--- /dev/null
+++ b/imv/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/imv" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/imv"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    imv
diff --git a/lftp/.local/etc/lftp/rc b/lftp/.local/etc/lftp/rc
new file mode 100644
index 0000000..482fb6a
--- /dev/null
+++ b/lftp/.local/etc/lftp/rc
@@ -0,0 +1,14 @@
+set bmk:save-passwords false
+
+set cache:cache-empty-listings false
+set cache:enable true
+
+set cmd:prompt "\[\e[34m\]\u\[\e[0;34m\]\@\[\e[1m\]\h\[\e[1;30m\]:\[\e[1;34m\]\w\[\e[1;30m\] > \[\e[0m\]"
+set cmd:remote-completion true
+set cmd:save-cwd-history false
+set cmd:save-rl-history false
+
+set color:use-color auto
+
+set ftp:ssl-allow true
+set ftp:ssl-force true
diff --git a/lftp/@install b/lftp/@install
new file mode 100755
index 0000000..3e0ee65
--- /dev/null
+++ b/lftp/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/lftp" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/lftp"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    lftp
diff --git a/lldb/.lldbinit b/lldb/.lldbinit
new file mode 100644
index 0000000..73f3e67
--- /dev/null
+++ b/lldb/.lldbinit
@@ -0,0 +1 @@
+settings set target.x86-disassembly-flavor intel
diff --git a/lldb/@install b/lldb/@install
new file mode 100755
index 0000000..d29177d
--- /dev/null
+++ b/lldb/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    lldb
diff --git a/mksh/.mkshrc b/mksh/.mkshrc
new file mode 100644
index 0000000..ecf7cb2
--- /dev/null
+++ b/mksh/.mkshrc
@@ -0,0 +1,17 @@
+set -o vi
+
+HOSTNAME="$(builtin print -r -- "$(hostname 2>/dev/null)")"
+builtin export HOSTNAME
+
+USER="$(id -un 2>/dev/null)"
+builtin export USER
+
+MKSH="$(builtin whence -p mksh)"
+builtin export SHELL="$MKSH"
+
+if [ -d "$HOME/.shell.d" ]
+then
+    builtin source "$HOME/.shell.d/"*.sh
+fi
+
+# vim: filetype=sh
diff --git a/mksh/@install b/mksh/@install
new file mode 100755
index 0000000..7b589a4
--- /dev/null
+++ b/mksh/@install
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Depends on "shell".
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    mksh
diff --git a/mpd/.local/etc/mpd/mpd.conf b/mpd/.local/etc/mpd/mpd.conf
new file mode 100644
index 0000000..ca77d4f
--- /dev/null
+++ b/mpd/.local/etc/mpd/mpd.conf
@@ -0,0 +1,54 @@
+music_directory         "~/music"
+
+playlist_directory      "~/.local/var/cache"
+
+log_file                "/dev/null"
+log_level               "default"
+
+pid_file                "~/.local/run/mpd.pid"
+
+state_file              "~/.local/var/mpd/state"
+state_file_interval     "60"
+
+sticker_file            "~/.local/var/mpd/sticker.db"
+
+restore_paused          "yes"
+
+auto_update             "no"
+
+follow_outside_symlinks "yes"
+follow_inside_symlinks  "yes"
+
+replaygain              "album"
+replaygain_preamp       "0"
+replaygain_limit        "yes"
+
+volume_normalization    "no"
+
+filesystem_charset      "UTF-8"
+
+bind_to_address         "localhost"
+port                    "6600"
+
+connection_timeout      "10"
+max_connections         "10"
+max_playlist_length     "2048"
+max_command_list_size   "2048"
+max_output_buffer_size  "8192"
+
+zeroconf_enabled        "no"
+
+database {
+    plugin              "simple"
+    path                "~/.local/var/mpd/database.gz"
+    compress            "yes"
+}
+
+audio_output {
+    type                "alsa"
+    name                "ALSA"
+    mixer_type          "software"
+    mixer_control       "PCM"
+}
+
+# vim:filetype=conf
diff --git a/mpd/@install b/mpd/@install
new file mode 100755
index 0000000..c4240a3
--- /dev/null
+++ b/mpd/@install
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/mpd" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/mpd"
+[ ! -d "${XDG_DATA_HOME}/mpd" ] && \
+    mkdir -p "${XDG_DATA_HOME}/mpd"
+[ ! -d "${XDG_DATA_HOME}/mpd/playlists" ] && \
+    mkdir -p "${XDG_DATA_HOME}/mpd/playlists"
+[ ! -f "${XDG_DATA_HOME}/mpd/state" ] && \
+    touch "${XDG_DATA_HOME}/mpd/state"
+[ ! -f "${XDG_DATA_HOME}/mpd/database.gz" ] && \
+    touch "${XDG_DATA_HOME}/mpd/database.gz"
+[ ! -f "${XDG_DATA_HOME}/mpd/sticker.db" ] && \
+    touch "${XDG_DATA_HOME}/mpd/sticker.db"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    mpd
diff --git a/mpv/.local/etc/mpv/input.conf b/mpv/.local/etc/mpv/input.conf
new file mode 100644
index 0000000..ed0a2de
--- /dev/null
+++ b/mpv/.local/etc/mpv/input.conf
@@ -0,0 +1,16 @@
+RIGHT seek  10
+LEFT  seek -10
+UP    seek  60
+DOWN  seek -60
+
+Shift+RIGHT no-osd seek  1 exact
+Shift+LEFT  no-osd seek -1 exact
+Shift+UP    no-osd seek  5 exact
+Shift+DOWN  no-osd seek -5 exact
+
+ALT+k add sub-scale +0.1
+ALT+j add sub-scale -0.1
+
+B cycle-values background "#000000" "#ffffff"
+
+# vim:filetype=config
diff --git a/mpv/.local/etc/mpv/mpv.conf b/mpv/.local/etc/mpv/mpv.conf
new file mode 100644
index 0000000..f365d0b
--- /dev/null
+++ b/mpv/.local/etc/mpv/mpv.conf
@@ -0,0 +1,100 @@
+### General ###
+
+audio-display=no
+autofit-larger=100%x95%
+cursor-autohide=1000
+force-seekable=no
+fullscreen=yes
+load-unsafe-playlists=yes
+msg-color=yes
+msg-module=yes
+prefetch-playlist=yes
+save-position-on-quit=no
+screenshot-format=jpg
+screenshot-template="%F [%p]"
+stop-screensaver=yes
+term-osd-bar=yes
+use-filedir-conf=yes
+
+### OSD ###
+
+osd-bar-align-y=0
+osd-bar-h=2
+osd-bar-w=60
+osd-border-color="#FF262626"
+osd-border-size=2.5
+osd-color="#FFFFFFFF"
+osd-duration=2500
+osd-font-size=40
+osd-fractions=yes
+osd-level=1
+osd-shadow-color="#33000000"
+osd-status-msg='${time-pos} / ${duration}${?percent-pos: (${percent-pos}%)}${?frame-drop-count:${!frame-drop-count==0: Dropped: ${frame-drop-count}}}\n${?chapter:Chapter: ${chapter}}'
+
+### OSC ###
+
+no-osc
+
+### Subtitles ###
+
+sub-auto=fuzzy
+sub-file-paths-append=ass
+sub-file-paths-append=srt
+
+sub-ass-force-margins=yes
+sub-ass-force-style=Kerning=yes
+sub-fix-timing=yes
+sub-use-margins=yes
+
+sub-font-size=40
+sub-color="#FFFFFFFF"
+sub-border-color="#FF262626"
+sub-border-size=2.5
+sub-shadow-offset=1
+sub-shadow-color="#33000000"
+sub-spacing=0.5
+
+### Languages ###
+
+alang=japanese,jp,jpn,jaJP,ja-JP,english,en,eng,enUS,en-US,russian,ru,rus,ruRU,ru-RU
+slang=japanese,jp,jpn,jaJP,ja-JP,english,en,eng,enUS,en-US,russian,ru,rus,ruRU,ru-RU
+
+### youtube-dl ###
+
+ytdl=yes
+ytdl-raw-options=sub-lang="jp,jpn,jaJP,ja-JP,en,eng,enUS,en-US,ru,rus,ruRU,ru-RU",write-sub=
+ytdl-format=(bestvideo[height<=?1080][fps<=?30][protocol!=http_dash_segments])+(bestaudio[acodec=opus]/bestaudio)/best
+
+### Audio ###
+
+audio-file-auto=fuzzy
+
+volume=100
+volume-max=200
+
+### Video ###
+
+blend-subtitles=yes
+
+### Extensions ###
+
+[extension.webm]
+cache=no
+loop-file=inf
+
+[extension.gif]
+profile=extension.webm
+
+### Protocols ###
+
+[protocol.http]
+force-window=immediate
+
+[protocol.https]
+force-window=immediate
+
+### Default ###
+
+[default]
+
+# vim:filetype=cfg
diff --git a/mpv/.local/etc/mpv/scripts/autoload.lua b/mpv/.local/etc/mpv/scripts/autoload.lua
new file mode 100644
index 0000000..2d0a12e
--- /dev/null
+++ b/mpv/.local/etc/mpv/scripts/autoload.lua
@@ -0,0 +1,129 @@
+MAXENTRIES = 30
+
+function Set (t)
+    local set = {}
+    for _, v in pairs(t) do set[v] = true end
+    return set
+end
+
+EXTENSIONS = Set {
+    '3gp',
+    'avi',
+    'flac',
+    'flv',
+    'm4a',
+    'm4v',
+    'mkv',
+    'mp3',
+    'mp4',
+    'mpeg',
+    'mpg',
+    'ogv',
+    'ogv',
+    'rmvb',
+    'wav',
+    'webm',
+    'wma',
+    'wmv',
+}
+
+mputils = require 'mp.utils'
+
+function add_files_at(index, files)
+    index = index - 1
+    local oldcount = mp.get_property_number("playlist-count", 1)
+    for i = 1, #files do
+        mp.commandv("loadfile", files[i], "append")
+        mp.commandv("playlist_move", oldcount + i - 1, index + i - 1)
+    end
+end
+
+function get_extension(path)
+    match = string.match(path, "%.([^%.]+)$" )
+    if match == nil then
+        return "nomatch"
+    else
+        return match
+    end
+end
+
+table.filter = function(t, iter)
+    for i = #t, 1, -1 do
+        if not iter(t[i]) then
+            table.remove(t, i)
+        end
+    end
+end
+
+function find_and_add_entries()
+    local path = mp.get_property("path", "")
+    local dir, filename = mputils.split_path(path)
+    if #dir == 0 then
+        return
+    end
+
+    local files = mputils.readdir(dir, "files")
+    if files == nil then
+        return
+    end
+    table.filter(files, function (v, k)
+        local ext = get_extension(v)
+        if ext == nil then
+            return false
+        end
+        return EXTENSIONS[string.lower(ext)]
+    end)
+    table.sort(files, function (a, b)
+        return string.lower(a) < string.lower(b)
+    end)
+
+    if dir == "." then
+        dir = ""
+    end
+
+    local pl = mp.get_property_native("playlist", {})
+    local pl_current = mp.get_property_number("playlist-pos", 0) + 1
+    local current
+    for i = 1, #files do
+        if files[i] == filename then
+            current = i
+            break
+        end
+    end
+    if current == nil then
+        return
+    end
+
+    local append = {[-1] = {}, [1] = {}}
+    for direction = -1, 1, 2 do
+        for i = 1, MAXENTRIES do
+            local file = files[current + i * direction]
+            local pl_e = pl[pl_current + i * direction]
+            if file == nil or file[1] == "." then
+                break
+            end
+
+            local filepath = dir .. file
+            if pl_e then
+                if pl_e.filename == filepath then
+                    break
+                end
+            end
+
+            if direction == -1 then
+                if pl_current == 1 then
+                    mp.msg.info("Prepending " .. file)
+                    table.insert(append[-1], 1, filepath)
+                end
+            else
+                mp.msg.info("Adding " .. file)
+                table.insert(append[1], filepath)
+            end
+        end
+    end
+
+    add_files_at(pl_current + 1, append[1])
+    add_files_at(pl_current, append[-1])
+end
+
+mp.register_event("start-file", find_and_add_entries)
diff --git a/mpv/.local/etc/mpv/scripts/autosub.lua b/mpv/.local/etc/mpv/scripts/autosub.lua
new file mode 100644
index 0000000..a44564e
--- /dev/null
+++ b/mpv/.local/etc/mpv/scripts/autosub.lua
@@ -0,0 +1,27 @@
+local utils = require 'mp.utils'
+
+function display_error()
+    mp.msg.warn("Subtitle download failed: ")
+    mp.osd_message("Subtitle download failed")
+end
+
+function load_sub_fn()
+    path = mp.get_property("path")
+    srt_path = string.gsub(path, "%.%w+$", ".srt")
+    t = { args = { "subliminal", "download", "-s", "-f", "-l", "en", path } }
+
+    mp.osd_message("Searching subtitle")
+    res = utils.subprocess(t)
+    if res.error == nil then
+        if mp.commandv("sub_add", srt_path) then
+            mp.msg.warn("Subtitle download succeeded")
+            mp.osd_message("Subtitle '" .. srt_path .. "' download succeeded")
+        else
+            display_error()
+        end
+    else
+        display_error()
+    end
+end
+
+mp.add_key_binding("b", "auto_load_subs", load_sub_fn)
diff --git a/mpv/@install b/mpv/@install
new file mode 100755
index 0000000..f90ac62
--- /dev/null
+++ b/mpv/@install
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/mpv" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/mpv"
+[ ! -d "${XDG_CONFIG_HOME}/mpv/script-opts" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/mpv/script-opts"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    mpv
diff --git a/ncmpcpp/.local/etc/ncmpcpp/bindings b/ncmpcpp/.local/etc/ncmpcpp/bindings
new file mode 100644
index 0000000..e7e3327
--- /dev/null
+++ b/ncmpcpp/.local/etc/ncmpcpp/bindings
@@ -0,0 +1,393 @@
+#
+#def_key "mouse"
+#  mouse_event
+#
+def_key "k"
+  scroll_up
+#
+def_key "K"
+  select_item
+  scroll_up
+#
+def_key "j"
+  scroll_down
+#
+def_key "J"
+  select_item
+  scroll_down
+#
+#def_key "["
+#  scroll_up_album
+#
+#def_key "]"
+#  scroll_down_album
+#
+#def_key "{"
+#  scroll_up_artist
+#
+#def_key "}"
+#  scroll_down_artist
+#
+#def_key "page_up"
+#  page_up
+#
+#def_key "page_down"
+#  page_down
+#
+def_key "g"
+  move_home
+#
+def_key "G"
+  move_end
+#
+#def_key "insert"
+#  select_item
+#
+#def_key "enter"
+#  enter_directory
+#
+#def_key "enter"
+#  toggle_output
+#
+#def_key "enter"
+#  run_action
+#
+#def_key "enter"
+#  play_item
+#
+#def_key "space"
+#  add_item_to_playlist
+#
+#def_key "space"
+#  toggle_lyrics_update_on_song_change
+#
+#def_key "space"
+#  toggle_visualization_type
+#
+def_key "d"
+  delete_playlist_items
+#
+def_key "d"
+  delete_browser_items
+#
+def_key "d"
+  delete_stored_playlist
+#
+def_key "l"
+  next_column
+#
+def_key "l"
+  slave_screen
+#
+def_key "l"
+  volume_up
+#
+#def_key "+"
+#  volume_up
+#
+def_key "h"
+  previous_column
+#
+def_key "h"
+  master_screen
+#
+def_key "h"
+  volume_down
+#
+#def_key "-"
+#  volume_down
+#
+#def_key ":"
+#  execute_command
+#
+#def_key "tab"
+#  next_screen
+#
+#def_key "shift-tab"
+#  previous_screen
+#
+#def_key "f1"
+#  show_help
+#
+#def_key "1"
+#  show_playlist
+#
+#def_key "2"
+#  show_browser
+#
+#def_key "2"
+#  change_browse_mode
+#
+#def_key "3"
+#  show_search_engine
+#
+#def_key "3"
+#  reset_search_engine
+#
+#def_key "4"
+#  show_media_library
+#
+#def_key "4"
+#  toggle_media_library_columns_mode
+#
+#def_key "5"
+#  show_playlist_editor
+#
+#def_key "6"
+#  show_tag_editor
+#
+#def_key "7"
+#  show_outputs
+#
+#def_key "8"
+#  show_visualizer
+#
+#def_key "="
+#  show_clock
+#
+#def_key "@"
+#  show_server_info
+#
+#def_key "s"
+#  stop
+#
+#def_key "p"
+#  pause
+#
+#def_key ">"
+#  next
+#
+#def_key "<"
+#  previous
+#
+#def_key "ctrl-h"
+#  jump_to_parent_directory
+#
+#def_key "ctrl-h"
+#  replay_song
+#
+#def_key "backspace"
+#  jump_to_parent_directory
+#
+#def_key "backspace"
+#  replay_song
+#
+#def_key "f"
+#  seek_forward
+#
+#def_key "b"
+#  seek_backward
+#
+#def_key "r"
+#  toggle_repeat
+#
+#def_key "z"
+#  toggle_random
+#
+#def_key "y"
+#  save_tag_changes
+#
+#def_key "y"
+#  start_searching
+#
+#def_key "y"
+#  toggle_single
+#
+#def_key "R"
+#  toggle_consume
+#
+#def_key "Y"
+#  toggle_replay_gain_mode
+#
+#def_key "T"
+#  toggle_add_mode
+#
+#def_key "|"
+#  toggle_mouse
+#
+#def_key "#"
+#  toggle_bitrate_visibility
+#
+#def_key "Z"
+#  shuffle
+#
+#def_key "x"
+#  toggle_crossfade
+#
+#def_key "X"
+#  set_crossfade
+#
+#def_key "u"
+#  update_database
+#
+#def_key "ctrl-s"
+#  sort_playlist
+#
+#def_key "ctrl-s"
+#  toggle_browser_sort_mode
+#
+#def_key "ctrl-s"
+#  toggle_media_library_sort_mode
+#
+#def_key "ctrl-r"
+#  reverse_playlist
+#
+#def_key "ctrl-f"
+#  apply_filter
+#
+#def_key "ctrl-_"
+#  select_found_items
+#
+#def_key "/"
+#  find
+#
+#def_key "/"
+#  find_item_forward
+#
+#def_key "?"
+#  find
+#
+#def_key "?"
+#  find_item_backward
+#
+#def_key "."
+#  next_found_item
+#
+#def_key ","
+#  previous_found_item
+#
+#def_key "w"
+#  toggle_find_mode
+#
+#def_key "e"
+#  edit_song
+#
+#def_key "e"
+#  edit_library_tag
+#
+#def_key "e"
+#  edit_library_album
+#
+#def_key "e"
+#  edit_directory_name
+#
+#def_key "e"
+#  edit_playlist_name
+#
+#def_key "e"
+#  edit_lyrics
+#
+#def_key "i"
+#  show_song_info
+#
+#def_key "I"
+#  show_artist_info
+#
+#def_key "g"
+#  jump_to_position_in_song
+#
+def_key "L"
+  show_lyrics
+#
+#def_key "ctrl-v"
+#  select_range
+#
+#def_key "v"
+#  reverse_selection
+#
+#def_key "V"
+#  remove_selection
+#
+#def_key "B"
+#  select_album
+#
+#def_key "a"
+#  add_selected_items
+#
+#def_key "c"
+#  clear_playlist
+#
+#def_key "c"
+#  clear_main_playlist
+#
+#def_key "C"
+#  crop_playlist
+#
+#def_key "C"
+#  crop_main_playlist
+#
+#def_key "m"
+#  move_sort_order_up
+#
+#def_key "m"
+#  move_selected_items_up
+#
+#def_key "n"
+#  move_sort_order_down
+#
+#def_key "n"
+#  move_selected_items_down
+#
+#def_key "M"
+#  move_selected_items_to
+#
+#def_key "A"
+#  add
+#
+#def_key "S"
+#  save_playlist
+#
+#def_key "o"
+#  jump_to_playing_song
+#
+#def_key "G"
+#  jump_to_browser
+#
+#def_key "G"
+#  jump_to_playlist_editor
+#
+#def_key "~"
+#  jump_to_media_library
+#
+#def_key "E"
+#  jump_to_tag_editor
+#
+#def_key "U"
+#  toggle_playing_song_centering
+#
+#def_key "P"
+#  toggle_display_mode
+#
+#def_key "\\"
+#  toggle_interface
+#
+#def_key "!"
+#  toggle_separators_between_albums
+#
+def_key "H"
+  toggle_lyrics_fetcher
+#
+#def_key "F"
+#  fetch_lyrics_in_background
+#
+#def_key "alt-l"
+#  toggle_fetching_lyrics_in_background
+#
+#def_key "ctrl-l"
+#  toggle_screen_lock
+#
+#def_key "`"
+#  toggle_library_tag_type
+#
+#def_key "`"
+#  refetch_lyrics
+#
+#def_key "`"
+#  add_random_items
+#
+#def_key "ctrl-p"
+#  set_selected_items_priority
+#
+#def_key "q"
+#  quit
+#
diff --git a/ncmpcpp/.local/etc/ncmpcpp/config b/ncmpcpp/.local/etc/ncmpcpp/config
new file mode 100644
index 0000000..3197663
--- /dev/null
+++ b/ncmpcpp/.local/etc/ncmpcpp/config
@@ -0,0 +1,124 @@
+ncmpcpp_directory   = "~/.local/var/lib/ncmpcpp"
+lyrics_directory    = "~/.local/var/lib/ncmpcpp/lyrics"
+
+mpd_host                = "/var/lib/mpd/mpd.socket"
+#mpd_host                = "localhost"
+#mpd_port                = "6600"
+mpd_connection_timeout  = "10"
+mpd_music_dir           = "/media/marisa/music"
+mpd_crossfade_time      = "0"
+
+system_encoding = "UTF-8"
+
+playlist_disable_highlight_delay    = "1"
+message_delay_time                  = "1"
+
+song_window_title_format    = "{%a - }{%t}|{%f}"
+song_list_format            = "{$6%t}|{$2%f}$1 $R{$8%b}$1 {$5%a}"
+song_columns_list_format    = "(20)[red]{a} (30)[cyan]{b} (50)[blue]{t|f}"
+song_status_format          = "{{$8%a$9{ $b-$/b $6%b$9 {(%y)}} - } '{%t}}|{%f}'"
+song_library_format         = "{%n - }{%t}|{%f}"
+
+now_playing_prefix  = "$b$1$8>>>$1 "
+now_playing_suffix  = "$1 $8<<<$1$/b"
+
+selected_item_prefix    = "$0"
+selected_item_suffix    = "$9"
+modified_item_prefix    = "$3> $9"
+
+browser_playlist_prefix = "$2playlist$9 "
+browser_sort_format     = "{%a - }{%t}|{%f} {(%l)}"
+
+playlist_show_mpd_host          = "no"
+playlist_show_remaining_time    = "no"
+playlist_shorten_total_times    = "no"
+playlist_separate_albums        = "no"
+
+playlist_display_mode           = "classic"
+browser_display_mode            = "classic"
+search_engine_display_mode      = "classic"
+playlist_editor_display_mode    = "classic"
+
+incremental_seeking = "yes"
+seek_time           = "1"
+
+volume_change_step  = "5"
+
+autocenter_mode = "yes"
+centered_cursor = "yes"
+
+progressbar_look = "->-"
+
+default_place_to_search_in                      = "database"
+search_engine_default_search_mode               = "1"
+data_fetching_delay                             = "no"
+media_library_primary_tag                       = "album_artist"
+browser_sort_mode                               = "name"
+default_find_mode                               = "wrapped"
+default_tag_editor_pattern                      = "%n - %t"
+empty_tag_marker                                = "<blank>"
+tags_separator                                  = " | "
+tag_editor_extended_numeration                  = "yes"
+media_library_sort_by_mtime                     = "no"
+regular_expressions                             = "none"
+block_search_constraints_change_if_items_found  = "yes"
+
+ignore_leading_the      = "yes"
+
+enable_window_title     = "no"
+
+header_visibility       = "no"
+statusbar_visibility    = "no"
+titles_visibility       = "no"
+
+display_volume_level    = "no"
+display_bitrate         = "no"
+display_remaining_time  = "no"
+
+cyclic_scrolling    = "yes"
+lines_scrolled      = "1"
+
+follow_now_playing_lyrics                   = "no"
+fetch_lyrics_for_current_song_in_background = "no"
+store_lyrics_in_song_dir                    = "no"
+
+generate_win32_compatible_filenames = "yes"
+allow_for_physical_item_deletion    = "no"
+show_hidden_files_in_local_browser  = "no"
+
+screen_switcher_mode                = "playlist, browser"
+startup_screen                      = "playlist"
+startup_slave_screen                = ""
+startup_slave_screen_focus          = "no"
+locked_screen_width_part            = "50"
+ask_for_locked_screen_width_part    = "yes"
+
+jump_to_now_playing_song_at_start   = "no"
+
+ask_before_clearing_playlists   = "no"
+
+clock_display_seconds   = "no"
+
+mouse_support   = "no"
+
+external_editor     = "vim"
+use_console_editor  = "yes"
+
+colors_enabled                      = "yes"
+discard_colors_if_item_is_selected  = "yes"
+
+empty_tag_color                 = "cyan"
+header_window_color             = "cyan"
+volume_color                    = "cyan"
+state_line_color                = "cyan"
+state_flags_color               = "green"
+main_window_color               = "blue"
+color1                          = "cyan"
+color2                          = "red"
+progressbar_color               = "cyan"
+progressbar_elapsed_color       = "white"
+statusbar_color                 = "yellow"
+window_border_color             = "green"
+active_window_border            = "red"
+
+# vim: filetype=config
diff --git a/ncmpcpp/@install b/ncmpcpp/@install
new file mode 100755
index 0000000..e82601b
--- /dev/null
+++ b/ncmpcpp/@install
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/ncmpcpp" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/ncmpcpp"
+[ ! -d "${XDG_DATA_HOME}/ncmpcpp" ] && \
+    mkdir -p "${XDG_DATA_HOME}/ncmpcpp"
+[ ! -d "${XDG_DATA_HOME}/ncmpcpp/lyrics" ] && \
+    mkdir -p "${XDG_DATA_HOME}/ncmpcpp/lyrics"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ncmpcpp
diff --git a/nix/.local/etc/nixpkgs/home.nix b/nix/.local/etc/nixpkgs/home.nix
new file mode 100644
index 0000000..8d367f5
--- /dev/null
+++ b/nix/.local/etc/nixpkgs/home.nix
@@ -0,0 +1,577 @@
+{ config, pkgs, ... }:
+let
+  font1 = "UW Ttyp0";
+  font2 = "Efont Biwidth";
+  xftBase = ":pixelsize=14:style=Regular:antialias=false";
+  xftFont1 = "${font1}${xftBase}";
+  xftFont2 = "${font2}${xftBase}";
+
+  colorBlack0 = "#161719";
+  colorBlack1 = "#969896";
+  colorRed0 = "#cc6666";
+  colorRed1 = "#cc6666";
+  colorGreen0 = "#b5bd68";
+  colorGreen1 = "#b5bd68";
+  colorYellow0 = "#f0c674";
+  colorYellow1 = "#f0c674";
+  colorBlue0 = "#81a2be";
+  colorBlue1 = "#81a2be";
+  colorMagenta0 = "#b294bb";
+  colorMagenta1 = "#b294bb";
+  colorCyan0 = "#8abeb7";
+  colorCyan1 = "#8abeb7";
+  colorWhite0 = "#c5c8c6";
+  colorWhite1 = "#ffffff";
+in {
+  home = {
+    username = builtins.getEnv "USER";
+    homeDirectory = builtins.getEnv "HOME";
+
+    packages = with pkgs; [
+      bat
+      bear
+      ccls
+      clang-tools
+      cling
+      cmake-language-server
+      doxygen
+      fd
+      include-what-you-use
+      llvmPackages_12.clangUseLLVM
+      nixfmt
+      pandoc
+      pgcli
+      pipenv
+      plan9port
+      python-language-server
+      python39Packages.adblock
+      python39Packages.black
+      python39Packages.isort
+      python39Packages.pyflakes
+      rappel
+      ripgrep
+      ripgrep-all
+      shellcheck
+      shfmt
+      speedtest-cli
+      stdman
+      translate-shell
+    ];
+
+    stateVersion = "21.11";
+  };
+
+  xdg = let localDirectory = "${config.home.homeDirectory}/.local";
+  in {
+    configHome = "${localDirectory}/etc";
+    dataHome = "${localDirectory}/var/lib";
+    cacheHome = "${localDirectory}/var/cache";
+
+    userDirs = let
+      atHome = dir: config.home.homeDirectory + "/" + dir;
+      tmp = atHome "tmp";
+    in {
+      enable = true;
+      createDirectories = true;
+
+      desktop = tmp;
+      documents = tmp;
+      download = tmp;
+      music = atHome "music";
+      pictures = tmp;
+      publicShare = tmp;
+      templates = tmp;
+      videos = tmp;
+    };
+  };
+
+  programs = {
+    home-manager.enable = true;
+
+    bat = {
+      enable = true;
+
+      config = {
+        style = "plain";
+        tabs = "4";
+        theme = "base16";
+        wrap = "never";
+      };
+    };
+
+    beets = {
+      enable = true;
+
+      settings = with config.xdg; {
+        library = "${dataHome}/beets/library.db";
+        directory = userDirs.music;
+        plugins = "badfiles edit fetchart info mbsync scrub";
+        original_date = true;
+        import = {
+          write = true;
+          copy = true;
+          move = false;
+          bell = true;
+          from_scratch = true;
+        };
+        match = {
+          preferred = {
+            countries =
+              [ "JP" "KR" "TW" "HK" "CN" "RU" "GB|UK" "AU" "NZ" "US" ];
+            original_year = true;
+          };
+        };
+        edit = {
+          albumfields = "album artist albumartist";
+          itemfields =
+            "track title album artist albumartist day month year genre";
+        };
+        fetchart = {
+          auto = true;
+          cautious = true;
+          cover_names =
+            "cover Cover folder Folder art Art album Album front Front";
+          sources = "filesystem coverart itunes amazon albumart wikipedia";
+        };
+        scrub.auto = true;
+      };
+    };
+
+    direnv = {
+      enable = true;
+      nix-direnv = {
+        enable = true;
+        enableFlakes = true;
+      };
+    };
+
+    neovim = {
+      enable = true;
+
+      extraConfig = ''
+        set autoread
+        set backspace=indent,eol,start
+        set clipboard=unnamed,unnamedplus
+        set fillchars=vert:\ "
+        set hidden
+        set lazyredraw
+        set modeline
+        set mouse=
+        set noshowmode
+        set path+=**
+
+        set statusline=
+        set statusline+=\ %m%r
+        set statusline+=%f\ "
+        set statusline+=%1*
+        set statusline+=%*
+        set statusline+=%=
+        set statusline+=%1*
+        set statusline+=\ %l:%c/%L\ %p%%\ "
+        set statusline+=%*
+
+        set noerrorbells
+        set novisualbell
+
+        set splitbelow
+        set splitright
+
+        set complete=
+        set complete+=.
+        set complete+=b
+        set complete+=t
+        set completeopt=
+        set completeopt+=menu
+        set completeopt+=longest
+
+        set gdefault
+        set hlsearch
+        set incsearch
+        set iskeyword+=-
+        set magic
+
+        set foldmethod=marker
+        set nofoldenable
+
+        set shortmess=
+        set shortmess+=I
+        set shortmess+=T
+        set shortmess+=a
+        set shortmess+=c
+        set shortmess+=t
+
+        set nolist
+        set nowrap
+        set scrolloff=10
+        set sidescrolloff=10
+
+        set number
+        set relativenumber
+
+        set wildignorecase
+        set wildmenu
+        set wildignore=
+
+        set nobackup
+        set noswapfile
+        set noundofile
+        set nowritebackup
+
+        set smartcase
+        set ignorecase
+
+        set autoindent
+        set breakindent
+        set smartindent
+
+        set expandtab
+        set shiftround
+        set shiftwidth=4
+        set smarttab
+        set softtabstop=4
+        set tabstop=4
+
+        try
+            set encoding=utf-8
+            scriptencoding utf-8
+        catch
+        endtry
+
+        if has('autocmd')
+            filetype on
+            filetype plugin on
+            filetype indent on
+        endif
+
+        if has('syntax')
+            syntax enable
+        endif
+
+        let mapleader = ' '
+
+        nnoremap <Expr> j           v:count ? 'j' : 'gj'
+        nnoremap <Expr> k           v:count ? 'k' : 'gk'
+
+        nnoremap        J           gt
+        nnoremap        K           gT
+
+        nnoremap        <C-a>       ^h
+        vnoremap        <C-a>       ^h
+        nnoremap        H           ^h
+        vnoremap        H           ^h
+
+        nnoremap        <C-e>       $
+        vnoremap        <C-e>       $
+        nnoremap        L           $
+        vnoremap        L           $
+
+        nnoremap        N           Nzzzv
+        nnoremap        n           nzzzv
+
+        vnoremap        <           <gv
+        vnoremap        >           >gv
+
+        nnoremap        ]b          :<C-u>bnext<CR>
+        nnoremap        [b          :<C-u>bprevious<CR>
+
+        nnoremap        <C-h>       <C-w>h
+        nnoremap        <C-j>       <C-w>j
+        nnoremap        <C-k>       <C-w>k
+        nnoremap        <C-l>       <C-w>l
+
+        nnoremap        <C-l>       :<C-u>nohlsearch<Bar>redraw!<Bar>echo<CR><C-l>
+
+        cnoremap        ;/          <C-r>=expand('%:p:h').'/'<CR>
+        cnoremap        ;;          <C-r>=expand('%:t')<CR>
+        cnoremap        ;.          <C-r>=expand('%:p:r')<CR>
+
+        nnoremap        <Leader>.   :lcd %:p:h<CR>
+
+        cnoremap        <C-a>       <Home>
+        cnoremap        <C-e>       <End>
+
+        nnoremap        gw          vapgw
+
+        nnoremap        Q           @q
+
+        nnoremap        <Leader>c   ^v$h
+        nnoremap        <Leader>v   ggVG
+
+        map             <Leader>sn  ]s
+        map             <Leader>sp  [s
+        map             <Leader>sa  zg
+        map             <Leader>s?  z=
+
+        nnoremap        <Leader>y   "+y
+        nnoremap        <Leader>Y   "+Y
+
+        nnoremap        <Leader>p   "+p
+        nnoremap        <Leader>P   "+P
+
+        inoremap        <C-v>       <C-c>"+pi
+        cnoremap        <C-v>       <C-r>+
+
+        nmap            <Leader>w   :<C-u>w!<CR>
+        nmap            <Leader>wq  :<C-u>wq!<CR>
+
+        nnoremap        ZX          :<C-u>qa!<CR>
+
+        nnoremap        <Leader>q   :q<CR>
+
+        function! SwitchCase()
+            normal! ~
+            if strlen(getline('.')) != virtcol('.')
+                normal! h
+            endif
+        endfunction
+        nnoremap        ~           :<C-u>call SwitchCase()<CR>
+
+        function! MapGoToTab()
+            let s:i = 1
+            while s:i < 10
+                exe 'nnoremap <Leader>' . s:i . ' :<C-u>tabnext ' . s:i . '<CR>'
+                let s:i += 1
+            endwhile
+        endfunction
+        call MapGoToTab()
+
+        autocmd BufEnter * set noreadonly
+      '';
+
+      plugins = with pkgs.vimPlugins; [
+        ansible-vim
+        auto-pairs
+        calendar-vim
+        csv-vim
+        editorconfig-vim
+        gentoo-syntax
+        neco-vim
+        neoinclude-vim
+        nginx-vim
+        rainbow_parentheses-vim
+        vim-SyntaxRange
+        vim-abolish
+        vim-commentary
+        vim-cool
+        vim-eunuch
+        vim-expand-region
+        vim-fugitive
+        vim-gnupg
+        vim-husk
+        vim-illuminate
+        vim-lastplace
+        vim-nix
+        vim-obsession
+        vim-polyglot
+        vim-repeat
+        vim-rhubarb
+        vim-shellcheck
+        vim-sleuth
+        vim-sneak
+        vim-speeddating
+        vim-surround
+        vim-tmux
+        vim-tmux-focus-events
+        vim-unimpaired
+        {
+          plugin = vim-clang-format;
+          config = ''
+            nnoremap <Buffer><Leader>cf :<C-u>ClangFormat<CR>
+            vnoremap <Buffer><Leader>cf :<C-u>ClangFormat<CR>
+          '';
+        }
+        {
+          plugin = LanguageClient-neovim;
+          config = ''
+            let g:LanguageClient_loadSettings = 1
+
+            nnoremap <Leader>lm :<C-u>call LanguageClient_contextMenu()<CR>
+            nnoremap <Leader>la :<C-u>call LanguageClient_workspace_applyEdit()<CR>
+            nnoremap <Leader>lc :<C-u>call LanguageClient#textDocument_completion()<CR>
+            nnoremap <Leader>ld :<C-u>call LanguageClient#textDocument_definition()<CR>
+            nnoremap <Leader>le :<C-u>call LanguageClient#textDocument_references()<CR>
+            nnoremap <Leader>lf :<C-u>call LanguageClient#textDocument_formatting()<CR>
+            nnoremap <Leader>lh :<C-u>call LanguageClient#textDocument_hover()<CR>
+            nnoremap <Leader>lr :<C-u>call LanguageClient#textDocument_rename()<CR>
+            nnoremap <Leader>ls :<C-u>call LanguageClient#textDocument_documentSymbol()<CR>
+            nnoremap <Leader>lt :<C-u>call LanguageClient#textDocument_typeDefinition()<CR>
+
+            let g:LanguageClient_serverCommands = {}
+
+            if executable('ccls')
+                let g:LanguageClient_serverCommands[ 'c'   ] = [ 'ccls' ]
+                let g:LanguageClient_serverCommands[ 'cpp' ] = [ 'ccls' ]
+
+                nnoremap <Leader>h :<C-u>call LanguageClient#findLocations({'method':'$ccls/navigate','direction':'L'})<CR>
+                nnoremap <Leader>j :<C-u>call LanguageClient#findLocations({'method':'$ccls/navigate','direction':'D'})<CR>
+                nnoremap <Leader>k :<C-u>call LanguageClient#findLocations({'method':'$ccls/navigate','direction':'U'})<CR>
+                nnoremap <Leader>l :<C-u>call LanguageClient#findLocations({'method':'$ccls/navigate','direction':'R'})<CR>
+            elseif executable('clangd')
+                let g:LanguageClient_serverCommands[ 'c'   ] = [ 'clangd', '-background-index' ]
+                let g:LanguageClient_serverCommands[ 'cpp' ] = [ 'clangd', '-background-index' ]
+            endif
+
+            if executable('gopls')
+                let g:LanguageClient_serverCommands[ 'go' ] = [ 'gopls' ]
+            endif
+
+            if executable('haskell-language-server-wrapper')
+                let g:LanguageClient_serverCommands[ 'haskell' ] = [ 'haskell-language-server-wrapper', '--lsp' ]
+            endif
+
+            if executable('pyls')
+                let g:LanguageClient_serverCommands[ 'python' ] = [ 'pyls' ]
+            endif
+          '';
+        }
+      ];
+
+      withNodeJs = false;
+      withPython3 = true;
+      withRuby = false;
+    };
+
+    zathura = {
+      enable = true;
+
+      options = {
+        font = font1;
+
+        default-fg = colorWhite0;
+        default-bg = colorBlack0;
+
+        statusbar-fg = colorBlack0;
+        statusbar-bg = colorWhite0;
+
+        inputbar-fg = colorBlack0;
+        inputbar-bg = colorGreen1;
+
+        notification-fg = colorBlack0;
+        notification-bg = colorBlue1;
+
+        notification-error-fg = colorBlack0;
+        notification-error-bg = colorRed1;
+
+        notification-warning-fg = colorBlack0;
+        notification-warning-bg = colorYellow1;
+
+        highlight-color = colorYellow1;
+        highlight-active-color = colorYellow0;
+
+        completion-fg = colorWhite1;
+        completion-bg = colorBlack1;
+
+        completion-highlight-fg = colorBlack0;
+        completion-highlight-bg = colorRed1;
+
+        completion-group-fg = colorBlack0;
+        completion-group-bg = colorRed1;
+
+        recolor-darkcolor = colorBlack0;
+        recolor-lightcolor = colorWhite0;
+
+        recolor = true;
+        recolor-keephue = false;
+        recolor-reverse-video = false;
+
+        highlight-transparency = "0.3";
+
+        n-completion-items = 10;
+
+        guioptions = "";
+
+        statusbar-basename = true;
+        statusbar-home-tilde = true;
+
+        statusbar-h-padding = 0;
+        statusbar-v-padding = 0;
+
+        window-height = 800;
+        window-width = 600;
+
+        window-icon = "";
+
+        abort-clear-search = true;
+
+        incremental-search = true;
+
+        adjust-open = "best-fit";
+
+        advance-pages-per-row = false;
+
+        database = "sqlite";
+
+        dbus-service = false;
+
+        page-padding = 0;
+
+        pages-per-row = 1;
+
+        render-loading = false;
+
+        show-directories = true;
+        show-hidden = true;
+        show-recent = 10;
+
+        link-zoom = true;
+        link-hadjust = true;
+
+        window-title-basename = true;
+        window-title-home-tilde = true;
+        window-title-page = true;
+
+        zoom-center = false;
+        zoom-max = 1000;
+        zoom-min = 10;
+        zoom-step = 10;
+
+        scroll-hstep = -1;
+        scroll-step = 40;
+        scroll-full-overlap = 0;
+        scroll-wrap = true;
+        scroll-page-aware = false;
+
+        selection-clipboard = "primary";
+        selection-notification = false;
+      };
+    };
+  };
+
+  xresources = {
+    properties = {
+      "*.font" = xftFont1;
+
+      "Xcursor.theme" = "core";
+      "Xcursor.theme_core" = "true";
+      "Xcursor.size" = 16;
+
+      "Xft.antialias" = 1;
+      "Xft.autohint" = 0;
+      "Xft.dpi" = 96;
+      "Xft.hinting" = 1;
+      "Xft.hintstyle" = "hintslight";
+      "Xft.lcdfilter" = "lcddefault";
+      "Xft.rgba" = "rgb";
+
+      "*.color0" = colorBlack0;
+      "*.color8" = colorBlack1;
+      "*.color1" = colorRed0;
+      "*.color9" = colorRed1;
+      "*.color2" = colorGreen0;
+      "*.color10" = colorGreen1;
+      "*.color3" = colorYellow0;
+      "*.color11" = colorYellow1;
+      "*.color4" = colorBlue0;
+      "*.color12" = colorBlue1;
+      "*.color5" = colorMagenta0;
+      "*.color13" = colorMagenta1;
+      "*.color6" = colorCyan0;
+      "*.color14" = colorCyan1;
+      "*.color7" = colorWhite0;
+      "*.color15" = colorWhite1;
+
+      "*.background" = colorBlack0;
+      "*.foreground" = colorWhite0;
+    };
+  };
+}
diff --git a/nix/.nix-channels b/nix/.nix-channels
new file mode 100644
index 0000000..4a8d253
--- /dev/null
+++ b/nix/.nix-channels
@@ -0,0 +1,2 @@
+https://nixos.org/channels/nixpkgs-unstable nixpkgs
+https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
diff --git a/nix/@install b/nix/@install
new file mode 100755
index 0000000..dc4c1f0
--- /dev/null
+++ b/nix/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/nixpkgs" ] &&
+    mkdir -p "${XDG_CONFIG_HOME}/nixpkgs"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    nix
diff --git a/nuget/.nuget/NuGet/NuGet.Config b/nuget/.nuget/NuGet/NuGet.Config
new file mode 100644
index 0000000..a95cade
--- /dev/null
+++ b/nuget/.nuget/NuGet/NuGet.Config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <packageSources>
+        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
+    </packageSources>
+</configuration>
diff --git a/nuget/@install b/nuget/@install
new file mode 100755
index 0000000..cacb567
--- /dev/null
+++ b/nuget/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.nuget" ] && \
+    mkdir -p "$HOME/.nuget"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    nuget
diff --git a/picom/.local/etc/picom.conf b/picom/.local/etc/picom.conf
new file mode 100644
index 0000000..0275835
--- /dev/null
+++ b/picom/.local/etc/picom.conf
@@ -0,0 +1,80 @@
+# Shadow.
+
+shadow = false
+
+shadow-radius = 7
+shadow-opacity = 0.7
+shadow-offset-x = 0
+shadow-offset-y = 0
+
+shadow-exclude =
+[
+    "_GTK_FRAME_EXTENTS@:c",
+    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
+    "class_g = 'slop'",
+    "name = 'oneko'",
+]
+
+# Fade.
+
+fading = false
+
+fade-delta = 3
+no-fading-openclose = false
+no-fading-destroyed-argb = false
+
+inactive-opacity = 1.0
+frame-opacity = 1.0
+active-opacity = 1.0
+
+inactive-dim = 0.0
+inactive-dim-fixed = 0.0
+
+# Opacity.
+
+opacity-rule = [
+    "0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
+]
+
+# Corner.
+
+corner-radius = 0
+
+# Blur.
+
+blur-background = false
+
+# General.
+
+daemon = false
+
+backend = "glx"
+
+vsync = true
+
+refresh-rate = 0
+
+dbus = false
+
+log-level = "error"
+
+# Wintypes.
+
+wintypes:
+{
+    combo = {}
+    desktop = {}
+    dialog = {}
+    dnd = {}
+    dock = {}
+    dropdown_menu = {}
+    menu = {}
+    normal = {}
+    notification = {}
+    popup_menu = {}
+    splash = {}
+    toolbar = {}
+    tooltip = {}
+    unknown = {}
+    utility = {}
+}
diff --git a/picom/@install b/picom/@install
new file mode 100755
index 0000000..140ddac
--- /dev/null
+++ b/picom/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    picom
diff --git a/pip/.local/etc/pip/pip.conf b/pip/.local/etc/pip/pip.conf
new file mode 100644
index 0000000..b0ba198
--- /dev/null
+++ b/pip/.local/etc/pip/pip.conf
@@ -0,0 +1,2 @@
+[global]
+user = true
diff --git a/pip/@install b/pip/@install
new file mode 100755
index 0000000..ca2f8aa
--- /dev/null
+++ b/pip/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/pip" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/pip"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    pip
diff --git a/postgres/.psqlrc b/postgres/.psqlrc
new file mode 100644
index 0000000..6405f72
--- /dev/null
+++ b/postgres/.psqlrc
@@ -0,0 +1,16 @@
+\set QUIET 1
+\pset null '[NULL]'
+
+\set PROMPT1 '%[%033[1m%]%M %n@%/%R%[%033[0m%]% λ '
+\set PROMPT2 '    … > '
+
+\timing
+
+\x auto
+
+\set HISTCONTROL ignoredups
+\set HISTFILE ~/.local/var/lib/psql_history_ :DBNAME
+
+\set VERBOSITY verbose
+
+\unset QUIET
diff --git a/postgres/@install b/postgres/@install
new file mode 100755
index 0000000..dce00ea
--- /dev/null
+++ b/postgres/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    postgres
diff --git a/profile/.profile b/profile/.profile
new file mode 100644
index 0000000..b05eafb
--- /dev/null
+++ b/profile/.profile
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+if [ "$(umask)" = "000" ] || [ "$(umask)" = "0000" ]
+then
+    umask 0022
+fi
+
+if [ -f "/etc/profile.env" ]
+then
+    # shellcheck disable=SC1091
+    . "/etc/profile.env"
+fi
+
+for i in /etc/profile.d/*.sh
+do
+    # shellcheck disable=SC1090
+    [ -r "$i" ] && . "$i"
+done
+
+for i in "${HOME}"/.profile.d/*.sh
+do
+    # shellcheck disable=SC1090
+    [ -r "$i" ] && . "$i"
+done
+
+export PROFILE_SOURCED="1"
diff --git a/profile/.profile.d/00_lang.sh b/profile/.profile.d/00_lang.sh
new file mode 100644
index 0000000..060c6c1
--- /dev/null
+++ b/profile/.profile.d/00_lang.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+export LC_COLLATE=C
+export LC_MESSAGES=C
diff --git a/profile/.profile.d/10_xdg.sh b/profile/.profile.d/10_xdg.sh
new file mode 100644
index 0000000..8a7cebe
--- /dev/null
+++ b/profile/.profile.d/10_xdg.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+_local="${HOME}/.local"
+
+export XDG_CACHE_HOME="${_local}/var/cache"
+export XDG_CONFIG_HOME="${_local}/etc"
+export XDG_DATA_HOME="${_local}/var/lib"
+export XDG_DESKTOP_DIR="${HOME}/tmp"
+export XDG_DOCUMENTS_DIR="${HOME}/doc"
+export XDG_DOWNLOAD_DIR="${HOME}/tmp"
+export XDG_MUSIC_DIR="${HOME}/music"
+export XDG_PICTURES_DIR="${HOME}/tmp"
+export XDG_PUBLICSHARE_DIR="${HOME}/tmp"
+export XDG_RUNTIME_DIR="${_local}/var/run"
+export XDG_TEMPLATES_DIR="${HOME}/tmp"
+export XDG_VIDEOS_DIR="${HOME}/tmp"
+
+unset _local
+
+_xdg_dirs="
+${XDG_CACHE_HOME}
+${XDG_CONFIG_HOME}
+${XDG_DATA_HOME}
+${XDG_DESKTOP_DIR}
+${XDG_DOCUMENTS_DIR}
+${XDG_DOWNLOAD_DIR}
+${XDG_MUSIC_DIR}
+${XDG_PICTURES_DIR}
+${XDG_PUBLICSHARE_DIR}
+${XDG_RUNTIME_DIR}
+${XDG_TEMPLATES_DIR}
+${XDG_VIDEOS_DIR}
+"
+
+for _xdg_dir in ${_xdg_dirs}; do
+	[ ! -d "${_xdg_dir}" ] && mkdir -p "${_xdg_dir}"
+done
+
+unset _xdg_dir _xdg_dirs
diff --git a/profile/.profile.d/20_history.sh b/profile/.profile.d/20_history.sh
new file mode 100644
index 0000000..b7f42bc
--- /dev/null
+++ b/profile/.profile.d/20_history.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+export HISTFILE="${XDG_DATA_HOME}/.histfile"
+export HISTSIZE=100000
diff --git a/profile/.profile.d/30_manpath.sh b/profile/.profile.d/30_manpath.sh
new file mode 100644
index 0000000..af4273e
--- /dev/null
+++ b/profile/.profile.d/30_manpath.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+manpath_append() {
+	[ ! -d "${1}" ] && return
+	echo "${MANPATH}" | grep -q "\(:\|^\)${1}\(:\|$\)" && return
+	export MANPATH="${MANPATH}:${1}"
+}
+
+manpath_prepend() {
+	[ ! -d "${1}" ] && return
+	echo "${MANPATH}" | grep -q "\(:\|^\)${1}\(:\|$\)" && return
+	export MANPATH="${1}:${MANPATH}"
+}
+
+manpath_prepend "/usr/share/man"
+manpath_prepend "/usr/local/share/man"
+manpath_prepend "${HOME}/.local/share/man"
diff --git a/profile/.profile.d/30_path.sh b/profile/.profile.d/30_path.sh
new file mode 100644
index 0000000..1469162
--- /dev/null
+++ b/profile/.profile.d/30_path.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
+
+path_prepend() {
+	[ ! -d "${1}" ] && return
+	echo "${PATH}" | grep -q "\(:\|^\)${1}\(:\|$\)" && return
+	export PATH="${1}:${PATH}"
+}
+
+path_append() {
+	[ ! -d "${1}" ] && return
+	echo "${PATH}" | grep -q "\(:\|^\)${1}\(:\|$\)" && return
+	export PATH="${PATH}:${1}"
+}
+
+path_append "/usr/local/bin"
+path_append "${HOME}/.bin"
+path_append "${HOME}/.local/bin"
diff --git a/profile/.profile.d/40_nix.sh b/profile/.profile.d/40_nix.sh
new file mode 100644
index 0000000..ede32bf
--- /dev/null
+++ b/profile/.profile.d/40_nix.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+nix_sh="${HOME}/.nix-profile/etc/profile.d/nix.sh"
+
+if [ -e "${nix_sh}" ]; then
+	# shellcheck disable=SC1090
+	. "${nix_sh}"
+
+	export NIXPKGS_ALLOW_UNFREE="1"
+
+	hm_session_vars="$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
+	if [ -e "${hm_session_vars}" ]; then
+		# shellcheck disable=SC1090
+		. "${hm_session_vars}"
+	fi
+	unset hm_session_vars
+fi
+
+unset nix_sh
diff --git a/profile/.profile.d/50_browser.sh b/profile/.profile.d/50_browser.sh
new file mode 100644
index 0000000..0a15ba1
--- /dev/null
+++ b/profile/.profile.d/50_browser.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+_browsers="
+qutebrowser
+chromium
+chromium-browser
+firefox
+lynx
+w3m
+elinks
+links
+"
+
+for _browser in ${_browsers}; do
+	# shellcheck disable=SC2139
+	if command -v "${_browser}" >/dev/null 2>&1; then
+		export BROWSER="${_browser}"
+
+		alias b="${BROWSER}"
+		if ! command -v br >/dev/null 2>&1; then
+			alias br="${BROWSER}"
+		fi
+
+		break
+	fi
+done
+
+unset _browser _browsers
diff --git a/profile/.profile.d/50_diff.sh b/profile/.profile.d/50_diff.sh
new file mode 100644
index 0000000..9253657
--- /dev/null
+++ b/profile/.profile.d/50_diff.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+_diffs="
+colordiff
+diff
+"
+
+for _diff in ${_diffs}; do
+	# shellcheck disable=SC2139
+	if command -v "${_diff}" >/dev/null 2>&1; then
+		export DIFF="${_diff}"
+
+		alias d="${DIFF}"
+		if ! command -v di >/dev/null 2>&1; then
+			alias di="${DIFF}"
+		fi
+
+		break
+	fi
+done
+
+unset _diff _diffs
diff --git a/profile/.profile.d/50_editor.sh b/profile/.profile.d/50_editor.sh
new file mode 100644
index 0000000..b3203fb
--- /dev/null
+++ b/profile/.profile.d/50_editor.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+_editors="
+nvim
+vim
+vi
+emacs
+nano
+ed
+"
+
+for _editor in ${_editors}; do
+	# shellcheck disable=SC2139
+	if command -v "${_editor}" >/dev/null 2>&1; then
+		export EDITOR="${_editor}" VISUAL="${_editor}"
+
+		alias e="${EDITOR}"
+		if ! command -v ed >/dev/null 2>&1; then
+			alias ed="${EDITOR}"
+		fi
+
+		break
+	fi
+done
+
+unset _editor _editors
diff --git a/profile/.profile.d/50_pager.sh b/profile/.profile.d/50_pager.sh
new file mode 100644
index 0000000..4270919
--- /dev/null
+++ b/profile/.profile.d/50_pager.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+_pagers="
+bat
+less
+more
+cat
+"
+
+for _pager in ${_pagers}; do
+	# shellcheck disable=SC2139
+	if command -v "${_pager}" >/dev/null 2>&1; then
+		export PAGER="${_pager}" MANPAGER="${_pager}"
+
+		alias p="${PAGER}"
+		if ! command -v pa >/dev/null 2>&1; then
+			alias pa="${PAGER}"
+		fi
+
+		break
+	fi
+done
+
+unset _pager _pagers
diff --git a/profile/.profile.d/60_devtoolset.sh b/profile/.profile.d/60_devtoolset.sh
new file mode 100644
index 0000000..fcc1816
--- /dev/null
+++ b/profile/.profile.d/60_devtoolset.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if [ -f "/opt/rh/devtoolset-9/enable" ]; then
+	source scl_source enable "devtoolset-9"
+fi
diff --git a/profile/.profile.d/60_dotnet.sh b/profile/.profile.d/60_dotnet.sh
new file mode 100644
index 0000000..5d4992b
--- /dev/null
+++ b/profile/.profile.d/60_dotnet.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+if command -v dotnet >/dev/null 2>&1; then
+	path_append "${HOME}/.dotnet/tools"
+
+	export DOTNET_CLI_TELEMETRY_OPTOUT="1"
+	export DOTNET_SKIP_FIRST_TIME_EXPERIENCE="1"
+
+	if command -v nuget >/dev/null 2>&1; then
+		export NUGET_CERT_REVOCATION_MODE="online"
+		export NUGET_PERSIST_DG="false"
+		export NUGET_RESTORE_MSBUILD_VERBOSITY="normal"
+		export NUGET_SHOW_STACK="true"
+		export NUGET_XMLDOC_MODE="skip"
+	fi
+fi
diff --git a/profile/.profile.d/60_go.sh b/profile/.profile.d/60_go.sh
new file mode 100644
index 0000000..252c46c
--- /dev/null
+++ b/profile/.profile.d/60_go.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if command -v go >/dev/null 2>&1; then
+	export GO111MODULE="on"
+	export GOPATH="${HOME}/.go"
+
+	path_append "${GOPATH}/bin"
+fi
diff --git a/profile/.profile.d/60_haskell.sh b/profile/.profile.d/60_haskell.sh
new file mode 100644
index 0000000..3ba7324
--- /dev/null
+++ b/profile/.profile.d/60_haskell.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v cabal >/dev/null 2>&1; then
+	path_append "${HOME}/.cabal/bin"
+fi
diff --git a/profile/.profile.d/60_java.sh b/profile/.profile.d/60_java.sh
new file mode 100644
index 0000000..e9ddf25
--- /dev/null
+++ b/profile/.profile.d/60_java.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+export _JAVA_AWT_WM_NONREPARENTING="1"
+export _JAVA_OPTIONS="-Dawt.useSystemAAFontSettings=on"
+
+if command -v java >/dev/null 2>&1; then
+	if [ -n "${JAVA_HOME}" ]; then
+		export JAVA_HOME="${HOME}/.gentoo/java-config-2/current-user-vm"
+	fi
+	path_append "${JAVA_HOME}/bin"
+	manpath_append "${JAVA_HOME}/man"
+fi
diff --git a/profile/.profile.d/60_lisp.sh b/profile/.profile.d/60_lisp.sh
new file mode 100644
index 0000000..e450d24
--- /dev/null
+++ b/profile/.profile.d/60_lisp.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+_implementations="
+sbcl
+ccl
+clasp
+clisp
+ecl
+abcl
+"
+
+for _implementation in ${_implementations}; do
+	# shellcheck disable=SC2139
+	if command -v "$_implementation" >/dev/null 2>&1; then
+		if command -v rlwrap >/dev/null 2>&1; then
+			alias lisp="rlwrap $_implementation"
+		else
+			alias lisp="$_implementation"
+		fi
+
+		break
+	fi
+done
+
+unset _implementation _implementations
diff --git a/profile/.profile.d/60_ocaml.sh b/profile/.profile.d/60_ocaml.sh
new file mode 100644
index 0000000..b981b3d
--- /dev/null
+++ b/profile/.profile.d/60_ocaml.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if command -v opam >/dev/null 2>&1; then
+	if [ -f "${HOME}/.opam/opam-init/init.sh" ]; then
+		# shellcheck disable=SC1091
+		. "${HOME}/.opam/opam-init/init.sh" >/dev/null 2>&1
+	fi
+fi
diff --git a/profile/.profile.d/60_python.sh b/profile/.profile.d/60_python.sh
new file mode 100644
index 0000000..9329cdf
--- /dev/null
+++ b/profile/.profile.d/60_python.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+_implementations="
+python
+python3
+python2
+"
+
+for _implementation in ${_implementations}; do
+	if command -v "${_implementation}" >/dev/null 2>&1; then
+		if [ -f "${HOME}/.pystartup" ]; then
+			export PYTHONSTARTUP="${HOME}/.pystartup"
+		fi
+
+		break
+	fi
+done
+
+unset _implementation _implementations
diff --git a/profile/.profile.d/60_rust.sh b/profile/.profile.d/60_rust.sh
new file mode 100644
index 0000000..1b6fd36
--- /dev/null
+++ b/profile/.profile.d/60_rust.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if command -v cargo >/dev/null 2>&1; then
+	export CARGO_HOME="${HOME}/.cargo"
+	export CARGO_CACHE_RUSTC_INFO="0"
+
+	path_append "${CARGO_HOME}/bin"
+fi
diff --git a/profile/.profile.d/90_alias.sh b/profile/.profile.d/90_alias.sh
new file mode 100644
index 0000000..39dc364
--- /dev/null
+++ b/profile/.profile.d/90_alias.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+if cp --help | grep -q "\--progress-bar" 2>&1 >/dev/null; then
+	alias cp="cp -i -r -g"
+else
+	alias cp="cp -i -r"
+fi
+
+if mv --help | grep -q "\--progress-bar" 2>&1 >/dev/null; then
+	alias mv="mv -i -g"
+else
+	alias mv="mv -i"
+fi
+
+if rm --help | grep -q "\--interactive\[=WHEN\]" 2>&1 >/dev/null; then
+	alias rm="rm -I"
+else
+	alias rm="rm -i"
+fi
+
+alias c="cd"
+
+alias ln="ln -i"
+
+alias mkdir="mkdir -p"
+alias rmdir="rmdir -p"
+
+alias grep="grep --color=auto"
+alias egrep="egrep --color=auto"
+alias fgrep="fgrep --color=auto"
+
+alias du="du -h"
+
+alias df="df -h"
diff --git a/profile/.profile.d/90_functions.sh b/profile/.profile.d/90_functions.sh
new file mode 100644
index 0000000..a5b63ec
--- /dev/null
+++ b/profile/.profile.d/90_functions.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+count() {
+	printf "%d\n" "${#}"
+}
+
+dec2hex() {
+	printf "0x%X\n" "${1}"
+}
+
+hex2dec() {
+	printf "%d\n" "0x${1}"
+}
+
+ff() {
+	find . -type f -iname "${@}" -ls
+}
+
+mkcd() {
+	mkdir -p "${1}" &&
+		builtin cd "${1}" ||
+		return
+}
+
+mvcd() {
+	mv -i -- "${PWD}" "${1}" &&
+		builtin cd . ||
+		return
+}
+
+cald() {
+	printf "\t\t%s\n\n" "$(date)" && cal -m -3
+}
+
+cheat() {
+	curl "cheat.sh/${1}"
+}
+
+myip() {
+	dig -4 +short @resolver1.opendns.com myip.opendns.com A
+}
+
+myip6() {
+	dig -6 +short @resolver1.opendns.com myip.opendns.com AAAA
+}
+
+if ! command -v sponge >/dev/null 2>&1; then
+	sponge() {
+		_tmp="$(mktemp)" || return 1
+
+		cat >"${_tmp}"
+		cat -- "${_tmp}"
+		rm -f -- "${_tmp}"
+
+		unset _tmp
+	}
+fi
diff --git a/profile/.profile.d/ag.sh b/profile/.profile.d/ag.sh
new file mode 100644
index 0000000..2ddded0
--- /dev/null
+++ b/profile/.profile.d/ag.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v ag >/dev/null 2>&1; then
+	alias ag="ag --color --smart-case"
+fi
diff --git a/profile/.profile.d/bat.sh b/profile/.profile.d/bat.sh
new file mode 100644
index 0000000..205da87
--- /dev/null
+++ b/profile/.profile.d/bat.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if command -v bat >/dev/null 2>&1; then
+	export BAT_THEME="base16"
+
+	if [ "${MANPAGER}" == "bat" ]; then
+		export MANPAGER="sh -c 'col -bx | bat -l man -p'"
+	fi
+fi
diff --git a/profile/.profile.d/bear.sh b/profile/.profile.d/bear.sh
new file mode 100644
index 0000000..7309b7c
--- /dev/null
+++ b/profile/.profile.d/bear.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# shellcheck disable=SC2139
+
+if command -v bear >/dev/null 2>&1; then
+	_implementations="
+remake
+make
+"
+
+	for _implementation in ${_implementations}; do
+		if command -v "${_implementation}" >/dev/null 2>&1; then
+			if command -v nproc >/dev/null 2>&1; then
+				alias m="bear ${_implementation} --jobs=$(($(nproc) + 1))"
+			else
+				alias m="bear ${_implementation}"
+			fi
+			alias mc="${_implementation} clean"
+
+			break
+		fi
+	done
+	unset _implementation _implementations
+fi
diff --git a/profile/.profile.d/beet.sh b/profile/.profile.d/beet.sh
new file mode 100644
index 0000000..2c2fd9a
--- /dev/null
+++ b/profile/.profile.d/beet.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if command -v beet >/dev/null 2>&1; then
+	export BEETSDIR="${XDG_DATA_HOME}/beets"
+
+	_beets_config="${XDG_CONFIG_HOME}/beets/config.yaml"
+	if [ -f "${_beets_config}" ]; then
+		# shellcheck disable=SC2139
+		alias beet="beet -c ${_beets_config}"
+	fi
+fi
+
+unset _beets_config
diff --git a/profile/.profile.d/ccache.sh b/profile/.profile.d/ccache.sh
new file mode 100644
index 0000000..895f9f0
--- /dev/null
+++ b/profile/.profile.d/ccache.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if command -v ccache >/dev/null 2>&1; then
+	export CCACHE_DIR="${HOME}/.ccache"
+	if [ -d "/usr/lib/ccache/bin" ]; then
+		export CCACHE_PATH="/usr/lib/ccache/bin:${PATH}"
+	else
+		export CCACHE_PATH="${PATH}"
+	fi
+fi
diff --git a/profile/.profile.d/df.sh b/profile/.profile.d/df.sh
new file mode 100644
index 0000000..26a767b
--- /dev/null
+++ b/profile/.profile.d/df.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v df >/dev/null 2>&1; then
+	alias disk="df --human-readable --exclude-type=tmpfs --exclude-type=devtmpfs"
+fi
diff --git a/profile/.profile.d/docker.sh b/profile/.profile.d/docker.sh
new file mode 100644
index 0000000..b034b51
--- /dev/null
+++ b/profile/.profile.d/docker.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if command -v docker >/dev/null 2>&1; then
+	alias dk="docker"
+	alias dk-ip="docker inspect --format '{{ .NetworkSettings.IPAddress }}'"
+	alias dk-pid="docker inspect --format '{{ .State.Pid }}'"
+	alias dk-rm-all="docker rm \$(docker ps --quiet --all)"
+	alias dk-rm-exited="docker rm \$(docker ps --quiet --format 'status=exited')"
+	alias dk-rmi-all="docker rmi \$(docker images --quiet --all)"
+	alias dk-rmi-dangling="docker rmi \$(docker images --quiet --format 'dangling=true')"
+	alias dk-stop-all="docker stop \$(docker ps --quiet --format 'status=running')"
+fi
diff --git a/profile/.profile.d/doom.sh b/profile/.profile.d/doom.sh
new file mode 100644
index 0000000..ad91c9f
--- /dev/null
+++ b/profile/.profile.d/doom.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if [ -x "${HOME}/.emacs.d/bin/doom" ]; then
+	path_append "${HOME}/.emacs.d/bin"
+fi
diff --git a/profile/.profile.d/free.sh b/profile/.profile.d/free.sh
new file mode 100644
index 0000000..ac04417
--- /dev/null
+++ b/profile/.profile.d/free.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v free >/dev/null 2>&1; then
+	alias ram="free --human --wide"
+fi
diff --git a/profile/.profile.d/fzf.sh b/profile/.profile.d/fzf.sh
new file mode 100644
index 0000000..3942b01
--- /dev/null
+++ b/profile/.profile.d/fzf.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if command -v fzf >/dev/null 2>&1; then
+	export FZF_DEFAULT_COMMAND=""
+	export FZF_DEFAULT_OPTS="--height 20% --reverse --border"
+fi
diff --git a/profile/.profile.d/git.sh b/profile/.profile.d/git.sh
new file mode 100644
index 0000000..d0b5e8f
--- /dev/null
+++ b/profile/.profile.d/git.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if command -v git >/dev/null 2>&1; then
+	if command -v hub >/dev/null 2>&1; then
+		alias git="hub"
+	fi
+	alias g="git"
+
+	if command -v delta >/dev/null 2>&1; then
+		export GIT_PAGER="delta"
+	fi
+fi
diff --git a/profile/.profile.d/gnupg.sh b/profile/.profile.d/gnupg.sh
new file mode 100644
index 0000000..d5d531f
--- /dev/null
+++ b/profile/.profile.d/gnupg.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+if command -v gpg >/dev/null 2>&1; then
+	GPG_TTY="$(tty)"
+	export GPG_TTY
+
+	if command -v ssh >/dev/null 2>&1 &&
+		command -v gpgconf >/dev/null 2>&1; then
+		unset SSH_AGENT_PID
+		if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne "${$}" ]; then
+			SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
+			export SSH_AUTH_SOCK
+		fi
+	fi
+
+	if command -v gpg-connect-agent >/dev/null 2>&1 &&
+		[ "${TERM}" != "linux" ]; then
+		gpg-connect-agent updatestartuptty /bye >/dev/null 2>&1
+	fi
+fi
diff --git a/profile/.profile.d/grep.sh b/profile/.profile.d/grep.sh
new file mode 100644
index 0000000..013a8ed
--- /dev/null
+++ b/profile/.profile.d/grep.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if command -v grep >/dev/null 2>&1; then
+	alias gr="grep"
+
+	if command -v batgrep >/dev/null 2>&1; then
+		alias gr="batgrep"
+	fi
+fi
+
+if command -v egrep >/dev/null 2>&1; then
+	alias egr="egrep"
+fi
+
+if command -v pgrep >/dev/null 2>&1; then
+	alias pgr="pgrep"
+fi
diff --git a/profile/.profile.d/hledger.sh b/profile/.profile.d/hledger.sh
new file mode 100644
index 0000000..b656ba2
--- /dev/null
+++ b/profile/.profile.d/hledger.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v hledger >/dev/null 2>&1; then
+	export LEDGER_FILE="${XDG_DOCUMENTS_DIR}/accounting/current.journal"
+fi
diff --git a/profile/.profile.d/jot.sh b/profile/.profile.d/jot.sh
new file mode 100644
index 0000000..21ff224
--- /dev/null
+++ b/profile/.profile.d/jot.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if command -v jot >/dev/null 2>&1 &&
+	command -v tput >/dev/null 2>&1; then
+	# shellcheck disable=SC2139
+	alias hr="jot -b '═' -s '' '$(tput cols)'"
+fi
diff --git a/profile/.profile.d/less.sh b/profile/.profile.d/less.sh
new file mode 100644
index 0000000..9418348
--- /dev/null
+++ b/profile/.profile.d/less.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if command -v less >/dev/null 2>&1; then
+	export LESSHISTFILE="/dev/null"
+	export LESSHISTSIZE=0
+fi
diff --git a/profile/.profile.d/llvm.sh b/profile/.profile.d/llvm.sh
new file mode 100644
index 0000000..f62b09b
--- /dev/null
+++ b/profile/.profile.d/llvm.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+_llvm_root="/usr/lib/llvm"
+
+if [ -d "${_llvm_root}" ]; then
+	for _version in "${_llvm_root}"/*; do
+		path_append "${_version}/bin"
+		manpath_append "${_version}/share/man"
+	done
+fi
+
+unset _version _llvm_root
diff --git a/profile/.profile.d/ls.sh b/profile/.profile.d/ls.sh
new file mode 100644
index 0000000..385caf8
--- /dev/null
+++ b/profile/.profile.d/ls.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# shellcheck disable=SC2139
+
+_gnu_ls="--color=always --human-readable --group-directories-first --indicator-style=classify --author"
+_bsd_ls="-G -p"
+
+if ls --color "${HOME}" >/dev/null 2>&1; then
+	alias ls="ls ${_gnu_ls} -C"
+	alias la="ls ${_gnu_ls} -C -A"
+	alias ll="ls ${_gnu_ls} -l -A"
+else
+	if command -v gls >/dev/null 2>&1; then
+		alias ls="gls ${_gnu_ls} -C"
+		alias la="gls ${_gnu_ls} -C -A"
+		alias ll="gls ${_gnu_ls} -l -A"
+	else
+		alias ls="ls ${_bsd_ls}"
+		alias la="ls ${_bsd_ls} -A"
+		alias ll="ls ${_bsd_ls} -A -l"
+	fi
+fi
+
+alias l="ll"
+
+unset _bsd_ls _gnu_ls
diff --git a/profile/.profile.d/man.sh b/profile/.profile.d/man.sh
new file mode 100644
index 0000000..54d3513
--- /dev/null
+++ b/profile/.profile.d/man.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if command -v man >/dev/null 2>&1; then
+	export MANOPT="--no-hyphenation"
+
+	alias man="LANG=\"C\" LC_MESSAGES=\"C\" man"
+fi
diff --git a/profile/.profile.d/mpd.sh b/profile/.profile.d/mpd.sh
new file mode 100644
index 0000000..8ed7310
--- /dev/null
+++ b/profile/.profile.d/mpd.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v mpd >/dev/null 2>&1; then
+	export MPD_HOST="/var/lib/mpd/mpd.socket"
+fi
diff --git a/profile/.profile.d/nnn.sh b/profile/.profile.d/nnn.sh
new file mode 100644
index 0000000..3890592
--- /dev/null
+++ b/profile/.profile.d/nnn.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+if command -v nnn >/dev/null 2>&1; then
+	export NNN_BMS="h:~;s:~/src;d:~/downloads;e:/etc;u:/usr;p:/etc/portage;t:/tmp"
+	export NNN_PLUG="j:autojump"
+	export NNN_MULTISCRIPT=1
+	export NNN_NO_AUTOSELECT=1
+	export NNN_OPENER="nuke"
+	export NNN_QUOTE_ON=1
+	export NNN_TMPFILE="${XDG_CACHE_HOME}/nnn"
+	export NNN_TRASH=0
+	export NNN_USE_EDITOR=1
+
+	alias f="nnn"
+
+	# shellcheck disable=SC2139
+	alias ncp="cat ${NNN_TMPFILE}/.selection | tr '\0' '\n'"
+fi
diff --git a/profile/.profile.d/open.sh b/profile/.profile.d/open.sh
new file mode 100644
index 0000000..8d0cd22
--- /dev/null
+++ b/profile/.profile.d/open.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+if [ "$(uname)" = "Linux" ]; then
+	if grep -q Microsoft /proc/version; then
+		alias open="explorer.exe"
+	elif command -v "xdg-open" >/dev/null 2>&1; then
+		alias open="xdg-open"
+	fi
+fi
+
+if command -v "open" >/dev/null 2>&1; then
+	o() {
+		if [ "${#}" -eq 0 ]; then
+			open "${PWD}"
+		else
+			open "${@}"
+		fi
+	}
+fi
diff --git a/profile/.profile.d/pass.sh b/profile/.profile.d/pass.sh
new file mode 100644
index 0000000..c8831b1
--- /dev/null
+++ b/profile/.profile.d/pass.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+_impls="
+gopass
+pass
+"
+
+for _impl in ${_impls}; do
+	if command -v "${_impl}" >/dev/null 2>&1; then
+		export PASSWORD_STORE_DIR="${XDG_DATA_HOME}/password-store"
+
+		break
+	fi
+done
+
+unset _impl _impls
diff --git a/profile/.profile.d/rsync.sh b/profile/.profile.d/rsync.sh
new file mode 100644
index 0000000..cbbda1a
--- /dev/null
+++ b/profile/.profile.d/rsync.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#shellcheck disable=SC2139
+
+if command -v rsync >/dev/null 2>&1; then
+	_rsync_cp="rsync --archive --compress --verbose --progress --human-readable"
+
+	alias rsync-cp="${_rsync_cp}"
+	alias rsync-mv="${_rsync_cp} --remove-source-files"
+	alias rsync-sync="${_rsync_cp} --update --delete"
+
+	unset _rsync_cp
+fi
diff --git a/profile/.profile.d/shellcheck.sh b/profile/.profile.d/shellcheck.sh
new file mode 100644
index 0000000..73b12e3
--- /dev/null
+++ b/profile/.profile.d/shellcheck.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v shellcheck >/dev/null 2>&1; then
+	alias sc="shellcheck"
+fi
diff --git a/profile/.profile.d/svn.sh b/profile/.profile.d/svn.sh
new file mode 100644
index 0000000..9fa1219
--- /dev/null
+++ b/profile/.profile.d/svn.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v svn >/dev/null 2>&1; then
+	alias s="svn"
+fi
diff --git a/profile/.profile.d/torrentinfo.sh b/profile/.profile.d/torrentinfo.sh
new file mode 100644
index 0000000..77c3833
--- /dev/null
+++ b/profile/.profile.d/torrentinfo.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if command -v torrentinfo >/dev/null 2>&1; then
+	alias torrentinfo="torrentinfo --everything"
+fi
diff --git a/profile/.profile.d/uim.sh b/profile/.profile.d/uim.sh
new file mode 100644
index 0000000..d8b6202
--- /dev/null
+++ b/profile/.profile.d/uim.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if command -v uim-xim >/dev/null 2>&1; then
+	export GTK_IM_MODULE="uim"
+	export QT_IM_MODULE="uim"
+	export SHORT_DESC="UIM"
+	export UIM_FEP="skk"
+	export XIM="uim"
+	export XIM_ARGS=
+	export XIM_PROGRAM="uim-xim"
+	export XMODIFIERS="@im=uim"
+fi
diff --git a/profile/.profile.d/units.sh b/profile/.profile.d/units.sh
new file mode 100644
index 0000000..7b19142
--- /dev/null
+++ b/profile/.profile.d/units.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if command -v units >/dev/null 2>&1; then
+	# shellcheck disable=SC2139
+	alias units="units --history=${XDG_DATA_HOME}/units_history"
+fi
diff --git a/profile/.profile.d/urxvt.sh b/profile/.profile.d/urxvt.sh
new file mode 100644
index 0000000..c08a63d
--- /dev/null
+++ b/profile/.profile.d/urxvt.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if command -v urxvt >/dev/null 2>&1; then
+	export RXVT_SOCKET="${XDG_RUNTIME_DIR}/urxvtd.socket"
+	export URXVT_PERL_LIB="${XDG_DATA_HOME}/urxvt/ext"
+fi
diff --git a/profile/.profile.d/vi.sh b/profile/.profile.d/vi.sh
new file mode 100644
index 0000000..d93b91d
--- /dev/null
+++ b/profile/.profile.d/vi.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+_implementations="
+vim
+vi
+"
+
+for _implementation in ${_implementations}; do
+	# shellcheck disable=SC2139
+	command -v "${_implementation}" >/dev/null 2>&1 &&
+		alias vim="${_implementation}" &&
+		alias vi="${_implementation}" &&
+		alias v="${_implementation}" &&
+		break
+done
+
+unset _implementation _implementations
diff --git a/profile/.profile.d/wakatime.sh b/profile/.profile.d/wakatime.sh
new file mode 100644
index 0000000..ff1ba89
--- /dev/null
+++ b/profile/.profile.d/wakatime.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if command -v wakatime >/dev/null 2>&1; then
+	export WAKATIME_HOME="${HOME}/.wakatime"
+
+	[ ! -d "${WAKATIME_HOME}" ] &&
+		mkdir -p "${WAKATIME_HOME}"
+fi
diff --git a/profile/.profile.d/wget.sh b/profile/.profile.d/wget.sh
new file mode 100644
index 0000000..de72b2b
--- /dev/null
+++ b/profile/.profile.d/wget.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if command -v wget >/dev/null 2>&1; then
+	# shellcheck disable=SC2139
+	alias wget="wget --hsts-file=${XDG_DATA_HOME}/wget-hsts"
+fi
diff --git a/profile/.profile.d/wine.sh b/profile/.profile.d/wine.sh
new file mode 100644
index 0000000..8f078ce
--- /dev/null
+++ b/profile/.profile.d/wine.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#shellcheck disable=SC2139
+
+if command -v wine >/dev/null 2>&1; then
+	export WINEARCH="win64"
+	export WINEDEBUG="+all"
+	export WINEDLLOVERRIDES="winemenubuilder.exe=d"
+	export WINEPREFIX="${HOME}/.wine"
+
+	if command -v xrandr >/dev/null 2>&1; then
+		alias wine-run="wine explorer.exe /desktop=default,$(xrandr | grep '\*' | cut -d' ' -f4)"
+	fi
+fi
diff --git a/profile/@install b/profile/@install
new file mode 100755
index 0000000..d2073f2
--- /dev/null
+++ b/profile/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.profile.d" ] && \
+    mkdir -p "${HOME}/.profile.d"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    profile
diff --git a/pulseaudio/.local/etc/pulse/client.conf b/pulseaudio/.local/etc/pulse/client.conf
new file mode 100644
index 0000000..1038752
--- /dev/null
+++ b/pulseaudio/.local/etc/pulse/client.conf
@@ -0,0 +1,37 @@
+# This file is part of PulseAudio.
+#
+# PulseAudio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# PulseAudio is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+
+## Configuration file for PulseAudio clients. See pulse-client.conf(5) for
+## more information. Default values are commented out.  Use either ; or # for
+## commenting.
+
+; default-sink =
+; default-source =
+; default-server =
+; default-dbus-server =
+
+; autospawn = yes
+; daemon-binary = /usr/bin/pulseaudio
+; extra-arguments = --log-target=syslog
+
+; cookie-file =
+
+; enable-shm = yes
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
+
+; auto-connect-localhost = no
+; auto-connect-display = no
+
+auth-cookie = ~/.local/var/esd_auth
diff --git a/pulseaudio/.local/etc/pulse/daemon.conf b/pulseaudio/.local/etc/pulse/daemon.conf
new file mode 100644
index 0000000..e15a2f7
--- /dev/null
+++ b/pulseaudio/.local/etc/pulse/daemon.conf
@@ -0,0 +1,89 @@
+# This file is part of PulseAudio.
+#
+# PulseAudio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# PulseAudio is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+
+## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for
+## more information. Default values are commented out.  Use either ; or # for
+## commenting.
+
+; daemonize = no
+; fail = yes
+; allow-module-loading = yes
+; allow-exit = yes
+; use-pid-file = yes
+; system-instance = no
+; local-server-type = user
+; enable-shm = yes
+; enable-memfd = yes
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
+; lock-memory = no
+; cpu-limit = no
+
+; high-priority = yes
+; nice-level = -11
+
+; realtime-scheduling = yes
+; realtime-priority = 5
+
+; exit-idle-time = 20
+; scache-idle-time = 20
+
+; dl-search-path = (depends on architecture)
+
+; load-default-script-file = yes
+; default-script-file = /etc/pulse/default.pa
+
+; log-target = auto
+; log-level = notice
+; log-meta = no
+; log-time = no
+; log-backtrace = 0
+
+; resample-method = speex-float-1
+; avoid-resampling = false
+; enable-remixing = yes
+; remixing-use-all-sink-channels = yes
+; enable-lfe-remixing = no
+; lfe-crossover-freq = 0
+
+; flat-volumes = no
+
+; rlimit-fsize = -1
+; rlimit-data = -1
+; rlimit-stack = -1
+; rlimit-core = -1
+; rlimit-as = -1
+; rlimit-rss = -1
+; rlimit-nproc = -1
+; rlimit-nofile = 256
+; rlimit-memlock = -1
+; rlimit-locks = -1
+; rlimit-sigpending = -1
+; rlimit-msgqueue = -1
+; rlimit-nice = 31
+; rlimit-rtprio = 9
+; rlimit-rttime = 200000
+
+; default-sample-format = s16le
+; default-sample-rate = 44100
+; alternate-sample-rate = 48000
+; default-sample-channels = 2
+; default-channel-map = front-left,front-right
+
+; default-fragments = 4
+; default-fragment-size-msec = 25
+
+; enable-deferred-volume = yes
+; deferred-volume-safety-margin-usec = 8000
+; deferred-volume-extra-delay-usec = 0
diff --git a/pulseaudio/.local/etc/pulse/default.pa b/pulseaudio/.local/etc/pulse/default.pa
new file mode 100644
index 0000000..64c94cb
--- /dev/null
+++ b/pulseaudio/.local/etc/pulse/default.pa
@@ -0,0 +1,130 @@
+#!/usr/bin/pulseaudio -nF
+#
+# This file is part of PulseAudio.
+#
+# PulseAudio is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# PulseAudio is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+
+# This startup script is used only if PulseAudio is started per-user
+# (i.e. not in system mode)
+
+.fail
+
+### Automatically restore the volume of streams and devices
+load-module module-device-restore
+load-module module-stream-restore
+load-module module-card-restore
+
+### Automatically augment property information from .desktop files
+### stored in /usr/share/application
+load-module module-augment-properties
+
+### Should be after module-*-restore but before module-*-detect
+load-module module-switch-on-port-available
+
+### Load audio drivers statically
+### (it's probably better to not load these drivers manually, but instead
+### use module-udev-detect -- see below -- for doing this automatically)
+#load-module module-alsa-sink
+#load-module module-alsa-source device=hw:1,0
+#load-module module-null-sink
+#load-module module-pipe-sink
+
+### Automatically load driver modules depending on the hardware available
+.ifexists module-udev-detect.so
+load-module module-udev-detect
+.else
+### Use the static hardware detection module (for systems that lack udev support)
+load-module module-detect
+.endif
+
+### Automatically connect sink and source if JACK server is present
+.ifexists module-jackdbus-detect.so
+.nofail
+load-module module-jackdbus-detect channels=2
+.fail
+.endif
+
+
+### Load several protocols
+.ifexists module-esound-protocol-unix.so
+load-module module-esound-protocol-unix
+.endif
+load-module module-native-protocol-unix
+
+### Network access (may be configured with paprefs, so leave this commented
+### here if you plan to use paprefs)
+#load-module module-esound-protocol-tcp
+#load-module module-native-protocol-tcp
+
+### Load the RTP receiver module (also configured via paprefs, see above)
+#load-module module-rtp-recv
+
+### Load the RTP sender module (also configured via paprefs, see above)
+#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
+#load-module module-rtp-send source=rtp.monitor
+
+### Load additional modules from GSettings. This can be configured with the paprefs tool.
+### Please keep in mind that the modules configured by paprefs might conflict with manually
+### loaded modules.
+#.ifexists module-gsettings.so
+#.nofail
+#load-module module-gsettings
+#.fail
+#.endif
+
+
+### Automatically restore the default sink/source when changed by the user
+### during runtime
+### NOTE: This should be loaded as early as possible so that subsequent modules
+### that look up the default sink/source get the right value
+load-module module-default-device-restore
+
+### Automatically move streams to the default sink if the sink they are
+### connected to dies, similar for sources
+load-module module-rescue-streams
+
+### Make sure we always have a sink around, even if it is a null sink.
+load-module module-always-sink
+
+### Honour intended role device property
+load-module module-intended-roles
+
+### Automatically suspend sinks/sources that become idle for too long
+load-module module-suspend-on-idle
+
+### If autoexit on idle is enabled we want to make sure we only quit
+### when no local session needs us anymore.
+.ifexists module-console-kit.so
+load-module module-console-kit
+.endif
+.ifexists module-systemd-login.so
+load-module module-systemd-login
+.endif
+
+### Enable positioned event sounds
+load-module module-position-event-sounds
+
+### Cork music/video streams when a phone stream is active
+load-module module-role-cork
+
+### Modules to allow autoloading of filters (such as echo cancellation)
+### on demand. module-filter-heuristics tries to determine what filters
+### make sense, and module-filter-apply does the heavy-lifting of
+### loading modules and rerouting streams.
+load-module module-filter-heuristics
+load-module module-filter-apply
+
+### Make some devices default
+#set-default-sink output
+#set-default-source input
diff --git a/pulseaudio/@install b/pulseaudio/@install
new file mode 100755
index 0000000..e391077
--- /dev/null
+++ b/pulseaudio/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/pulse" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/pulse"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    pulseaudio
diff --git a/pylint/.pylintrc b/pylint/.pylintrc
new file mode 100644
index 0000000..4a73ef5
--- /dev/null
+++ b/pylint/.pylintrc
@@ -0,0 +1,570 @@
+[MASTER]
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code.
+extension-pkg-whitelist=
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Add files or directories matching the regex patterns to the blacklist. The
+# regex matches against base names, not paths.
+ignore-patterns=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
+# number of processors available to use.
+jobs=0
+
+# Control the amount of potential inferred values when inferring a single
+# object. This can help the performance when dealing with large functions or
+# complex, nested conditions.
+limit-inference-results=100
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Specify a configuration file.
+#rcfile=
+
+# When enabled, pylint would attempt to guess common misconfiguration and emit
+# user-friendly hints instead of false-positive error messages.
+suggestion-mode=yes
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once). You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use "--disable=all --enable=classes
+# --disable=W".
+# disable=print-statement,
+#         parameter-unpacking,
+#         unpacking-in-except,
+#         old-raise-syntax,
+#         backtick,
+#         long-suffix,
+#         old-ne-operator,
+#         old-octal-literal,
+#         import-star-module-level,
+#         non-ascii-bytes-literal,
+#         raw-checker-failed,
+#         bad-inline-option,
+#         locally-disabled,
+#         file-ignored,
+#         suppressed-message,
+#         useless-suppression,
+#         deprecated-pragma,
+#         use-symbolic-message-instead,
+#         apply-builtin,
+#         basestring-builtin,
+#         buffer-builtin,
+#         cmp-builtin,
+#         coerce-builtin,
+#         execfile-builtin,
+#         file-builtin,
+#         long-builtin,
+#         raw_input-builtin,
+#         reduce-builtin,
+#         standarderror-builtin,
+#         unicode-builtin,
+#         xrange-builtin,
+#         coerce-method,
+#         delslice-method,
+#         getslice-method,
+#         setslice-method,
+#         no-absolute-import,
+#         old-division,
+#         dict-iter-method,
+#         dict-view-method,
+#         next-method-called,
+#         metaclass-assignment,
+#         indexing-exception,
+#         raising-string,
+#         reload-builtin,
+#         oct-method,
+#         hex-method,
+#         nonzero-method,
+#         cmp-method,
+#         input-builtin,
+#         round-builtin,
+#         intern-builtin,
+#         unichr-builtin,
+#         map-builtin-not-iterating,
+#         zip-builtin-not-iterating,
+#         range-builtin-not-iterating,
+#         filter-builtin-not-iterating,
+#         using-cmp-argument,
+#         eq-without-hash,
+#         div-method,
+#         idiv-method,
+#         rdiv-method,
+#         exception-message-attribute,
+#         invalid-str-codec,
+#         sys-max-int,
+#         bad-python3-import,
+#         deprecated-string-function,
+#         deprecated-str-translate-call,
+#         deprecated-itertools-function,
+#         deprecated-types-field,
+#         next-method-defined,
+#         dict-items-not-iterating,
+#         dict-keys-not-iterating,
+#         dict-values-not-iterating,
+#         deprecated-operator-function,
+#         deprecated-urllib-function,
+#         xreadlines-attribute,
+#         deprecated-sys-function,
+#         exception-escape,
+#         comprehension-escape
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+enable=c-extension-no-member
+
+
+[REPORTS]
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details.
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, json
+# and msvs (visual studio). You can also give a reporter class, e.g.
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Tells whether to display a full report or only the messages.
+reports=no
+
+# Activate the evaluation score.
+score=yes
+
+
+[REFACTORING]
+
+# Maximum number of nested blocks for function / method body
+max-nested-blocks=5
+
+# Complete name of functions that never returns. When checking for
+# inconsistent-return-statements if a never returning function is called then
+# it will be considered as an explicit return statement and no message will be
+# printed.
+never-returning-functions=sys.exit
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid defining new builtins when possible.
+additional-builtins=
+
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables=yes
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,
+          _cb
+
+# A regular expression matching the name of dummy variables (i.e. expected to
+# not be used).
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore.
+ignored-argument-names=_.*|^ignored_|^unused_
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,
+      XXX,
+      TODO
+
+
+[FORMAT]
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren=4
+
+# String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1
+# tab).
+indent-string='    '
+
+# Maximum number of characters on a single line.
+max-line-length=100
+
+# Maximum number of lines in a module.
+max-module-lines=1000
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=trailing-comma,
+               dict-separator
+
+# Allow the body of a class to be on the same line as the declaration if body
+# contains single statement.
+single-line-class-stmt=no
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[STRING]
+
+# This flag controls whether the implicit-str-concat-in-sequence should
+# generate a warning on implicit string concatenation in sequences defined over
+# several lines.
+check-str-concat-over-line-jumps=no
+
+
+[BASIC]
+
+# Naming style matching correct argument names.
+argument-naming-style=snake_case
+
+# Regular expression matching correct argument names. Overrides argument-
+# naming-style.
+#argument-rgx=
+
+# Naming style matching correct attribute names.
+attr-naming-style=snake_case
+
+# Regular expression matching correct attribute names. Overrides attr-naming-
+# style.
+#attr-rgx=
+
+# Bad variable names which should always be refused, separated by a comma.
+bad-names=foo,
+          bar,
+          baz,
+          toto,
+          tutu,
+          tata
+
+# Naming style matching correct class attribute names.
+class-attribute-naming-style=any
+
+# Regular expression matching correct class attribute names. Overrides class-
+# attribute-naming-style.
+#class-attribute-rgx=
+
+# Naming style matching correct class names.
+class-naming-style=PascalCase
+
+# Regular expression matching correct class names. Overrides class-naming-
+# style.
+#class-rgx=
+
+# Naming style matching correct constant names.
+const-naming-style=UPPER_CASE
+
+# Regular expression matching correct constant names. Overrides const-naming-
+# style.
+#const-rgx=
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+# Naming style matching correct function names.
+function-naming-style=snake_case
+
+# Regular expression matching correct function names. Overrides function-
+# naming-style.
+#function-rgx=
+
+# Good variable names which should always be accepted, separated by a comma.
+good-names=i,
+           j,
+           k,
+           ex,
+           Run,
+           _
+
+# Include a hint for the correct naming format with invalid-name.
+include-naming-hint=no
+
+# Naming style matching correct inline iteration names.
+inlinevar-naming-style=any
+
+# Regular expression matching correct inline iteration names. Overrides
+# inlinevar-naming-style.
+#inlinevar-rgx=
+
+# Naming style matching correct method names.
+method-naming-style=snake_case
+
+# Regular expression matching correct method names. Overrides method-naming-
+# style.
+#method-rgx=
+
+# Naming style matching correct module names.
+module-naming-style=snake_case
+
+# Regular expression matching correct module names. Overrides module-naming-
+# style.
+#module-rgx=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=^_
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+# These decorators are taken in consideration only for invalid-name.
+property-classes=abc.abstractproperty
+
+# Naming style matching correct variable names.
+variable-naming-style=snake_case
+
+# Regular expression matching correct variable names. Overrides variable-
+# naming-style.
+#variable-rgx=
+
+
+[LOGGING]
+
+# Format style used to check logging format string. `old` means using %
+# formatting, while `new` is for `{}` formatting.
+logging-format-style=old
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format.
+logging-modules=logging
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# Tells whether to warn about missing members when the owner of the attribute
+# is inferred to be None.
+ignore-none=yes
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference
+# can return multiple potential results while evaluating a Python object, but
+# some branches might not be evaluated, which results in partial inference. In
+# that case, it might be useful to still emit no-member and other checks for
+# the rest of the inferred objects.
+ignore-on-opaque-inference=yes
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis. It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# Show a hint with possible names when a member name was not found. The aspect
+# of finding the hint is based on edit distance.
+missing-member-hint=yes
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance=1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices=1
+
+
+[SPELLING]
+
+# Limits count of emitted suggestions for spelling mistakes.
+max-spelling-suggestions=4
+
+# Spelling dictionary name. Available dictionaries: none. To make it working
+# install python-enchant package..
+spelling-dict=
+
+# List of comma separated words that should not be checked.
+spelling-ignore-words=
+
+# A path to a file that contains private dictionary; one word per line.
+spelling-private-dict-file=
+
+# Tells whether to store unknown words to indicated private dictionary in
+# --spelling-private-dict-file option instead of raising a message.
+spelling-store-unknown-words=no
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,
+                      __new__,
+                      setUp
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,
+                  _fields,
+                  _replace,
+                  _source,
+                  _make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=cls
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method.
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of boolean expressions in an if statement.
+max-bool-expr=5
+
+# Maximum number of branch for function / method body.
+max-branches=12
+
+# Maximum number of locals for function / method body.
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body.
+max-returns=6
+
+# Maximum number of statements in function / method body.
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+
+[IMPORTS]
+
+# Allow wildcard imports from modules that define __all__.
+allow-wildcard-with-all=no
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+# Deprecated modules which should not be used, separated by a comma.
+deprecated-modules=optparse,tkinter.tix
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled).
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled).
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled).
+int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "BaseException, Exception".
+overgeneral-exceptions=BaseException,
+                       Exception
diff --git a/pylint/@install b/pylint/@install
new file mode 100755
index 0000000..dd12d23
--- /dev/null
+++ b/pylint/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    pylint
diff --git a/python/.pystartup b/python/.pystartup
new file mode 100644
index 0000000..98d17b5
--- /dev/null
+++ b/python/.pystartup
@@ -0,0 +1,128 @@
+from code import InteractiveConsole
+from tempfile import mkstemp
+import atexit
+import os
+import readline
+import rlcompleter
+import sys
+
+
+readline.parse_and_bind("tab: complete")
+
+
+class TermColors(dict):
+    color_templates = (
+        ("Normal",      "0"),
+        ("Black",       "0;30"),
+        ("Red",         "0;31"),
+        ("Green",       "0;32"),
+        ("Brown",       "0;33"),
+        ("Blue",        "0;34"),
+        ("Purple",      "0;35"),
+        ("Cyan",        "0;36"),
+        ("LightGray",   "0;37"),
+        ("DarkGray",    "1;30"),
+        ("LightRed",    "1;31"),
+        ("LightGreen",  "1;32"),
+        ("Yellow",      "1;33"),
+        ("LightBlue",   "1;34"),
+        ("LightPurple", "1;35"),
+        ("LightCyan",   "1;36"),
+        ("White",       "1;37")
+    )
+    color_base = '\001\033[%sm\002'
+
+    def __init__(self):
+        self.update(dict(
+            [(k, self.color_base % v) for k, v in self.color_templates]))
+
+
+class Completer(object):
+    def save_history(self):
+        import readline
+
+        readline.write_history_file(self.python_histfile)
+
+    def __init__(self):
+        self.python_dir = os.path.expanduser(
+            "%s/python" % os.environ["XDG_DATA_HOME"])
+
+        if not os.path.exists(self.python_dir):
+            os.mkdir(self.python_dir)
+
+        self.python_histfile = os.path.expanduser(
+            "%s/history" % self.python_dir)
+
+        if os.path.exists(self.python_histfile):
+            readline.read_history_file(self.python_histfile)
+
+        readline.set_history_length(1000)
+        atexit.register(self.save_history)
+
+
+def DisplayHook(value):
+    if value is not None:
+        try:
+            import __builtin__
+            __builtin__._ = value
+        except ImportError:
+            __builtins__._ = value
+
+        import pprint
+
+        pprint.pprint(value)
+        del pprint
+
+
+class EditableBufferInteractiveConsole(InteractiveConsole):
+    def __init__(self, *args, **kwargs):
+        self.last_buffer = []
+        InteractiveConsole.__init__(self, *args, **kwargs)
+
+    def runsource(self, source, *args):
+        self.last_buffer = [source.encode('utf-8')]
+        return InteractiveConsole.runsource(self, source, *args)
+
+    def raw_input(self, *args):
+        line = InteractiveConsole.raw_input(self, *args)
+
+        if line == EDIT_CMD:
+            tmp_fd, tmp_file = mkstemp('.py')
+
+            os.write(tmp_fd, b'\n'.join(self.last_buffer))
+            os.close(tmp_fd)
+
+            os.system('%s %s' % (EDITOR, tmp_file))
+
+            line = open(tmp_file).read()
+
+            os.unlink(tmp_file)
+            tmp_file = ''
+
+            lines = line.split('\n')
+
+            for i in range(len(lines) - 1):
+                self.push(lines[i])
+
+            line = lines[-1]
+        return line
+
+
+TC = TermColors()
+ps1 = "%sλ%s %s>%s "
+sys.ps1 = ps1 % (TC['Blue'],  TC['Normal'],
+                 TC['White'], TC['Normal'])
+ps2 = "    %s…%s %s>%s "
+sys.ps2 = ps2 % (TC['Blue'],  TC['Normal'],
+                 TC['White'], TC['Normal'])
+sys.displayhook = DisplayHook
+
+C = Completer()
+EDITOR = os.environ.get('EDITOR', 'vim')
+EDIT_CMD = ':e'
+C = EditableBufferInteractiveConsole(locals=locals())
+C.interact(banner="")
+
+sys.exit()
+
+# vim: filetype=python
diff --git a/python/@install b/python/@install
new file mode 100755
index 0000000..1d8f685
--- /dev/null
+++ b/python/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    python
diff --git a/qutebrowser/.local/etc/qutebrowser/config.py b/qutebrowser/.local/etc/qutebrowser/config.py
new file mode 100644
index 0000000..a145e59
--- /dev/null
+++ b/qutebrowser/.local/etc/qutebrowser/config.py
@@ -0,0 +1,1225 @@
+# Autogenerated config.py
+#
+# NOTE: config.py is intended for advanced users who are comfortable
+# with manually migrating the config file on qutebrowser upgrades. If
+# you prefer, you can also configure qutebrowser using the
+# :set/:bind/:config-* commands without having to write a config.py
+# file.
+#
+# Documentation:
+#   qute://help/configuring.html
+#   qute://help/settings.html
+
+# Change the argument to True to still load settings configured via autoconfig.yml
+config.load_autoconfig(False)
+
+# Require a confirmation before quitting the application.
+# Type: ConfirmQuit
+# Valid values:
+#   - always: Always show a confirmation.
+#   - multiple-tabs: Show a confirmation if multiple tabs are opened.
+#   - downloads: Show a confirmation if downloads are running
+#   - never: Never show a confirmation.
+c.confirm_quit = ['downloads']
+
+# Maximum time (in minutes) between two history items for them to be
+# considered being from the same browsing session. Items with less time
+# between them are grouped when being displayed in `:history`. Use -1 to
+# disable separation.
+# Type: Int
+c.history_gap_interval = 30
+
+# When to find text on a page case-insensitively.
+# Type: IgnoreCase
+# Valid values:
+#   - always: Search case-insensitively.
+#   - never: Search case-sensitively.
+#   - smart: Search case-sensitively if there are capital characters.
+c.search.ignore_case = 'smart'
+
+# How to open links in an existing instance if a new one is launched.
+# This happens when e.g. opening a link from a terminal. See
+# `new_instance_open_target_window` to customize in which window the
+# link is opened in.
+# Type: String
+# Valid values:
+#   - tab: Open a new tab in the existing window and activate the window.
+#   - tab-bg: Open a new background tab in the existing window and activate the window.
+#   - tab-silent: Open a new tab in the existing window without activating the window.
+#   - tab-bg-silent: Open a new background tab in the existing window without activating the window.
+#   - window: Open in a new window.
+#   - private-window: Open in a new private window.
+c.new_instance_open_target = 'tab'
+
+# Which window to choose when opening links as new tabs. When
+# `new_instance_open_target` is set to `window`, this is ignored.
+# Type: String
+# Valid values:
+#   - first-opened: Open new tabs in the first (oldest) opened window.
+#   - last-opened: Open new tabs in the last (newest) opened window.
+#   - last-focused: Open new tabs in the most recently focused window.
+#   - last-visible: Open new tabs in the most recently visible window.
+c.new_instance_open_target_window = 'last-focused'
+
+# Additional arguments to pass to Qt, without leading `--`. With
+# QtWebEngine, some Chromium arguments (see
+# https://peter.sh/experiments/chromium-command-line-switches/ for a
+# list) will work.
+# Type: List of String
+c.qt.args = []
+
+# Turn on Qt HighDPI scaling. This is equivalent to setting
+# QT_AUTO_SCREEN_SCALE_FACTOR=1 or QT_ENABLE_HIGHDPI_SCALING=1 (Qt >=
+# 5.14) in the environment. It's off by default as it can cause issues
+# with some bitmap fonts. As an alternative to this, it's possible to
+# set font sizes and the `zoom.default` setting.
+# Type: Bool
+c.qt.highdpi = False
+
+# Automatically start playing `<video>` elements.
+# Type: Bool
+c.content.autoplay = False
+
+# Which cookies to accept. With QtWebEngine, this setting also controls
+# other features with tracking capabilities similar to those of cookies;
+# including IndexedDB, DOM storage, filesystem API, service workers, and
+# AppCache. Note that with QtWebKit, only `all` and `never` are
+# supported as per-domain values. Setting `no-3rdparty` or `no-
+# unknown-3rdparty` per-domain on QtWebKit will have the same effect as
+# `all`. If this setting is used with URL patterns, the pattern gets
+# applied to the origin/first party URL of the page making the request,
+# not the request URL. With QtWebEngine 5.15.0+, paths will be stripped
+# from URLs, so URL patterns using paths will not match. With
+# QtWebEngine 5.15.2+, subdomains are additionally stripped as well, so
+# you will typically need to set this setting for `example.com` when the
+# cookie is set on `somesubdomain.example.com` for it to work properly.
+# To debug issues with this setting, start qutebrowser with `--debug
+# --logfilter network --debug-flag log-cookies` which will show all
+# cookies being set.
+# Type: String
+# Valid values:
+#   - all: Accept all cookies.
+#   - no-3rdparty: Accept cookies from the same origin only. This is known to break some sites, such as GMail.
+#   - no-unknown-3rdparty: Accept cookies from the same origin only, unless a cookie is already set for the domain. On QtWebEngine, this is the same as no-3rdparty.
+#   - never: Don't accept cookies at all.
+config.set('content.cookies.accept', 'all', 'chrome-devtools://*')
+
+# Which cookies to accept. With QtWebEngine, this setting also controls
+# other features with tracking capabilities similar to those of cookies;
+# including IndexedDB, DOM storage, filesystem API, service workers, and
+# AppCache. Note that with QtWebKit, only `all` and `never` are
+# supported as per-domain values. Setting `no-3rdparty` or `no-
+# unknown-3rdparty` per-domain on QtWebKit will have the same effect as
+# `all`. If this setting is used with URL patterns, the pattern gets
+# applied to the origin/first party URL of the page making the request,
+# not the request URL. With QtWebEngine 5.15.0+, paths will be stripped
+# from URLs, so URL patterns using paths will not match. With
+# QtWebEngine 5.15.2+, subdomains are additionally stripped as well, so
+# you will typically need to set this setting for `example.com` when the
+# cookie is set on `somesubdomain.example.com` for it to work properly.
+# To debug issues with this setting, start qutebrowser with `--debug
+# --logfilter network --debug-flag log-cookies` which will show all
+# cookies being set.
+# Type: String
+# Valid values:
+#   - all: Accept all cookies.
+#   - no-3rdparty: Accept cookies from the same origin only. This is known to break some sites, such as GMail.
+#   - no-unknown-3rdparty: Accept cookies from the same origin only, unless a cookie is already set for the domain. On QtWebEngine, this is the same as no-3rdparty.
+#   - never: Don't accept cookies at all.
+config.set('content.cookies.accept', 'all', 'devtools://*')
+
+# Store cookies.
+# Type: Bool
+c.content.cookies.store = True
+
+# Default encoding to use for websites. The encoding must be a string
+# describing an encoding such as _utf-8_, _iso-8859-1_, etc.
+# Type: String
+c.content.default_encoding = 'utf-8'
+
+# Allow websites to share screen content.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.desktop_capture', True, 'https://discord.com')
+
+# Allow websites to share screen content.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.desktop_capture', True, 'https://web.skype.com')
+
+# Allow websites to share screen content.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+c.content.desktop_capture = 'ask'
+
+# Request websites to minimize non-essentials animations and motion.
+# This results in the `prefers-reduced-motion` CSS media query to
+# evaluate to `reduce` (rather than `no-preference`). On Windows, if
+# this setting is set to False, the system-wide animation setting is
+# considered.
+# Type: Bool
+c.content.prefers_reduced_motion = True
+
+# Allow websites to request geolocations.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+c.content.geolocation = False
+
+# Value to send in the `Accept-Language` header. Note that the value
+# read from JavaScript is always the global value.
+# Type: String
+c.content.headers.accept_language = 'en-US,en'
+
+# Value to send in the `Accept-Language` header. Note that the value
+# read from JavaScript is always the global value.
+# Type: String
+config.set('content.headers.accept_language', '', 'https://matchmaker.krunker.io/*')
+
+# Custom headers for qutebrowser HTTP requests.
+# Type: Dict
+c.content.headers.custom = {}
+
+# Value to send in the `DNT` header. When this is set to true,
+# qutebrowser asks websites to not track your identity. If set to null,
+# the DNT header is not sent at all.
+# Type: Bool
+c.content.headers.do_not_track = True
+
+# User agent to send.  The following placeholders are defined:  *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value   with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version.  The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine.  Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}; rv:71.0) Gecko/20100101 Firefox/71.0', 'https://docs.google.com/*')
+
+# User agent to send.  The following placeholders are defined:  *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value   with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version.  The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine.  Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}; rv:71.0) Gecko/20100101 Firefox/71.0', 'https://drive.google.com/*')
+
+# User agent to send.  The following placeholders are defined:  *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value   with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version.  The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine.  Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {upstream_browser_key}/{upstream_browser_version} Safari/{webkit_version}', 'https://web.whatsapp.com/')
+
+# User agent to send.  The following placeholders are defined:  *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value   with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version.  The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine.  Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {upstream_browser_key}/{upstream_browser_version} Safari/{webkit_version} Edg/{upstream_browser_version}', 'https://accounts.google.com/*')
+
+# User agent to send.  The following placeholders are defined:  *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value   with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version.  The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine.  Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99 Safari/537.36', 'https://*.slack.com/*')
+
+# Enable hyperlink auditing (`<a ping>`).
+# Type: Bool
+c.content.hyperlink_auditing = False
+
+# Load images automatically in web pages.
+# Type: Bool
+config.set('content.images', True, 'chrome-devtools://*')
+
+# Load images automatically in web pages.
+# Type: Bool
+config.set('content.images', True, 'devtools://*')
+
+# Allow JavaScript to read from or write to the clipboard. With
+# QtWebEngine, writing the clipboard as response to a user interaction
+# is always allowed.
+# Type: Bool
+c.content.javascript.can_access_clipboard = False
+
+# Allow JavaScript to open new tabs without user interaction.
+# Type: Bool
+c.content.javascript.can_open_tabs_automatically = False
+
+# Enable JavaScript.
+# Type: Bool
+c.content.javascript.enabled = True
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'file://*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'chrome-devtools://*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'devtools://*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'chrome://*/*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'qute://*/*')
+
+# Allow locally loaded documents to access remote URLs.
+# Type: Bool
+c.content.local_content_can_access_remote_urls = False
+
+# Allow locally loaded documents to access other local URLs.
+# Type: Bool
+c.content.local_content_can_access_file_urls = True
+
+# Enable support for HTML 5 local storage and Web SQL.
+# Type: Bool
+c.content.local_storage = True
+
+# Allow websites to record audio.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.media.audio_capture', True, 'https://web.skype.com')
+
+# Allow websites to record audio and video.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.media.audio_video_capture', True, 'https://discord.com')
+
+# Allow websites to record audio and video.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.media.audio_video_capture', True, 'https://web.skype.com')
+
+# Allow websites to show notifications.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.notifications.enabled', True, 'https://web.skype.com')
+
+# Allow websites to show notifications.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.notifications.enabled', False, 'https://www.reddit.com')
+
+# Allow websites to show notifications.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.notifications.enabled', True, 'https://web.telegram.org')
+
+# Allow websites to show notifications.
+# Type: BoolAsk
+# Valid values:
+#   - true
+#   - false
+#   - ask
+config.set('content.notifications.enabled', True, 'https://web.whatsapp.com')
+
+# Enable plugins in Web pages.
+# Type: Bool
+c.content.plugins = False
+
+# Draw the background color and images also when the page is printed.
+# Type: Bool
+c.content.print_element_backgrounds = True
+
+# Open new windows in private browsing mode which does not record
+# visited pages.
+# Type: Bool
+c.content.private_browsing = False
+
+# Proxy to use. In addition to the listed values, you can use a
+# `socks://...` or `http://...` URL. Note that with QtWebEngine, it will
+# take a couple of seconds until the change is applied, if this value is
+# changed at runtime.
+# Type: Proxy
+# Valid values:
+#   - system: Use the system wide proxy.
+#   - none: Don't use any proxy
+c.content.proxy = 'system'
+
+# List of user stylesheet filenames to use.
+# Type: List of File, or File
+c.content.user_stylesheets = []
+
+# Enable WebGL.
+# Type: Bool
+c.content.webgl = True
+
+# Number of commands to save in the command history. 0: no history / -1:
+# unlimited
+# Type: Int
+c.completion.cmd_history_max_items = 100
+
+# Height (in pixels or as percentage of the window) of the completion.
+# Type: PercOrInt
+c.completion.height = '50%'
+
+# When to show the autocompletion window.
+# Type: String
+# Valid values:
+#   - always: Whenever a completion is available.
+#   - auto: Whenever a completion is requested.
+#   - never: Never.
+c.completion.show = 'auto'
+
+# Shrink the completion to be smaller than the configured size if there
+# are no scrollbars.
+# Type: Bool
+c.completion.shrink = True
+
+# Width (in pixels) of the scrollbar in the completion window.
+# Type: Int
+c.completion.scrollbar.width = 0
+
+# Padding (in pixels) of the scrollbar handle in the completion window.
+# Type: Int
+c.completion.scrollbar.padding = 0
+
+# Format of timestamps (e.g. for the history completion). See
+# https://sqlite.org/lang_datefunc.html and
+# https://docs.python.org/3/library/datetime.html#strftime-strptime-
+# behavior for allowed substitutions, qutebrowser uses both sqlite and
+# Python to format its timestamps.
+# Type: String
+c.completion.timestamp_format = '%Y-%m-%d'
+
+# Minimum amount of characters needed to update completions.
+# Type: Int
+c.completion.min_chars = 3
+
+# Directory to save downloads to. If unset, a sensible OS-specific
+# default is used.
+# Type: Directory
+c.downloads.location.directory = '~/tmp'
+
+# Prompt the user for the download location. If set to false,
+# `downloads.location.directory` will be used.
+# Type: Bool
+c.downloads.location.prompt = False
+
+# Remember the last used download directory.
+# Type: Bool
+c.downloads.location.remember = True
+
+# What to display in the download filename input.
+# Type: String
+# Valid values:
+#   - path: Show only the download path.
+#   - filename: Show only download filename.
+#   - both: Show download path and filename.
+c.downloads.location.suggestion = 'path'
+
+# Which categories to show (in which order) in the :open completion.
+# Type: FlagList
+# Valid values:
+#   - searchengines
+#   - quickmarks
+#   - bookmarks
+#   - history
+#   - filesystem
+c.completion.open_categories = ['bookmarks', 'quickmarks', 'history']
+
+# Duration (in milliseconds) to wait before removing finished downloads.
+# If set to -1, downloads are never removed.
+# Type: Int
+c.downloads.remove_finished = 0
+
+# Editor (and arguments) to use for the `edit-*` commands. The following
+# placeholders are defined:  * `{file}`: Filename of the file to be
+# edited. * `{line}`: Line in which the caret is found in the text. *
+# `{column}`: Column in which the caret is found in the text. *
+# `{line0}`: Same as `{line}`, but starting from index 0. * `{column0}`:
+# Same as `{column}`, but starting from index 0.
+# Type: ShellCommand
+c.editor.command = ['st', '-e', 'vim', '-f', '{}']
+
+# When a hint can be automatically followed without pressing Enter.
+# Type: String
+# Valid values:
+#   - always: Auto-follow whenever there is only a single hint on a page.
+#   - unique-match: Auto-follow whenever there is a unique non-empty match in either the hint string (word mode) or filter (number mode).
+#   - full-match: Follow the hint when the user typed the whole hint (letter, word or number mode) or the element's text (only in number mode).
+#   - never: The user will always need to press Enter to follow a hint.
+c.hints.auto_follow = 'unique-match'
+
+# Duration (in milliseconds) to ignore normal-mode key bindings after a
+# successful auto-follow.
+# Type: Int
+c.hints.auto_follow_timeout = 0
+
+# CSS border value for hints.
+# Type: String
+c.hints.border = '0px'
+
+# Padding (in pixels) for hints.
+# Type: Padding
+c.hints.padding = {'bottom': 3, 'left': 3, 'right': 3, 'top': 3}
+
+# Rounding radius (in pixels) for the edges of hints.
+# Type: Int
+c.hints.radius = 0
+
+# Characters used for hint strings.
+# Type: UniqueCharString
+c.hints.chars = 'hjklasdfgyuiopqwertnmzxcvb'
+
+# Dictionary file to be used by the word hints.
+# Type: File
+c.hints.dictionary = '/dev/null'
+
+# Minimum number of characters used for hint strings.
+# Type: Int
+c.hints.min_chars = 1
+
+# Mode to use for hints.
+# Type: String
+# Valid values:
+#   - number: Use numeric hints. (In this mode you can also type letters from the hinted element to filter and reduce the number of elements that are hinted.)
+#   - letter: Use the characters in the `hints.chars` setting.
+#   - word: Use hints words based on the html elements and the extra words.
+c.hints.mode = 'letter'
+
+# Scatter hint key chains (like Vimium) or not (like dwb). Ignored for
+# number hints.
+# Type: Bool
+c.hints.scatter = False
+
+# Make characters in hint strings uppercase.
+# Type: Bool
+c.hints.uppercase = False
+
+# Rounding radius (in pixels) for the edges of the keyhint dialog.
+# Type: Int
+c.keyhint.radius = 0
+
+# Rounding radius (in pixels) for the edges of prompts.
+# Type: Int
+c.prompt.radius = 0
+
+# When/how to show the scrollbar.
+# Type: String
+# Valid values:
+#   - always: Always show the scrollbar.
+#   - never: Never show the scrollbar.
+#   - when-searching: Show the scrollbar when searching for text in the webpage. With the QtWebKit backend, this is equal to `never`.
+#   - overlay: Show an overlay scrollbar. On macOS, this is unavailable and equal to `when-searching`; with the QtWebKit backend, this is equal to `never`. Enabling/disabling overlay scrollbars requires a restart.
+c.scrolling.bar = 'never'
+
+# Enable smooth scrolling for web pages. Note smooth scrolling does not
+# work with the `:scroll-px` command.
+# Type: Bool
+c.scrolling.smooth = False
+
+# Languages to use for spell checking. You can check for available
+# languages and install dictionaries using scripts/dictcli.py. Run the
+# script with -h/--help for instructions.
+# Type: List of String
+# Valid values:
+#   - af-ZA: Afrikaans (South Africa)
+#   - bg-BG: Bulgarian (Bulgaria)
+#   - ca-ES: Catalan (Spain)
+#   - cs-CZ: Czech (Czech Republic)
+#   - da-DK: Danish (Denmark)
+#   - de-DE: German (Germany)
+#   - el-GR: Greek (Greece)
+#   - en-AU: English (Australia)
+#   - en-CA: English (Canada)
+#   - en-GB: English (United Kingdom)
+#   - en-US: English (United States)
+#   - es-ES: Spanish (Spain)
+#   - et-EE: Estonian (Estonia)
+#   - fa-IR: Farsi (Iran)
+#   - fo-FO: Faroese (Faroe Islands)
+#   - fr-FR: French (France)
+#   - he-IL: Hebrew (Israel)
+#   - hi-IN: Hindi (India)
+#   - hr-HR: Croatian (Croatia)
+#   - hu-HU: Hungarian (Hungary)
+#   - id-ID: Indonesian (Indonesia)
+#   - it-IT: Italian (Italy)
+#   - ko: Korean
+#   - lt-LT: Lithuanian (Lithuania)
+#   - lv-LV: Latvian (Latvia)
+#   - nb-NO: Norwegian (Norway)
+#   - nl-NL: Dutch (Netherlands)
+#   - pl-PL: Polish (Poland)
+#   - pt-BR: Portuguese (Brazil)
+#   - pt-PT: Portuguese (Portugal)
+#   - ro-RO: Romanian (Romania)
+#   - ru-RU: Russian (Russia)
+#   - sh: Serbo-Croatian
+#   - sk-SK: Slovak (Slovakia)
+#   - sl-SI: Slovenian (Slovenia)
+#   - sq: Albanian
+#   - sr: Serbian
+#   - sv-SE: Swedish (Sweden)
+#   - ta-IN: Tamil (India)
+#   - tg-TG: Tajik (Tajikistan)
+#   - tr-TR: Turkish (Turkey)
+#   - uk-UA: Ukrainian (Ukraine)
+#   - vi-VN: Vietnamese (Viet Nam)
+c.spellcheck.languages = ['en-US', 'ru-RU']
+
+# Padding (in pixels) for the statusbar.
+# Type: Padding
+c.statusbar.padding = {'bottom': 1, 'left': 6, 'right': 6, 'top': 1}
+
+# Position of the status bar.
+# Type: VerticalPosition
+# Valid values:
+#   - top
+#   - bottom
+c.statusbar.position = 'bottom'
+
+# Open new tabs (middleclick/ctrl+click) in the background.
+# Type: Bool
+c.tabs.background = True
+
+# Mouse button with which to close tabs.
+# Type: String
+# Valid values:
+#   - right: Close tabs on right-click.
+#   - middle: Close tabs on middle-click.
+#   - none: Don't close tabs using the mouse.
+c.tabs.close_mouse_button = 'middle'
+
+# Scaling factor for favicons in the tab bar. The tab size is unchanged,
+# so big favicons also require extra `tabs.padding`.
+# Type: Float
+c.tabs.favicons.scale = 1.0
+
+# When to show favicons in the tab bar. When switching this from never
+# to always/pinned, note that favicons might not be loaded yet, thus
+# tabs might require a reload to display them.
+# Type: String
+# Valid values:
+#   - always: Always show favicons.
+#   - never: Always hide favicons.
+#   - pinned: Show favicons only on pinned tabs.
+c.tabs.favicons.show = 'pinned'
+
+# Switch between tabs using the mouse wheel.
+# Type: Bool
+c.tabs.mousewheel_switching = True
+
+# Position of new tabs opened from another tab. See
+# `tabs.new_position.stacking` for controlling stacking behavior.
+# Type: NewTabPosition
+# Valid values:
+#   - prev: Before the current tab.
+#   - next: After the current tab.
+#   - first: At the beginning.
+#   - last: At the end.
+c.tabs.new_position.related = 'next'
+
+# Position of new tabs which are not opened from another tab. See
+# `tabs.new_position.stacking` for controlling stacking behavior.
+# Type: NewTabPosition
+# Valid values:
+#   - prev: Before the current tab.
+#   - next: After the current tab.
+#   - first: At the beginning.
+#   - last: At the end.
+c.tabs.new_position.unrelated = 'last'
+
+# Padding (in pixels) around text for tabs.
+# Type: Padding
+c.tabs.padding = {'bottom': 1, 'left': 6, 'right': 6, 'top': 1}
+
+# Position of the tab bar.
+# Type: Position
+# Valid values:
+#   - top
+#   - bottom
+#   - left
+#   - right
+c.tabs.position = 'top'
+
+# Which tab to select when the focused tab is removed.
+# Type: SelectOnRemove
+# Valid values:
+#   - prev: Select the tab which came before the closed one (left in horizontal, above in vertical).
+#   - next: Select the tab which came after the closed one (right in horizontal, below in vertical).
+#   - last-used: Select the previously selected tab.
+c.tabs.select_on_remove = 'next'
+
+# Alignment of the text inside of tabs.
+# Type: TextAlignment
+# Valid values:
+#   - left
+#   - right
+#   - center
+c.tabs.title.alignment = 'left'
+
+# Format to use for the tab title. The following placeholders are
+# defined:  * `{perc}`: Percentage as a string like `[10%]`. *
+# `{perc_raw}`: Raw percentage, e.g. `10`. * `{current_title}`: Title of
+# the current web page. * `{title_sep}`: The string `" - "` if a title
+# is set, empty otherwise. * `{index}`: Index of this tab. *
+# `{aligned_index}`: Index of this tab padded with spaces to have the
+# same   width. * `{id}`: Internal tab ID of this tab. * `{scroll_pos}`:
+# Page scroll position. * `{host}`: Host of the current web page. *
+# `{backend}`: Either `webkit` or `webengine` * `{private}`: Indicates
+# when private mode is enabled. * `{current_url}`: URL of the current
+# web page. * `{protocol}`: Protocol (http/https/...) of the current web
+# page. * `{audio}`: Indicator for audio/mute status.
+# Type: FormatString
+c.tabs.title.format = '{audio}{index} : {current_title}'
+
+# Format to use for the tab title for pinned tabs. The same placeholders
+# like for `tabs.title.format` are defined.
+# Type: FormatString
+c.tabs.title.format_pinned = '{audio}{index}'
+
+# Minimum width (in pixels) of tabs (-1 for the default minimum size
+# behavior). This setting only applies when tabs are horizontal. This
+# setting does not apply to pinned tabs, unless `tabs.pinned.shrink` is
+# False.
+# Type: Int
+c.tabs.min_width = -1
+
+# Maximum width (in pixels) of tabs (-1 for no maximum). This setting
+# only applies when tabs are horizontal. This setting does not apply to
+# pinned tabs, unless `tabs.pinned.shrink` is False. This setting may
+# not apply properly if max_width is smaller than the minimum size of
+# tab contents, or smaller than tabs.min_width.
+# Type: Int
+c.tabs.max_width = -1
+
+# Width (in pixels) of the progress indicator (0 to disable).
+# Type: Int
+c.tabs.indicator.width = 0
+
+# Padding (in pixels) for tab indicators.
+# Type: Padding
+c.tabs.indicator.padding = {'bottom': 3, 'left': 3, 'right': 3, 'top': 3}
+
+# Shrink pinned tabs down to their contents.
+# Type: Bool
+c.tabs.pinned.shrink = True
+
+# Force pinned tabs to stay at fixed URL.
+# Type: Bool
+c.tabs.pinned.frozen = False
+
+# Page to open if :open -t/-b/-w is used without URL. Use `about:blank`
+# for a blank page.
+# Type: FuzzyUrl
+c.url.default_page = 'about:blank'
+
+# Search engines which can be used via the address bar.  Maps a search
+# engine name (such as `DEFAULT`, or `ddg`) to a URL with a `{}`
+# placeholder. The placeholder will be replaced by the search term, use
+# `{{` and `}}` for literal `{`/`}` braces.  The following further
+# placeholds are defined to configure how special characters in the
+# search terms are replaced by safe characters (called 'quoting'):  *
+# `{}` and `{semiquoted}` quote everything except slashes; this is the
+# most   sensible choice for almost all search engines (for the search
+# term   `slash/and&amp` this placeholder expands to `slash/and%26amp`).
+# * `{quoted}` quotes all characters (for `slash/and&amp` this
+# placeholder   expands to `slash%2Fand%26amp`). * `{unquoted}` quotes
+# nothing (for `slash/and&amp` this placeholder   expands to
+# `slash/and&amp`). * `{0}` means the same as `{}`, but can be used
+# multiple times.  The search engine named `DEFAULT` is used when
+# `url.auto_search` is turned on and something else than a URL was
+# entered to be opened. Other search engines can be used by prepending
+# the search engine name to the search term, e.g. `:open google
+# qutebrowser`.
+# Type: Dict
+c.url.searchengines = {'DEFAULT': 'https://duckduckgo.com/?q={}'}
+
+# Page(s) to open at the start.
+# Type: List of FuzzyUrl, or FuzzyUrl
+c.url.start_pages = 'about:blank'
+
+# URL parameters to strip with `:yank url`.
+# Type: List of String
+c.url.yank_ignored_parameters = ['ref', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']
+
+# Hide the window decoration.  This setting requires a restart on
+# Wayland.
+# Type: Bool
+c.window.hide_decoration = True
+
+# Format to use for the window title. The same placeholders like for
+# `tabs.title.format` are defined.
+# Type: FormatString
+c.window.title_format = '{perc}{current_title}{title_sep}qutebrowser'
+
+# Text color of the completion widget. May be a single color to use for
+# all columns or a list of three colors, one for each column.
+# Type: List of QtColor, or QtColor
+c.colors.completion.fg = ['#c5c8c6', '#c5c8c6', '#c5c8c6']
+
+# Background color of the completion widget for odd rows.
+# Type: QssColor
+c.colors.completion.odd.bg = '#161719'
+
+# Background color of the completion widget for even rows.
+# Type: QssColor
+c.colors.completion.even.bg = '#161719'
+
+# Foreground color of completion widget category headers.
+# Type: QtColor
+c.colors.completion.category.fg = '#c5c8c6'
+
+# Background color of the completion widget category headers.
+# Type: QssColor
+c.colors.completion.category.bg = '#161719'
+
+# Top border color of the completion widget category headers.
+# Type: QssColor
+c.colors.completion.category.border.top = '#161719'
+
+# Bottom border color of the completion widget category headers.
+# Type: QssColor
+c.colors.completion.category.border.bottom = '#161719'
+
+# Foreground color of the selected completion item.
+# Type: QtColor
+c.colors.completion.item.selected.fg = '#161719'
+
+# Background color of the selected completion item.
+# Type: QssColor
+c.colors.completion.item.selected.bg = '#c5c8c6'
+
+# Top border color of the selected completion item.
+# Type: QssColor
+c.colors.completion.item.selected.border.top = '#161719'
+
+# Bottom border color of the selected completion item.
+# Type: QssColor
+c.colors.completion.item.selected.border.bottom = '#161719'
+
+# Foreground color of the matched text in the completion.
+# Type: QtColor
+c.colors.completion.match.fg = '#cc6666'
+
+# Color of the scrollbar handle in the completion view.
+# Type: QssColor
+c.colors.completion.scrollbar.fg = '#c5c8c6'
+
+# Color of the scrollbar in the completion view.
+# Type: QssColor
+c.colors.completion.scrollbar.bg = '#161719'
+
+# Background color for the download bar.
+# Type: QssColor
+c.colors.downloads.bar.bg = '#161719'
+
+# Color gradient start for download backgrounds.
+# Type: QtColor
+c.colors.downloads.start.bg = '#0000aa'
+
+# Color gradient interpolation system for download text.
+# Type: ColorSystem
+# Valid values:
+#   - rgb: Interpolate in the RGB color system.
+#   - hsv: Interpolate in the HSV color system.
+#   - hsl: Interpolate in the HSL color system.
+#   - none: Don't show a gradient.
+c.colors.downloads.system.fg = 'none'
+
+# Color gradient interpolation system for download backgrounds.
+# Type: ColorSystem
+# Valid values:
+#   - rgb: Interpolate in the RGB color system.
+#   - hsv: Interpolate in the HSV color system.
+#   - hsl: Interpolate in the HSL color system.
+#   - none: Don't show a gradient.
+c.colors.downloads.system.bg = 'none'
+
+# Foreground color for downloads with errors.
+# Type: QtColor
+c.colors.downloads.error.fg = '#ffffff'
+
+# Background color for downloads with errors.
+# Type: QtColor
+c.colors.downloads.error.bg = '#cc6666'
+
+# Font color for hints.
+# Type: QssColor
+c.colors.hints.fg = '#c5c8c6'
+
+# Background color for hints. Note that you can use a `rgba(...)` value
+# for transparency.
+# Type: QssColor
+c.colors.hints.bg = '#161719'
+
+# Font color for the matched part of hints.
+# Type: QtColor
+c.colors.hints.match.fg = '#cc6666'
+
+# Text color for the keyhint widget.
+# Type: QssColor
+c.colors.keyhint.fg = '#c5c8c6'
+
+# Highlight color for keys to complete the current keychain.
+# Type: QssColor
+c.colors.keyhint.suffix.fg = '#cc6666'
+
+# Background color of the keyhint widget.
+# Type: QssColor
+c.colors.keyhint.bg = '#161719'
+
+# Foreground color of an error message.
+# Type: QssColor
+c.colors.messages.error.fg = '#ffffff'
+
+# Background color of an error message.
+# Type: QssColor
+c.colors.messages.error.bg = '#cc6666'
+
+# Border color of an error message.
+# Type: QssColor
+c.colors.messages.error.border = '#cc6666'
+
+# Foreground color of a warning message.
+# Type: QssColor
+c.colors.messages.warning.fg = '#ffffff'
+
+# Background color of a warning message.
+# Type: QssColor
+c.colors.messages.warning.bg = '#f0c674'
+
+# Border color of a warning message.
+# Type: QssColor
+c.colors.messages.warning.border = '#f9c674'
+
+# Foreground color of an info message.
+# Type: QssColor
+c.colors.messages.info.fg = '#c5c8c6'
+
+# Background color of an info message.
+# Type: QssColor
+c.colors.messages.info.bg = '#161719'
+
+# Border color of an info message.
+# Type: QssColor
+c.colors.messages.info.border = '#161719'
+
+# Foreground color for prompts.
+# Type: QssColor
+c.colors.prompts.fg = '#c5c8c6'
+
+# Border used around UI elements in prompts.
+# Type: String
+c.colors.prompts.border = '0px'
+
+# Background color for prompts.
+# Type: QssColor
+c.colors.prompts.bg = '#161719'
+
+# Background color for the selected item in filename prompts.
+# Type: QssColor
+c.colors.prompts.selected.bg = '#c5c8c6'
+
+# Foreground color of the statusbar.
+# Type: QssColor
+c.colors.statusbar.normal.fg = '#c5c8c6'
+
+# Background color of the statusbar.
+# Type: QssColor
+c.colors.statusbar.normal.bg = '#161719'
+
+# Foreground color of the statusbar in insert mode.
+# Type: QssColor
+c.colors.statusbar.insert.fg = '#ffffff'
+
+# Background color of the statusbar in insert mode.
+# Type: QssColor
+c.colors.statusbar.insert.bg = '#b6bd68'
+
+# Foreground color of the statusbar in passthrough mode.
+# Type: QssColor
+c.colors.statusbar.passthrough.fg = '#ffffff'
+
+# Background color of the statusbar in passthrough mode.
+# Type: QssColor
+c.colors.statusbar.passthrough.bg = '#b294bb'
+
+# Foreground color of the statusbar in private browsing mode.
+# Type: QssColor
+c.colors.statusbar.private.fg = '#161719'
+
+# Foreground color of the statusbar in command mode.
+# Type: QssColor
+c.colors.statusbar.command.fg = '#c5c8c6'
+
+# Background color of the statusbar in command mode.
+# Type: QssColor
+c.colors.statusbar.command.bg = '#161719'
+
+# Default foreground color of the URL in the statusbar.
+# Type: QssColor
+c.colors.statusbar.url.fg = '#ffffff'
+
+# Foreground color of the URL in the statusbar on error.
+# Type: QssColor
+c.colors.statusbar.url.error.fg = '#cc6666'
+
+# Foreground color of the URL in the statusbar for hovered links.
+# Type: QssColor
+c.colors.statusbar.url.hover.fg = '#81a2be'
+
+# Foreground color of the URL in the statusbar on successful load
+# (http).
+# Type: QssColor
+c.colors.statusbar.url.success.http.fg = '#b5bd68'
+
+# Foreground color of the URL in the statusbar on successful load
+# (https).
+# Type: QssColor
+c.colors.statusbar.url.success.https.fg = '#b5bd68'
+
+# Foreground color of the URL in the statusbar when there's a warning.
+# Type: QssColor
+c.colors.statusbar.url.warn.fg = '#f0c674'
+
+# Background color of the tab bar.
+# Type: QssColor
+c.colors.tabs.bar.bg = '#161719'
+
+# Color for the tab indicator on errors.
+# Type: QtColor
+c.colors.tabs.indicator.error = '#cc6666'
+
+# Color gradient interpolation system for the tab indicator.
+# Type: ColorSystem
+# Valid values:
+#   - rgb: Interpolate in the RGB color system.
+#   - hsv: Interpolate in the HSV color system.
+#   - hsl: Interpolate in the HSL color system.
+#   - none: Don't show a gradient.
+c.colors.tabs.indicator.system = 'none'
+
+# Foreground color of unselected odd tabs.
+# Type: QtColor
+c.colors.tabs.odd.fg = '#c5c8c6'
+
+# Background color of unselected odd tabs.
+# Type: QtColor
+c.colors.tabs.odd.bg = '#161719'
+
+# Foreground color of unselected even tabs.
+# Type: QtColor
+c.colors.tabs.even.fg = '#c5c8c6'
+
+# Background color of unselected even tabs.
+# Type: QtColor
+c.colors.tabs.even.bg = '#161719'
+
+# Foreground color of selected odd tabs.
+# Type: QtColor
+c.colors.tabs.selected.odd.fg = '#161719'
+
+# Background color of selected odd tabs.
+# Type: QtColor
+c.colors.tabs.selected.odd.bg = '#c5c8c6'
+
+# Foreground color of selected even tabs.
+# Type: QtColor
+c.colors.tabs.selected.even.fg = '#161719'
+
+# Background color of selected even tabs.
+# Type: QtColor
+c.colors.tabs.selected.even.bg = '#c5c8c6'
+
+# Foreground color of pinned unselected odd tabs.
+# Type: QtColor
+c.colors.tabs.pinned.odd.fg = '#a19782'
+
+# Background color of pinned unselected odd tabs.
+# Type: QtColor
+c.colors.tabs.pinned.odd.bg = '#2f2b2a'
+
+# Foreground color of pinned unselected even tabs.
+# Type: QtColor
+c.colors.tabs.pinned.even.fg = '#a19782'
+
+# Background color of pinned unselected even tabs.
+# Type: QtColor
+c.colors.tabs.pinned.even.bg = '#2f2b2a'
+
+# Background color for webpages if unset (or empty to use the theme's
+# color).
+# Type: QtColor
+c.colors.webpage.bg = 'white'
+
+# Value to use for `prefers-color-scheme:` for websites. The "light"
+# value is only available with QtWebEngine 5.15.2+. On older versions,
+# it is the same as "auto". The "auto" value is broken on QtWebEngine
+# 5.15.2 due to a Qt bug. There, it will fall back to "light"
+# unconditionally.
+# Type: String
+# Valid values:
+#   - auto: Use the system-wide color scheme setting.
+#   - light: Force a light theme.
+#   - dark: Force a dark theme.
+c.colors.webpage.preferred_color_scheme = 'dark'
+
+# Default font families to use. Whenever "default_family" is used in a
+# font setting, it's replaced with the fonts listed here. If set to an
+# empty value, a system-specific monospace default is used.
+# Type: List of Font, or Font
+c.fonts.default_family = 'UW Ttyp0'
+
+# Default font size to use. Whenever "default_size" is used in a font
+# setting, it's replaced with the size listed here. Valid values are
+# either a float value with a "pt" suffix, or an integer value with a
+# "px" suffix.
+# Type: String
+c.fonts.default_size = '14px'
+
+# Font used in the completion widget.
+# Type: Font
+c.fonts.completion.entry = 'default_size default_family'
+
+# Font used in the completion categories.
+# Type: Font
+c.fonts.completion.category = 'default_size default_family'
+
+# Font used for the context menu. If set to null, the Qt default is
+# used.
+# Type: Font
+c.fonts.contextmenu = 'default_size default_family'
+
+# Font used for the debugging console.
+# Type: Font
+c.fonts.debug_console = 'default_size default_family'
+
+# Font used for the downloadbar.
+# Type: Font
+c.fonts.downloads = 'default_size default_family'
+
+# Font used for the hints.
+# Type: Font
+c.fonts.hints = 'default_size default_family'
+
+# Font used in the keyhint widget.
+# Type: Font
+c.fonts.keyhint = 'default_size default_family'
+
+# Font used for error messages.
+# Type: Font
+c.fonts.messages.error = 'default_size default_family'
+
+# Font used for info messages.
+# Type: Font
+c.fonts.messages.info = 'default_size default_family'
+
+# Font used for warning messages.
+# Type: Font
+c.fonts.messages.warning = 'default_size default_family'
+
+# Font used for prompts.
+# Type: Font
+c.fonts.prompts = 'default_size default_family'
+
+# Font used in the statusbar.
+# Type: Font
+c.fonts.statusbar = 'default_size default_family'
+
+# Font family for standard fonts.
+# Type: FontFamily
+c.fonts.web.family.standard = None
+
+# Font family for fixed fonts.
+# Type: FontFamily
+c.fonts.web.family.fixed = None
+
+# Font family for serif fonts.
+# Type: FontFamily
+c.fonts.web.family.serif = None
+
+# Font family for sans-serif fonts.
+# Type: FontFamily
+c.fonts.web.family.sans_serif = None
+
+# Font family for cursive fonts.
+# Type: FontFamily
+c.fonts.web.family.cursive = None
+
+# Font family for fantasy fonts.
+# Type: FontFamily
+c.fonts.web.family.fantasy = None
+
+# Bindings for normal mode
+config.bind('z', 'hint links spawn --detach mpv {hint-url}')
diff --git a/qutebrowser/@install b/qutebrowser/@install
new file mode 100755
index 0000000..7cceb68
--- /dev/null
+++ b/qutebrowser/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/qutebrowser" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/qutebrowser"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    qutebrowser
diff --git a/r/.Rprofile b/r/.Rprofile
new file mode 100644
index 0000000..a4afb3b
--- /dev/null
+++ b/r/.Rprofile
@@ -0,0 +1,71 @@
+local({
+    r <- getOption("repos")
+    r["CRAN"] <- "http://cran.revolutionanalytics.com"
+    options(repos = r)
+})
+
+options(prompt="λ ")
+options(continue="    … ")
+
+options("digits.secs" = 3)
+options(browserNLdisabled = TRUE)
+options(editor = "vim")
+options(error = NULL)
+options(max.print = 100)
+options(max.print = 500)
+options(menu.graphics = FALSE)
+options(scipen = 10)
+options(show.signif.stars = FALSE)
+options(showErrorCalls = TRUE)
+options(showWarnCalls = TRUE)
+options(stringsAsFactors = FALSE)
+options(warn = 0)
+options(warnPartialMatchDollar = TRUE)
+options(width = 80)
+
+q <- function (save = "no", ...)
+    quit(save = save, ...)
+
+utils::rc.settings(ipck = TRUE)
+
+.First <- function()
+{
+    if (interactive())
+    {
+        library(utils)
+        timestamp(prefix = paste("##------ [", getwd(), "] ", sep = ""))
+    }
+}
+
+.Last <- function()
+{
+    if (interactive())
+    {
+        hist_file <- Sys.getenv("R_HISTFILE")
+        if (hist_file == "")
+            hist_file <- "~/.RHistory"
+        savehistory(hist_file)
+    }
+}
+
+if (Sys.getenv("TERM") == "xterm-256color")
+    library("colorout")
+
+.env <- new.env()
+
+.env$unrowname <- function(x)
+{
+    rownames(x) <- NULL
+    x
+}
+
+.env$unfactor <- function(df)
+{
+    id <- sapply(df, is.factor)
+    df[id] <- lapply(df[id], as.character)
+    df
+}
+
+attach(.env)
+
+# vim: filetype=r
diff --git a/r/@install b/r/@install
new file mode 100755
index 0000000..17864b4
--- /dev/null
+++ b/r/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    r
diff --git a/radare2/.radare2rc b/radare2/.radare2rc
new file mode 100644
index 0000000..4e9b694
--- /dev/null
+++ b/radare2/.radare2rc
@@ -0,0 +1,3 @@
+e io.cache = true
+e scr.color = true
+e scr.utf8 = true
diff --git a/radare2/@install b/radare2/@install
new file mode 100755
index 0000000..6267fb6
--- /dev/null
+++ b/radare2/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    radare2
diff --git a/readline/.inputrc b/readline/.inputrc
new file mode 100644
index 0000000..d789713
--- /dev/null
+++ b/readline/.inputrc
@@ -0,0 +1,65 @@
+$include /etc/inputrc
+
+set bell-style visible
+set bind-tty-special-chars off
+set blink-matching-paren on
+set colored-completion-prefix on
+set colored-stats on
+set completion-ignore-case on
+set convert-meta off
+set echo-control-characters off
+set editing-mode vi
+set input-meta on
+set mark-symlinked-directories on
+set match-hidden-files off
+set menu-complete-display-prefix on
+set meta-flag on
+set output-meta on
+set page-completions on
+set show-all-if-ambiguous on
+set show-all-if-unmodified on
+set show-mode-in-prompt on
+set visible-stats on
+
+$if mode=emacs
+	"\e[1~": beginning-of-line
+	"\e[4~": end-of-line
+	"\e[5C": forward-word
+	"\e[5D": backward-word
+	"\e[3~": delete-char
+	"\e[5~": history-search-backward
+	"\e[6~": history-search-forward
+	"\t": menu-complete
+$endif
+
+$if mode=vi
+	set keymap vi-command
+	"^": beginning-of-line
+	"$": end-of-line
+	"w": forward-word
+	"b": backward-word
+	"x": delete-char
+	"k": history-search-backward
+	"j": history-search-forward
+	"?": reverse-search-history
+	"/": forward-search-history
+	"gg": beginning-of-history
+	"G": end-of-history
+
+	set keymap vi-insert
+	"\C-l": clear-screen
+	"\C-w": backward-kill-word
+	"\C-a": beginning-of-line
+	"\C-e": end-of-line
+	"\C-p": history-search-backward
+	"\C-n": history-search-forward
+	"\t": menu-complete
+$endif
+
+$if term=linux
+	set vi-ins-mode-string \1\e[?0c\2
+	set vi-cmd-mode-string \1\e[?8c\2
+$else
+	set vi-ins-mode-string \1\e[6 q\2
+	set vi-cmd-mode-string \1\e[2 q\2
+$endif
diff --git a/readline/@install b/readline/@install
new file mode 100755
index 0000000..9a0d78d
--- /dev/null
+++ b/readline/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    readline
diff --git a/readme.org b/readme.org
new file mode 100644
index 0000000..fa73bad
--- /dev/null
+++ b/readme.org
@@ -0,0 +1,2 @@
+* dotfiles
+Deprecated and no longer be updated.
diff --git a/rhash/.rhashrc b/rhash/.rhashrc
new file mode 100644
index 0000000..fee871d
--- /dev/null
+++ b/rhash/.rhashrc
@@ -0,0 +1,2 @@
+percents=on
+recursive=on
diff --git a/rhash/@install b/rhash/@install
new file mode 100755
index 0000000..bcddf59
--- /dev/null
+++ b/rhash/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    rhash
diff --git a/ripgrep/.rgrc b/ripgrep/.rgrc
new file mode 100644
index 0000000..e6a3811
--- /dev/null
+++ b/ripgrep/.rgrc
@@ -0,0 +1,50 @@
+--color=auto
+--glob=!*.P
+--glob=!*.Po
+--glob=!*.crt
+--glob=!*.d
+--glob=!*.in
+--glob=!*.m4
+--glob=!*.pem
+--glob=!.bzr/*
+--glob=!.cabal-sandbox/*
+--glob=!.ccls-cache/*
+--glob=!.clang-format
+--glob=!.gdb_history
+--glob=!.ghc.environment.*
+--glob=!.git/*
+--glob=!.gitlab/*
+--glob=!.hg/*
+--glob=!.idea/*
+--glob=!.nupkg.metadata
+--glob=!.stack-work/*
+--glob=!.sublime-settings
+--glob=!.svn/*
+--glob=!.vs/*
+--glob=!.vscode/*
+--glob=!CMakeCache.txt
+--glob=!CMakeFiles/*
+--glob=!CODE_OF_CONDUCT.md
+--glob=!LICENSE
+--glob=!__pycache__/*
+--glob=!autom4te.cache/*
+--glob=!bin/Debug/*
+--glob=!bin/Release/*
+--glob=!build/*
+--glob=!cabal.project.*
+--glob=!cmake_install.cmake
+--glob=!compile_commands.json
+--glob=!config.status
+--glob=!configure
+--glob=!depcomp
+--glob=!dist-newstyle/*
+--glob=!dist/*
+--glob=!install-sh
+--glob=!ltmain.sh
+--glob=!missing
+--glob=!obj/*
+--glob=!stamp-h1
+--hidden
+--max-columns-preview
+--max-columns=100
+--smart-case
diff --git a/ripgrep/@install b/ripgrep/@install
new file mode 100755
index 0000000..1b606df
--- /dev/null
+++ b/ripgrep/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ripgrep
diff --git a/sbcl/.sbclrc b/sbcl/.sbclrc
new file mode 100644
index 0000000..fc64185
--- /dev/null
+++ b/sbcl/.sbclrc
@@ -0,0 +1,15 @@
+;;; -*- mode: Lisp -*-
+
+(setf (logical-pathname-translations "SYS")
+      '(("SYS:SRC;**;*.*.*" #p"/usr/lib64/sbcl/src/**/*.*")
+        ("SYS:CONTRIB;**;*.*.*" #p"/usr/lib64/sbcl/**/*.*")))
+
+(let ((gentoo-init "/etc/common-lisp/gentoo-init.lisp"))
+  (when (probe-file gentoo-init)
+    (load gentoo-init)))
+
+#-quicklisp
+(let ((quicklisp-init (merge-pathnames ".quicklisp/setup.lisp"
+                                       (user-homedir-pathname))))
+  (when (probe-file quicklisp-init)
+    (load quicklisp-init)))
diff --git a/sbcl/@install b/sbcl/@install
new file mode 100755
index 0000000..95585db
--- /dev/null
+++ b/sbcl/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    sbcl
diff --git a/sqlite/.sqliterc b/sqlite/.sqliterc
new file mode 100644
index 0000000..d02d822
--- /dev/null
+++ b/sqlite/.sqliterc
@@ -0,0 +1,3 @@
+.headers on
+.mode column
+.nullvalue NULL
diff --git a/sqlite/@install b/sqlite/@install
new file mode 100755
index 0000000..a67eb22
--- /dev/null
+++ b/sqlite/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    sqlite
diff --git a/ssh/.ssh/config b/ssh/.ssh/config
new file mode 100644
index 0000000..9ea4651
--- /dev/null
+++ b/ssh/.ssh/config
@@ -0,0 +1,17 @@
+Host *
+    Compression yes
+    ControlMaster auto
+    ControlPath ~/.ssh/%r@%h:%p
+    ControlPersist 24H
+    ForwardAgent no
+    ForwardX11 no
+    ForwardX11Trusted no
+    HashKnownHosts yes
+    IdentityFile ~/.ssh/azahi_ed25519
+    ServerAliveCountMax 30
+    ServerAliveInterval 60
+    TCPKeepAlive yes
+
+Include hosts
+
+# vim: filetype=sshconfig
diff --git a/ssh/@install b/ssh/@install
new file mode 100755
index 0000000..fde0f3f
--- /dev/null
+++ b/ssh/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.ssh" ] && \
+    mkdir -p "${HOME}/.ssh"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    ssh
diff --git a/stack/.stack/config.yaml b/stack/.stack/config.yaml
new file mode 100644
index 0000000..a7d5aec
--- /dev/null
+++ b/stack/.stack/config.yaml
@@ -0,0 +1,6 @@
+templates:
+  params:
+    author-name: Azat Bahawi
+    author-email: azahi@teknik.io
+    copyright: Copyright (C) 2020 Azat Bahawi
+    github-username: azahi
diff --git a/stack/.stack/global-project/stack.yaml b/stack/.stack/global-project/stack.yaml
new file mode 100644
index 0000000..8757b29
--- /dev/null
+++ b/stack/.stack/global-project/stack.yaml
@@ -0,0 +1,2 @@
+packages: []
+resolver: lts-16.22
diff --git a/stack/@install b/stack/@install
new file mode 100755
index 0000000..4a15a25
--- /dev/null
+++ b/stack/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.stack" ] && \
+    mkdir -p "${HOME}/.stack"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    stack
diff --git a/stow/.stow-global-ignore b/stow/.stow-global-ignore
new file mode 100644
index 0000000..fb8b116
--- /dev/null
+++ b/stow/.stow-global-ignore
@@ -0,0 +1,2 @@
+\.git
+\.svn
diff --git a/stow/@install b/stow/@install
new file mode 100755
index 0000000..e5f98c4
--- /dev/null
+++ b/stow/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    stow
diff --git a/streamlink/.local/etc/streamlink/config b/streamlink/.local/etc/streamlink/config
new file mode 100644
index 0000000..cdcd0c7
--- /dev/null
+++ b/streamlink/.local/etc/streamlink/config
@@ -0,0 +1,3 @@
+default-stream=1080p60,best
+player-no-close
+player=mpv
diff --git a/streamlink/@install b/streamlink/@install
new file mode 100755
index 0000000..1f6754b
--- /dev/null
+++ b/streamlink/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/streamlink" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/streamlink"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    streamlink
diff --git a/subversion/.subversion/config b/subversion/.subversion/config
new file mode 100644
index 0000000..c2f7fd0
--- /dev/null
+++ b/subversion/.subversion/config
@@ -0,0 +1,175 @@
+### This file configures various client-side behaviors.
+###
+### The commented-out examples below are intended to demonstrate
+### how to use this file.
+
+### Section for authentication and authorization customizations.
+[auth]
+### Set password stores used by Subversion. They should be
+### delimited by spaces or commas. The order of values determines
+### the order in which password stores are used.
+### Valid password stores:
+###   gnome-keyring        (Unix-like systems)
+###   kwallet              (Unix-like systems)
+###   gpg-agent            (Unix-like systems)
+###   keychain             (Mac OS X)
+###   windows-cryptoapi    (Windows)
+# password-stores = gpg-agent,gnome-keyring,kwallet
+### To disable all password stores, use an empty list:
+# password-stores =
+###
+### Set ssl-client-cert-file-prompt to 'yes' to cause the client
+### to prompt for a path to a client cert file when the server
+### requests a client cert but no client cert file is found in the
+### expected place (see the 'ssl-client-cert-file' option in the
+### 'servers' configuration file). Defaults to 'no'.
+# ssl-client-cert-file-prompt = no
+###
+### The rest of the [auth] section in this file has been deprecated.
+### Both 'store-passwords' and 'store-auth-creds' can now be
+### specified in the 'servers' file in your config directory
+### and are documented there. Anything specified in this section
+### is overridden by settings specified in the 'servers' file.
+# store-passwords = no
+# store-auth-creds = no
+
+### Section for configuring external helper applications.
+[helpers]
+### Set editor-cmd to the command used to invoke your text editor.
+###   This will override the environment variables that Subversion
+###   examines by default to find this information ($EDITOR,
+###   et al).
+# editor-cmd = editor (vi, emacs, notepad, etc.)
+### Set diff-cmd to the absolute path of your 'diff' program.
+###   This will override the compile-time default, which is to use
+###   Subversion's internal diff implementation.
+diff-cmd = colordiff
+### Diff-extensions are arguments passed to an external diff
+### program or to Subversion's internal diff implementation.
+### Set diff-extensions to override the default arguments ('-u').
+# diff-extensions = -u -p
+### Set diff3-cmd to the absolute path of your 'diff3' program.
+###   This will override the compile-time default, which is to use
+###   Subversion's internal diff3 implementation.
+# diff3-cmd = diff3_program (diff3, gdiff3, etc.)
+### Set diff3-has-program-arg to 'yes' if your 'diff3' program
+###   accepts the '--diff-program' option.
+# diff3-has-program-arg = [yes | no]
+### Set merge-tool-cmd to the command used to invoke your external
+### merging tool of choice. Subversion will pass 5 arguments to
+### the specified command: base theirs mine merged wcfile
+# merge-tool-cmd = merge_command
+
+### Section for configuring tunnel agents.
+[tunnels]
+### Configure svn protocol tunnel schemes here.  By default, only
+### the 'ssh' scheme is defined.  You can define other schemes to
+### be used with 'svn+scheme://hostname/path' URLs.  A scheme
+### definition is simply a command, optionally prefixed by an
+### environment variable name which can override the command if it
+### is defined.  The command (or environment variable) may contain
+### arguments, using standard shell quoting for arguments with
+### spaces.  The command will be invoked as:
+###   <command> <hostname> svnserve -t
+### (If the URL includes a username, then the hostname will be
+### passed to the tunnel agent as <user>@<hostname>.)  If the
+### built-in ssh scheme were not predefined, it could be defined
+### as:
+# ssh = $SVN_SSH ssh -q --
+### If you wanted to define a new 'rsh' scheme, to be used with
+### 'svn+rsh:' URLs, you could do so as follows:
+# rsh = rsh --
+### Or, if you wanted to specify a full path and arguments:
+# rsh = /path/to/rsh -l myusername --
+### On Windows, if you are specifying a full path to a command,
+### use a forward slash (/) or a paired backslash (\\) as the
+### path separator.  A single backslash will be treated as an
+### escape for the following character.
+
+### Section for configuring miscellaneous Subversion options.
+[miscellany]
+### Set global-ignores to a set of whitespace-delimited globs
+### which Subversion will ignore in its 'status' output, and
+### while importing or adding files and directories.
+### '*' matches leading dots, e.g. '*.rej' matches '.foo.rej'.
+global-ignores = .vscode .idea cmake-build-* *.tmp *.temp *.bak .ccls-cache .gdb_history .wakatime-project compile_commands.json cscope.* vgcore.* .ignore
+### Set log-encoding to the default encoding for log messages
+# log-encoding = latin1
+### Set use-commit-times to make checkout/update/switch/revert
+### put last-committed timestamps on every file touched.
+# use-commit-times = yes
+### Set no-unlock to prevent 'svn commit' from automatically
+### releasing locks on files.
+# no-unlock = yes
+### Set mime-types-file to a MIME type registry file, used to
+### provide hints to Subversion's MIME type auto-detection
+### algorithm.
+# mime-types-file = /path/to/mime.types
+### Set preserved-conflict-file-exts to a whitespace-delimited
+### list of patterns matching file extensions which should be
+### preserved in generated conflict file names.  By default,
+### conflict files use custom extensions.
+# preserved-conflict-file-exts = doc ppt xls od?
+### Set enable-auto-props to 'yes' to enable automatic properties
+### for 'svn add' and 'svn import', it defaults to 'no'.
+### Automatic properties are defined in the section 'auto-props'.
+# enable-auto-props = yes
+### Set interactive-conflicts to 'no' to disable interactive
+### conflict resolution prompting.  It defaults to 'yes'.
+# interactive-conflicts = no
+### Set memory-cache-size to define the size of the memory cache
+### used by the client when accessing a FSFS repository via
+### ra_local (the file:// scheme). The value represents the number
+### of MB used by the cache.
+# memory-cache-size = 16
+### Set diff-ignore-content-type to 'yes' to cause 'svn diff' to
+### attempt to show differences of all modified files regardless
+### of their MIME content type.  By default, Subversion will only
+### attempt to show differences for files believed to have human-
+### readable (non-binary) content.  This option is especially
+### useful when Subversion is configured (via the 'diff-cmd'
+### option) to employ an external differencing tool which is able
+### to show meaningful differences for binary file formats.  [New
+### in 1.9]
+diff-ignore-content-type = no
+
+### Section for configuring automatic properties.
+[auto-props]
+### The format of the entries is:
+###   file-name-pattern = propname[=value][;propname[=value]...]
+### The file-name-pattern can contain wildcards (such as '*' and
+### '?').  All entries which match (case-insensitively) will be
+### applied to the file.  Note that auto-props functionality
+### must be enabled, which is typically done by setting the
+### 'enable-auto-props' option.
+# *.c = svn:eol-style=native
+# *.cpp = svn:eol-style=native
+# *.h = svn:keywords=Author Date Id Rev URL;svn:eol-style=native
+# *.dsp = svn:eol-style=CRLF
+# *.dsw = svn:eol-style=CRLF
+# *.sh = svn:eol-style=native;svn:executable
+# *.txt = svn:eol-style=native;svn:keywords=Author Date Id Rev URL;
+# *.png = svn:mime-type=image/png
+# *.jpg = svn:mime-type=image/jpeg
+# Makefile = svn:eol-style=native
+
+### Section for configuring working copies.
+[working-copy]
+### Set to a list of the names of specific clients that should use
+### exclusive SQLite locking of working copies.  This increases the
+### performance of the client but prevents concurrent access by
+### other clients.  Third-party clients may also support this
+### option.
+### Possible values:
+###   svn                (the command line client)
+# exclusive-locking-clients =
+### Set to true to enable exclusive SQLite locking of working
+### copies by all clients using the 1.8 APIs.  Enabling this may
+### cause some clients to fail to work properly. This does not have
+### to be set for exclusive-locking-clients to work.
+# exclusive-locking = false
+### Set the SQLite busy timeout in milliseconds: the maximum time
+### the client waits to get access to the SQLite database before
+### returning an error.  The default is 10000, i.e. 10 seconds.
+### Longer values may be useful when exclusive locking is enabled.
+# busy-timeout = 10000
diff --git a/subversion/@install b/subversion/@install
new file mode 100755
index 0000000..5d15134
--- /dev/null
+++ b/subversion/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.subversion" ] && \
+    mkdir -p "${HOME}/.subversion"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    subversion
diff --git a/sx/.local/etc/sx/sxrc b/sx/.local/etc/sx/sxrc
new file mode 100755
index 0000000..8e65f35
--- /dev/null
+++ b/sx/.local/etc/sx/sxrc
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+if [ -f "${HOME}/.profile" ]; then
+    # shellcheck disable=SC1090
+    . "${HOME}/.profile"
+fi
+
+(
+    if command -v xrdb >/dev/null 2>&1 &&
+        [ -f "${HOME}/.Xresources" ]; then
+        xrdb "${HOME}/.Xresources"
+    fi
+
+    if command -v xset >/dev/null 2>&1; then
+        xset s off
+        xset -dpms
+        xset m 3/2 3
+        xset r rate 200 50
+    fi
+
+    if command -v setxkbmap >/dev/null 2>&1; then
+        setxkbmap \
+            -layout "us,ru" \
+            -variant ",phonetic" \
+            -option terminate:ctrl_alt_bksp \
+            -option caps:escape \
+            -option compose:menu \
+            -option grp:win_space_toggle
+    fi
+
+    if command -v xbindkeys >/dev/null 2>&1 &&
+        [ -f "${HOME}/.xbindkeysrc" ]; then
+        xbindkeys &
+    fi
+
+    if command -v xbanish >/dev/null 2>&1; then
+        xbanish &
+    fi
+
+    if command -v autocutsel >/dev/null 2>&1; then
+        autocutsel -fork -selection CLIPBOARD
+        autocutsel -fork -selection PRIMARY
+    fi
+
+    if command -v xgetres >/dev/null 2>&1; then
+        if command -v hsetroot >/dev/null 2>&1; then
+            hsetroot -solid "$(xgetres background)"
+        elif command -v xsetroot >/dev/null 2>&1; then
+            xsetroot -solid "$(xgetres background)"
+        fi
+    fi
+
+    if command -v picom >/dev/null 2>&1; then
+        picom --daemon
+    fi
+) &
+
+if command -v dbus-launch >/dev/null 2>&1 &&
+    [ -z "${DBUS_SESSION_BUS_ADDRESS}" ]; then
+    eval "$(dbus-launch --sh-syntax --exit-with-x11)"
+fi
+
+WM="dwm"
+if command -v "${WM}" >/dev/null 2>&1; then
+    if command -v wmname >/dev/null 2>&1; then
+        wmname "LG3D"
+    fi
+
+    if command -v dwm-status >/dev/null 2>&1; then
+        dwm-status &
+    fi
+
+    exec "${WM}"
+fi
diff --git a/sx/@install b/sx/@install
new file mode 100755
index 0000000..32da1b7
--- /dev/null
+++ b/sx/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/sx" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/sx"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    sx
diff --git a/tmux/.tmux.conf b/tmux/.tmux.conf
new file mode 100644
index 0000000..5253f5d
--- /dev/null
+++ b/tmux/.tmux.conf
@@ -0,0 +1,66 @@
+set -g default-terminal "screen-256color"
+
+set -g history-limit 10000
+
+set -g display-time 36000000
+set -g escape-time 0
+
+set -g base-index 1
+set -g pane-base-index 1
+
+set -g set-titles on
+
+set -g automatic-rename on
+
+set -g renumber-windows on
+
+set -g monitor-activity on
+set -g visual-activity off
+
+set -g status-justify left
+set -g status-position top
+
+set -g status-left ""
+set -g status-right ""
+
+set -g detach-on-destroy off
+
+set -g status-keys emacs
+set -g mode-keys   vi
+
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+
+bind F1 select-pane -t 1
+bind F2 select-pane -t 2
+bind F3 select-pane -t 3
+bind F4 select-pane -t 4
+bind F5 select-pane -t 5
+bind F6 select-pane -t 6
+bind F7 select-pane -t 7
+bind F8 select-pane -t 8
+bind F9 select-pane -t 9
+
+bind -r H resize-pane -L 10
+bind -r J resize-pane -D 10
+bind -r K resize-pane -U 10
+bind -r L resize-pane -R 10
+
+bind _ split-window -v
+bind | split-window -h
+
+bind -n M-F1 select-window -t 1
+bind -n M-F2 select-window -t 2
+bind -n M-F3 select-window -t 3
+bind -n M-F4 select-window -t 4
+bind -n M-F5 select-window -t 5
+bind -n M-F6 select-window -t 6
+bind -n M-F7 select-window -t 7
+bind -n M-F8 select-window -t 8
+bind -n M-F9 select-window -t 9
+
+bind Tab last-window
+
+bind c new-window -c "#{pane_current_path}"
diff --git a/tmux/@install b/tmux/@install
new file mode 100755
index 0000000..ec1f6d5
--- /dev/null
+++ b/tmux/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_DATA_HOME}/tmux" ] && \
+    mkdir -p "${XDG_DATA_HOME}/tmux"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    tmux
diff --git a/uim/.uim b/uim/.uim
new file mode 100644
index 0000000..493769d
--- /dev/null
+++ b/uim/.uim
@@ -0,0 +1,143 @@
+;;; -*- mode: scheme; -*-
+
+(define custom-activate-default-im-name? #t)
+(define custom-preserved-default-im-name 'skk)
+(define default-im-name 'skk)
+(define enabled-im-list '(skk))
+(define enable-im-switch? #f)
+(define switch-im-key '())
+(define switch-im-key? (make-key-predicate '()))
+(define switch-im-skip-direct-im? #f)
+(define enable-im-toggle? #f)
+(define toggle-im-key '())
+(define toggle-im-key? (make-key-predicate '()))
+(define toggle-im-alt-im 'direct)
+(define uim-color 'uim-color-uim)
+(define candidate-window-style 'vertical)
+(define candidate-window-position 'caret)
+(define enable-lazy-loading? #t)
+(define bridge-show-input-state? #f)
+(define bridge-show-with? 'time)
+(define bridge-show-input-state-time-length 3)
+
+
+(define toolbar-display-time 'never)
+
+
+(define uim-xim-use-xft-font? #t)
+(define uim-xim-xft-font-name "Source Sans Han")
+
+
+(define enable-annotation? #t)
+(define annotation-agent 'im)
+(define skk-show-annotation? #t)
+(define skk-show-annotation-in-preedit? #f)
+
+
+(define skk-use-candidate-window? #t)
+(define skk-commit-candidate-by-label-key? #t)
+(define skk-candidate-selection-style 'ddskk-like)
+(define skk-use-manual-candwin-setting? #f)
+(define skk-candidate-op-count 5)
+(define skk-nr-candidate-max 7)
+(define skk-widgets '(widget_skk_input_mode widget_skk_kana_input_method))
+(define default-widget_skk_input_mode 'action_skk_latin)
+(define skk-input-mode-actions '(action_skk_latin action_skk_hiragana action_skk_katakana action_skk_hankana action_skk_wide_latin))
+(define default-widget_skk_kana_input_method 'action_skk_roma)
+(define skk-kana-input-method-actions '(action_skk_roma action_skk_azik action_skk_act action_skk_kzik))
+
+
+(define skk-style 'skk-style-ddskk-like)
+(define skk-use-recursive-learning? #t)
+(define skk-use-numeric-conversion? #t)
+(define skk-auto-start-henkan? #t)
+(define skk-dcomp-activate? #t)
+(define skk-use-look? #f)
+(define skk-look-dict "")
+(define skk-show-annotation? #t)
+(define skk-show-annotation-in-preedit? #f)
+(define skk-use-with-vi? #t)
+(define skk-egg-like-newline? #t)
+(define skk-commit-newline-explicitly? #f)
+
+
+(define skk-use-skkserv? #f)
+(define skk-skkserv-enable-completion? #f)
+(define skk-skkserv-completion-timeout 2000)
+(define skk-skkserv-use-env? #t)
+(define skk-skkserv-hostname "localhost")
+(define skk-skkserv-portnum 1178)
+(define skk-skkserv-address-family 'unspecified)
+(define skk-dic-file-name "/usr/share/skk/SKK-JISYO.L")
+(define skk-personal-dic-filename "/home/azahi/.local/var/skk-jisyo")
+(define skk-uim-personal-dic-filename "/home/azahi/.local/var/skk-uim-jisyo")
+
+
+(define skk-on-key '("<IgnoreCase><Control>j" "zenkaku-hankaku" "<IgnoreShift><Alt>`"))
+(define skk-on-key? (make-key-predicate '("<IgnoreCase><Control>j" "zenkaku-hankaku" "<IgnoreShift><Alt>`")))
+(define skk-latin-key '("<IgnoreCase>l" "zenkaku-hankaku" "<IgnoreShift><Alt>`"))
+(define skk-latin-key? (make-key-predicate '("<IgnoreCase>l" "zenkaku-hankaku" "<IgnoreShift><Alt>`")))
+(define skk-wide-latin-key '("<IgnoreCase><Shift>l"))
+(define skk-wide-latin-key? (make-key-predicate '("<IgnoreCase><Shift>l")))
+(define skk-kcode-input-key '("yen"))
+(define skk-kcode-input-key? (make-key-predicate '("yen")))
+(define skk-kanji-mode-key '("<IgnoreCase><Shift>q"))
+(define skk-kanji-mode-key? (make-key-predicate '("<IgnoreCase><Shift>q")))
+(define skk-hankaku-kana-key '("<IgnoreCase><Control>q"))
+(define skk-hankaku-kana-key? (make-key-predicate '("<IgnoreCase><Control>q")))
+(define skk-kana-toggle-key '("<IgnoreCase>q"))
+(define skk-kana-toggle-key? (make-key-predicate '("<IgnoreCase>q")))
+(define skk-begin-conv-key '(" "))
+(define skk-begin-conv-key? (make-key-predicate '(" ")))
+(define skk-commit-key '("<IgnoreCase><Control>j"))
+(define skk-commit-key? (make-key-predicate '("<IgnoreCase><Control>j")))
+(define skk-cancel-key '("escape" "<IgnoreShift><Control>[" "<IgnoreCase><Control>g"))
+(define skk-cancel-key? (make-key-predicate '("escape" "<IgnoreShift><Control>[" "<IgnoreCase><Control>g")))
+(define skk-sticky-key '())
+(define skk-sticky-key? (make-key-predicate '()))
+
+
+(define skk-return-key '("return" "<IgnoreCase><Control>m"))
+(define skk-return-key? (make-key-predicate '("return" "<IgnoreCase><Control>m")))
+(define skk-latin-conv-key '("<IgnoreShift>/"))
+(define skk-latin-conv-key? (make-key-predicate '("<IgnoreShift>/")))
+(define skk-conv-wide-latin-key '("<IgnoreCase><Control>q"))
+(define skk-conv-wide-latin-key? (make-key-predicate '("<IgnoreCase><Control>q")))
+(define skk-conv-opposite-case-key '("<IgnoreCase><Control>u"))
+(define skk-conv-opposite-case-key? (make-key-predicate '("<IgnoreCase><Control>u")))
+(define skk-begin-completion-key '("tab" "<IgnoreCase><Control>i" "<Alt>tab" "<IgnoreCase><Control><Alt>i"))
+(define skk-begin-completion-key? (make-key-predicate '("tab" "<IgnoreCase><Control>i" "<Alt>tab" "<IgnoreCase><Control><Alt>i")))
+(define skk-next-completion-key '("<IgnoreShift>." "tab" "<IgnoreCase><Control>i"))
+(define skk-next-completion-key? (make-key-predicate '("<IgnoreShift>." "tab" "<IgnoreCase><Control>i")))
+(define skk-prev-completion-key '("<IgnoreShift>,"))
+(define skk-prev-completion-key? (make-key-predicate '("<IgnoreShift>,")))
+(define skk-new-completion-from-current-comp-key '("<Alt>tab" "<IgnoreCase><Control><Alt>i"))
+(define skk-new-completion-from-current-comp-key? (make-key-predicate '("<Alt>tab" "<IgnoreCase><Control><Alt>i")))
+(define skk-special-midashi-key '("<IgnoreShift>>" "<IgnoreShift><" "<IgnoreShift>?"))
+(define skk-special-midashi-key? (make-key-predicate '("<IgnoreShift>>" "<IgnoreShift><" "<IgnoreShift>?")))
+(define skk-vi-escape-key '("escape" "<IgnoreShift><Control>["))
+(define skk-vi-escape-key? (make-key-predicate '("escape" "<IgnoreShift><Control>[")))
+(define skk-state-direct-no-preedit-nop-key '("<IgnoreCase><Control>j"))
+(define skk-state-direct-no-preedit-nop-key? (make-key-predicate '("<IgnoreCase><Control>j")))
+(define skk-purge-candidate-key '("<IgnoreCase><Shift>x"))
+(define skk-purge-candidate-key? (make-key-predicate '("<IgnoreCase><Shift>x")))
+
+
+(define skk-begin-conv-with-completion-key '("<Alt> "))
+(define skk-begin-conv-with-completion-key? (make-key-predicate '("<Alt> ")))
+(define skk-commit-with-conv-completion-key '("<IgnoreCase><Control><Alt>j"))
+(define skk-commit-with-conv-completion-key? (make-key-predicate '("<IgnoreCase><Control><Alt>j")))
+(define skk-next-candidate-key '(" " "down" "<IgnoreCase><Control>n"))
+(define skk-next-candidate-key? (make-key-predicate '(" " "down" "<IgnoreCase><Control>n")))
+(define skk-prev-candidate-key '("<IgnoreCase>x" "up" "<IgnoreCase><Control>p"))
+(define skk-prev-candidate-key? (make-key-predicate '("<IgnoreCase>x" "up" "<IgnoreCase><Control>p")))
+(define skk-next-page-key '("next"))
+(define skk-next-page-key? (make-key-predicate '("next")))
+(define skk-prev-page-key '("prior"))
+(define skk-prev-page-key? (make-key-predicate '("prior")))
+(define skk-backspace-key '("backspace" "<IgnoreCase><Control>h"))
+(define skk-backspace-key? (make-key-predicate '("backspace" "<IgnoreCase><Control>h")))
+(define skk-go-left-key '("left" "<IgnoreCase><Control>b"))
+(define skk-go-left-key? (make-key-predicate '("left" "<IgnoreCase><Control>b")))
+(define skk-go-right-key '("right" "<IgnoreCase><Control>f"))
+(define skk-go-right-key? (make-key-predicate '("right" "<IgnoreCase><Control>f")))
diff --git a/uim/@install b/uim/@install
new file mode 100755
index 0000000..7e9a311
--- /dev/null
+++ b/uim/@install
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.uim.d" ] &&
+    mkdir -p "${HOME}/.uim.d"
+[ ! -d "${HOME}/.uim.d/customs" ] &&
+    mkdir -p "${HOME}/.uim.d/customs"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    uim
diff --git a/vim/.vim/vimrc b/vim/.vim/vimrc
new file mode 100644
index 0000000..a7f628b
--- /dev/null
+++ b/vim/.vim/vimrc
@@ -0,0 +1,236 @@
+set nocompatible
+
+let g:skip_defaults_vim = 1
+
+let $VIMFILES = expand('<sfile>:p:h')
+
+set autoread
+set backspace=indent,eol,start
+set clipboard=unnamed,unnamedplus
+set display+=lastline
+set fillchars=vert:\ "
+set hidden
+set history=1000
+set laststatus=2
+set lazyredraw
+set modeline
+set mouse=
+set noshowmode
+set path+=**
+set ruler
+set tabpagemax=50
+set viminfo=
+
+set sessionoptions-=options
+set viewoptions-=options
+
+set noerrorbells
+set novisualbell
+
+set splitbelow
+set splitright
+
+set complete=
+set complete+=.
+set complete+=b
+set complete+=t
+set completeopt=
+set completeopt+=menu
+set completeopt+=longest
+
+set gdefault
+set hlsearch
+set incsearch
+set iskeyword+=-
+set magic
+
+set foldmethod=marker
+set nofoldenable
+
+set shortmess=
+set shortmess+=I
+set shortmess+=T
+set shortmess+=a
+set shortmess+=c
+set shortmess+=t
+
+set nolist
+set nowrap
+
+set scrolloff=10
+set sidescrolloff=10
+
+set number
+if v:version >= 700
+    set numberwidth=3
+endif
+
+set wildignorecase
+set wildmenu
+set wildignore=
+
+set nobackup
+set noswapfile
+set noundofile
+set nowritebackup
+
+set smartcase
+set ignorecase
+
+set autoindent
+set breakindent
+set smartindent
+
+set expandtab
+set shiftround
+set shiftwidth=4
+set smarttab
+set softtabstop=4
+set tabstop=4
+
+if &t_Co == 8 && $TERM !~# '^Eterm'
+    set t_Co=16
+endif
+
+if &listchars ==# 'eol:$'
+    set listchars=tab:>\ ,trail:-,extends:>,precedes:<,nbsp:+
+endif
+
+if v:version > 703 || v:version == 703 && has("patch541")
+    set formatoptions+=j
+endif
+
+if has('path_extra')
+    setglobal tags-=./tags tags-=./tags; tags^=./tags;
+endif
+
+if !has('nvim') && &ttimeoutlen == -1
+    set ttimeout
+    set ttimeoutlen=100
+endif
+
+try
+    set encoding=utf-8
+    scriptencoding utf-8
+catch
+endtry
+
+try
+    if &fileencodings !~? "utf-8"
+        let g:added_fenc_utf8 = 1
+        set fileencodings+=utf-8
+    endif
+catch
+endtry
+
+if has('autocmd')
+    filetype plugin indent on
+
+    if exists("+omnifunc")
+        autocmd Filetype *
+                    \ if &omnifunc == "" |
+                    \ setlocal omnifunc=syntaxcomplete#Complete |
+                    \ endif
+    endif
+
+    autocmd BufEnter * set noreadonly
+endif
+
+if has('syntax') && !exists('g:syntax_on')
+    syntax enable
+endif
+
+if !exists('g:loaded_matchit') && findfile('plugin/matchit.vim', &rtp) ==# ''
+    runtime! macros/matchit.vim
+endif
+
+let mapleader = ' '
+
+nnoremap <Expr> j           v:count ? 'j' : 'gj'
+nnoremap <Expr> k           v:count ? 'k' : 'gk'
+
+nnoremap        J           gt
+nnoremap        K           gT
+
+nnoremap        <C-a>       ^h
+vnoremap        <C-a>       ^h
+nnoremap        H           ^h
+vnoremap        H           ^h
+
+nnoremap        <C-e>       $
+vnoremap        <C-e>       $
+nnoremap        L           $
+vnoremap        L           $
+
+nnoremap        N           Nzzzv
+nnoremap        n           nzzzv
+
+inoremap        <C-u>       <C-g>u<C-u>
+inoremap        <C-w>       <C-g>u<C-w>
+
+vnoremap        <           <gv
+vnoremap        >           >gv
+vnoremap        <Tab>       >gv
+vnoremap        <S-Tab>     <gv
+nnoremap        <Tab>       >>_
+nnoremap        <S-Tab>     <<_
+
+nnoremap        ]b          :<C-u>bnext<CR>
+nnoremap        [b          :<C-u>bprevious<CR>
+
+nnoremap        <C-h>       <C-w>h
+nnoremap        <C-j>       <C-w>j
+nnoremap        <C-k>       <C-w>k
+nnoremap        <C-l>       <C-w>l
+
+nnoremap        *           /\<<C-r>=expand('<cword>')<CR>\><CR>
+nnoremap        #           ?\<<C-r>=expand('<cword>')<CR>\><CR>
+
+nnoremap        <C-L>       :<C-u>nohlsearch<C-r>=has('diff')?'<Bar>diffupdate':''<CR><CR><C-l>
+
+cnoremap        ;/          <C-r>=expand('%:p:h').'/'<CR>
+cnoremap        ;;          <C-r>=expand('%:t')<CR>
+cnoremap        ;.          <C-r>=expand('%:p:r')<CR>
+
+nnoremap        <Leader>.   :<C-u>lcd %:p:h<CR>
+
+nnoremap        Q           @q
+
+nnoremap        <Leader>c   ^v$h
+nnoremap        <Leader>v   ggVG
+
+nnoremap        <Leader>y   "+y
+nnoremap        <Leader>Y   "+Y
+
+nnoremap        <Leader>p   "+p
+nnoremap        <Leader>P   "+P
+
+inoremap        <C-v>       <C-c>"+pi
+cnoremap        <C-v>       <C-r>+
+
+nmap            <Leader>w   :<C-u>w!<CR>
+nmap            <Leader>wq  :<C-u>wq!<CR>
+
+nnoremap        ZX          :<C-u>qa!<CR>
+
+nnoremap        <Leader>q   :<C-u>q<CR>
+
+command         W           w !sudo tee "%" >/dev/null
+
+function! SwitchCase()
+    normal! ~
+    if strlen(getline('.')) != virtcol('.')
+        normal! h
+    endif
+endfunction
+nnoremap        ~           :<C-u>call SwitchCase()<CR>
+
+function! s:GM()
+    execute 'normal! ^'
+    let first_col = virtcol('.')
+    execute 'normal! g_'
+    let last_col  = virtcol('.')
+    execute 'normal! ' . (first_col + last_col) / 2 . '|'
+endfunction
+nnoremap        gm          :<C-u>call <SID>GM()<CR>
+onoremap        gm          :<C-u>call <SID>GM()<CR>
diff --git a/vim/@install b/vim/@install
new file mode 100755
index 0000000..acf3500
--- /dev/null
+++ b/vim/@install
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.vim" ] && \
+    mkdir -p "${HOME}/.vim"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    vim
+
+if command -v nvim >/dev/null 2>&1 && [ ! -f "${XDG_CONFIG_HOME}/nvim/init.vim" ]
+then
+    mkdir -p "${XDG_CONFIG_HOME}/nvim"
+    ln -s "${HOME}/.vim/vimrc" "${XDG_CONFIG_HOME}/nvim/init.vim"
+fi
diff --git a/wget/.wgetrc b/wget/.wgetrc
new file mode 100644
index 0000000..862bb57
--- /dev/null
+++ b/wget/.wgetrc
@@ -0,0 +1,13 @@
+adjust_extension = on
+dirstruct = off
+follow_ftp = on
+hsts = 0
+passive_ftp = off
+quota = inf
+reclevel = 5
+recursive = off
+robots = off
+timestamping = off
+tries = 5
+wait = 0
+waitretry = 10
diff --git a/wget/@install b/wget/@install
new file mode 100755
index 0000000..75a3b2b
--- /dev/null
+++ b/wget/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    wget
diff --git a/xbindkeys/.xbindkeysrc b/xbindkeys/.xbindkeysrc
new file mode 100644
index 0000000..abb760b
--- /dev/null
+++ b/xbindkeys/.xbindkeysrc
@@ -0,0 +1,69 @@
+keystate_numlock = disable
+keystate_capslock = disable
+keystate_scrolllock= disable
+
+"st -e tmux"
+    Mod4 + Return
+
+"st -e tmux attach"
+    Mod4 + Shift + Return
+
+"st -e ncmpcpp"
+    Mod4 + Shift + m
+
+"st -e htop"
+    Mod4 + Shift + t
+
+"dmenu_run"
+    Mod4 + x
+
+"gentoo-passmenu"
+    Mod4 + Shift + p
+
+"otpmenu"
+    Mod4 + Control + p
+
+"qutebrowser"
+    Mod4 + w
+
+"xset dpms force suspend && slock"
+    XF86ScreenSaver
+
+"mon"
+    XF86Display
+
+"sus"
+    XF86Sleep
+
+"hib"
+    Shift + XF86Sleep
+
+"amixer sset Master toggle"
+    XF86AudioMute
+
+"amixer sset Master unmute 5%+"
+    XF86AudioRaiseVolume
+
+"amixer sset Master unmute 5%-"
+    XF86AudioLowerVolume
+
+"amixer sset Capture toggle"
+    XF86AudioMicMute
+
+"amixer sset Capture unmute 5%+"
+    Shift + XF86AudioRaiseVolume
+
+"amixer sset Capture unmute 5%-"
+    Shift + XF86AudioLowerVolume
+
+"mpc --quiet toggle"
+    XF86AudioPlay
+
+"mpc --quiet stop"
+    XF86AudioStop
+
+"mpc --quiet next"
+    XF86AudioNext
+
+"mpc --quiet prev"
+    XF86AudioPrev
diff --git a/xbindkeys/@install b/xbindkeys/@install
new file mode 100755
index 0000000..48067d9
--- /dev/null
+++ b/xbindkeys/@install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    xbindkeys
diff --git a/xdg/.local/etc/user-dirs.conf b/xdg/.local/etc/user-dirs.conf
new file mode 100644
index 0000000..24be7cf
--- /dev/null
+++ b/xdg/.local/etc/user-dirs.conf
@@ -0,0 +1,2 @@
+enabled=True
+filename_encoding=UTF-8
diff --git a/xdg/.local/etc/user-dirs.dirs b/xdg/.local/etc/user-dirs.dirs
new file mode 100644
index 0000000..9dd2a0a
--- /dev/null
+++ b/xdg/.local/etc/user-dirs.dirs
@@ -0,0 +1,12 @@
+XDG_CACHE_HOME="/tmp/.private/$USER/cache"
+XDG_CONFIG_HOME="$HOME/.etc"
+XDG_DATA_HOME="$HOME/.var/lib"
+XDG_DESKTOP_DIR="$HOME/tmp"
+XDG_DOCUMENTS_DIR="$HOME/doc"
+XDG_DOWNLOAD_DIR="$HOME/tmp"
+XDG_MUSIC_DIR="$HOME/music"
+XDG_PICTURES_DIR="$HOME/pic"
+XDG_PUBLICSHARE_DIR="$HOME/tmp"
+XDG_RUNTIME_DIR="$HOME/.var/run"
+XDG_TEMPLATES_DIR="$HOME/tmp"
+XDG_VIDEOS_DIR="$HOME/vid"
diff --git a/xdg/.local/etc/user-dirs.locale b/xdg/.local/etc/user-dirs.locale
new file mode 100644
index 0000000..3e0b419
--- /dev/null
+++ b/xdg/.local/etc/user-dirs.locale
@@ -0,0 +1 @@
+en_US
\ No newline at end of file
diff --git a/xdg/@install b/xdg/@install
new file mode 100755
index 0000000..15d2b98
--- /dev/null
+++ b/xdg/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    xdg
diff --git a/xresources/.Xresources b/xresources/.Xresources
new file mode 100644
index 0000000..c3fb5bf
--- /dev/null
+++ b/xresources/.Xresources
@@ -0,0 +1,4 @@
+#include ".xresources.d/color"
+#include ".xresources.d/font"
+#include ".xresources.d/xft"
+#include ".xresources.d/xcursor"
diff --git a/xresources/.Xresources.d/color b/xresources/.Xresources.d/color
new file mode 100644
index 0000000..ce944c4
--- /dev/null
+++ b/xresources/.Xresources.d/color
@@ -0,0 +1,38 @@
+#define color_black0    #161719
+#define color_black1    #969896
+#define color_red0      #cc6666
+#define color_red1      #cc6666
+#define color_green0    #b5bd68
+#define color_green1    #b5bd68
+#define color_yellow0   #f0c674
+#define color_yellow1   #f0c674
+#define color_blue0     #81a2be
+#define color_blue1     #81a2be
+#define color_magenta0  #b294bb
+#define color_magenta1  #b294bb
+#define color_cyan0     #8abeb7
+#define color_cyan1     #8abeb7
+#define color_white0    #c5c8c6
+#define color_white1    #ffffff
+
+*.color0:       color_black0
+*.color8:       color_black1
+*.color1:       color_red0
+*.color9:       color_red1
+*.color2:       color_green0
+*.color10:      color_green1
+*.color3:       color_yellow0
+*.color11:      color_yellow1
+*.color4:       color_blue0
+*.color12:      color_blue1
+*.color5:       color_magenta0
+*.color13:      color_magenta1
+*.color6:       color_cyan0
+*.color14:      color_cyan1
+*.color7:       color_white0
+*.color15:      color_white1
+
+*.background:   color_black0
+*.foreground:   color_white0
+
+! vim:filetype=xdefaults
diff --git a/xresources/.Xresources.d/font b/xresources/.Xresources.d/font
new file mode 100644
index 0000000..d7ed019
--- /dev/null
+++ b/xresources/.Xresources.d/font
@@ -0,0 +1,6 @@
+#define font1 UW Ttyp0:pixelsize=14:style=Regular:antialias=false
+#define font2 Efont Biwidth:pixelsize=14:style=Regular:antialias=false
+
+*.font: font1
+
+! vim:filetype=xdefaults
diff --git a/xresources/.Xresources.d/xcursor b/xresources/.Xresources.d/xcursor
new file mode 100644
index 0000000..fa59848
--- /dev/null
+++ b/xresources/.Xresources.d/xcursor
@@ -0,0 +1,5 @@
+Xcursor.theme:      core
+Xcursor.theme_core: true
+Xcursor.size:       16
+
+! vim:filetype=xdefaults
diff --git a/xresources/.Xresources.d/xft b/xresources/.Xresources.d/xft
new file mode 100644
index 0000000..f0175b2
--- /dev/null
+++ b/xresources/.Xresources.d/xft
@@ -0,0 +1,9 @@
+Xft.antialias:  1
+Xft.autohint:   0
+Xft.dpi:        96
+Xft.hinting:    1
+Xft.hintstyle:  hintslight
+Xft.lcdfilter:  lcddefault
+Xft.rgba:       rgb
+
+! vim:filetype=xdefaults
diff --git a/xresources/@install b/xresources/@install
new file mode 100755
index 0000000..f1432b0
--- /dev/null
+++ b/xresources/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.Xresources.d" ] && \
+    mkdir -p "${HOME}/.Xresources.d"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    xresources
diff --git a/youtube-dl/.local/etc/youtube-dl/config b/youtube-dl/.local/etc/youtube-dl/config
new file mode 100644
index 0000000..8309d10
--- /dev/null
+++ b/youtube-dl/.local/etc/youtube-dl/config
@@ -0,0 +1,15 @@
+--buffer-size 1024
+--continue
+--external-downloader aria2c
+--external-downloader-args '-k 2M'
+--geo-bypass
+--hls-prefer-ffmpeg
+--no-call-home
+--no-check-certificate
+--no-playlist
+--prefer-ffmpeg
+--prefer-free-formats
+--restrict-filenames
+--retries 3
+--skip-unavailable-fragments
+--youtube-skip-dash-manifest
diff --git a/youtube-dl/@install b/youtube-dl/@install
new file mode 100755
index 0000000..4a90a65
--- /dev/null
+++ b/youtube-dl/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${XDG_CONFIG_HOME}/youtube-dl" ] && \
+    mkdir -p "${XDG_CONFIG_HOME}/youtube-dl"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    youtube-dl
diff --git a/zsh/.zlogin b/zsh/.zlogin
new file mode 100644
index 0000000..350d066
--- /dev/null
+++ b/zsh/.zlogin
@@ -0,0 +1,28 @@
+#!/usr/bin/env zsh
+
+(
+    autoload -U zrecompile
+
+    lazy_zrecompile()
+    {
+        if [[ -s "${1}" && ( ! -s "${1}.zwc" || "${1}" -nt "${1}.zwc" ) ]]
+        then
+            zrecompile -pq "${1}"
+        fi
+    }
+
+    FLIST=(
+        ${ZCOMPDUMP}
+        ${ZLOGIN}
+        ${ZLOGOUT}
+        ${ZPROFILE}
+        ${ZSHENV}
+        ${ZSHRC}
+        ${HOME}/.zsh.d/*.zsh
+    )
+
+    for i in ${FLIST}
+    do
+        lazy_zrecompile "${i}"
+    done
+) &!
diff --git a/zsh/.zlogout b/zsh/.zlogout
new file mode 100644
index 0000000..d23ba0a
--- /dev/null
+++ b/zsh/.zlogout
@@ -0,0 +1,12 @@
+#!/usr/bin/env zsh
+
+if [ -f "${HOME}/.bin/logout-hook" ]
+then
+    source "${HOME}/.bin/logout-hook"
+
+    rm_existing "${ZLOGIN}.zwc.old"
+    rm_existing "${ZLOGOUT}.zwc.old"
+    rm_existing "${ZPROFILE}.zwc.old"
+    rm_existing "${ZSHENV}.zwc.old"
+    rm_existing "${ZSHRC}.zwc.old"
+fi
diff --git a/zsh/.zprofile b/zsh/.zprofile
new file mode 100644
index 0000000..b8f4712
--- /dev/null
+++ b/zsh/.zprofile
@@ -0,0 +1,6 @@
+#!/usr/bin/env zsh
+
+if [ -f "${HOME}"/.profile ]
+then
+    emulate sh -c ". ${HOME}/.profile"
+fi
diff --git a/zsh/.zsh.d/00_terminfo.zsh b/zsh/.zsh.d/00_terminfo.zsh
new file mode 100644
index 0000000..5f15f4a
--- /dev/null
+++ b/zsh/.zsh.d/00_terminfo.zsh
@@ -0,0 +1,16 @@
+#!/usr/bin/env zsh
+
+if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} ))
+then
+    function zle-line-init ()
+    {
+        echoti smkx
+    }
+    zle -N zle-line-init
+
+    function zle-line-finish ()
+    {
+        echoti rmkx
+    }
+    zle -N zle-line-finish
+fi
diff --git a/zsh/.zsh.d/10_options.zsh b/zsh/.zsh.d/10_options.zsh
new file mode 100644
index 0000000..785ccb8
--- /dev/null
+++ b/zsh/.zsh.d/10_options.zsh
@@ -0,0 +1,17 @@
+#!/usr/bin/env zsh
+
+setopt CLOBBER
+setopt GLOB_DOTS
+setopt INTERACTIVE_COMMENTS
+setopt LONG_LIST_JOBS
+setopt MAGIC_EQUAL_SUBST
+setopt NOTIFY
+setopt PROMPT_SUBST
+setopt PUSHD_IGNORE_DUPS
+setopt PUSHD_SILENT
+setopt PUSHD_TO_HOME
+setopt RC_QUOTES
+unsetopt BEEP
+unsetopt BG_NICE
+unsetopt CHECK_JOBS
+unsetopt CORRECT_ALL
diff --git a/zsh/.zsh.d/20_history.zsh b/zsh/.zsh.d/20_history.zsh
new file mode 100644
index 0000000..d1931f3
--- /dev/null
+++ b/zsh/.zsh.d/20_history.zsh
@@ -0,0 +1,20 @@
+#!/usr/bin/env zsh
+
+[ "${HISTFILE: -4}" != "_zsh" ] && export HISTFILE="${HISTFILE}_zsh"
+export SAVEHIST="${HISTSIZE}"
+
+setopt APPEND_HISTORY
+setopt BANG_HIST
+setopt EXTENDED_HISTORY
+setopt HIST_EXPIRE_DUPS_FIRST
+setopt HIST_IGNORE_ALL_DUPS
+setopt HIST_IGNORE_DUPS
+setopt HIST_IGNORE_SPACE
+setopt HIST_REDUCE_BLANKS
+setopt HIST_SAVE_NO_DUPS
+setopt HIST_VERIFY
+setopt INC_APPEND_HISTORY
+setopt SHARE_HISTORY
+unsetopt HIST_BEEP
+
+export HISTIGNORE="ls:cd:cd -:pwd:exit:date:cal:* --help"
diff --git a/zsh/.zsh.d/30_completion.zsh b/zsh/.zsh.d/30_completion.zsh
new file mode 100644
index 0000000..bd720d1
--- /dev/null
+++ b/zsh/.zsh.d/30_completion.zsh
@@ -0,0 +1,77 @@
+#!/usr/bin/env zsh
+
+autoload -Uz compinit
+if [[ -s ${ZCOMPDUMP}(#qN.mh+12) && ( ! -s "${ZCOMPDUMP}.zwc" || "${ZCOMPDUMP}" -nt "${ZCOMPDUMP}.zwc" ) ]]
+then
+    compinit -d "${ZCOMPDUMP}"
+    zrecompile -pq "${ZCOMPDUMP}"
+else
+    compinit -d "${ZCOMPDUMP}" -C
+fi
+
+setopt AUTO_LIST
+setopt AUTO_MENU
+setopt AUTO_PARAM_KEYS
+setopt AUTO_PARAM_SLASH
+setopt COMPLETE_IN_WORD
+setopt EXTENDED_GLOB
+setopt HASH_LIST_ALL
+setopt LIST_PACKED
+setopt PATH_DIRS
+unsetopt CASE_GLOB
+unsetopt FLOW_CONTROL
+unsetopt MENU_COMPLETE
+
+zstyle ':completion:*' use-cache                on
+zstyle ':completion:*' cache-path               "${XDG_CACHE_HOME:-$HOME}/.zcompcache"
+
+zstyle ':completion:*'                          format '%F{blue}%d%f'
+zstyle ':completion:*:corrections'              format '%F{yellow}%d (errors: %e)%f'
+zstyle ':completion:*:descriptions'             format '%F{green}%d%f'
+zstyle ':completion:*:messages'                 format '%F{purple}%d%f'
+zstyle ':completion:*:warnings'                 format '%F{red}no matches found%f'
+
+zstyle ':completion:*:*:*:*:*'                  menu select
+zstyle ':completion:*:matches'                  group 'yes'
+zstyle ':completion:*:options'                  description 'yes'
+zstyle ':completion:*:options'                  auto-description '%d'
+zstyle ':completion:*:corrections'              format ' %F{green}-- %d (errors: %e) --%f'
+zstyle ':completion:*:descriptions'             format ' %F{yellow}-- %d --%f'
+zstyle ':completion:*:messages'                 format ' %F{purple} -- %d --%f'
+zstyle ':completion:*:warnings'                 format ' %F{red}-- no matches found --%f'
+zstyle ':completion:*:default'                  list-prompt '%S%M matches%s'
+zstyle ':completion:*'                          format ' %F{yellow}-- %d --%f'
+zstyle ':completion:*'                          group-name ''
+zstyle ':completion:*'                          verbose yes
+zstyle ':completion:*'                          matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
+
+zstyle ':completion:*'                          squeeze-slashes true
+zstyle ':completion:*:default'                  list-colors ${(s.:.)LS_COLORS}
+zstyle ':completion:*:*:cd:*'                   tag-order local-directories directory-stack path-directories
+zstyle ':completion:*:*:cd:*:directory-stack'   menu yes select
+zstyle ':completion:*:-tilde-:*'                group-order 'named-directories' 'path-directories' 'users' 'expand'
+
+zstyle ':completion:*'                          completer _complete _match _approximate
+zstyle ':completion:*:match:*'                  original only
+zstyle ':completion:*:approximate:*'            max-errors 1 numeric
+
+zstyle ':completion:*:functions'                ignored-patterns '(_*|pre(cmd|exec))'
+
+zstyle ':completion:*:history-words'            stop yes
+zstyle ':completion:*:history-words'            remove-all-dups yes
+zstyle ':completion:*:history-words'            list false
+zstyle ':completion:*:history-words'            menu yes
+
+zstyle ':completion::*:(-command-|export):*'    fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-}
+
+zstyle ':completion:*:(rm|kill|diff):*'         ignore-line other
+zstyle ':completion:*:rm:*'                     file-patterns '*:all-files'
+
+zstyle ':completion:*:*:*:*:processes'          command 'ps -u ${LOGNAME} -o pid,user,command -w'
+zstyle ':completion:*:*:kill:*:processes'       list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01'
+zstyle ':completion:*:*:kill:*'                 menu yes select
+zstyle ':completion:*:*:kill:*'                 force-list always
+zstyle ':completion:*:*:kill:*'                 insert-ids single
+
+zstyle ':completion:*:manuals'                  separate-sections true
+zstyle ':completion:*:manuals.(^1*)'            insert-sections true
diff --git a/zsh/.zsh.d/40_keybindings.zsh b/zsh/.zsh.d/40_keybindings.zsh
new file mode 100644
index 0000000..1be223d
--- /dev/null
+++ b/zsh/.zsh.d/40_keybindings.zsh
@@ -0,0 +1,3 @@
+#!/usr/bin/env zsh
+
+bindkey '^[[Z'  reverse-menu-complete   # M-TAB
diff --git a/zsh/.zsh.d/50_colors.zsh b/zsh/.zsh.d/50_colors.zsh
new file mode 100644
index 0000000..bc122a6
--- /dev/null
+++ b/zsh/.zsh.d/50_colors.zsh
@@ -0,0 +1,3 @@
+#!/usr/bin/env zsh
+
+autoload -U colors && colors
diff --git a/zsh/.zsh.d/60_prompt.zsh b/zsh/.zsh.d/60_prompt.zsh
new file mode 100644
index 0000000..4b07a2c
--- /dev/null
+++ b/zsh/.zsh.d/60_prompt.zsh
@@ -0,0 +1,6 @@
+#!/usr/bin/env zsh
+
+precmd ()
+{
+    PROMPT="%{$fg[green]%}%~%{$reset_color%} %{$fg_bold[green]%}λ%{$reset_color%} "
+}
diff --git a/zsh/.zsh.d/80_plugins.zsh b/zsh/.zsh.d/80_plugins.zsh
new file mode 100644
index 0000000..dbabba3
--- /dev/null
+++ b/zsh/.zsh.d/80_plugins.zsh
@@ -0,0 +1,32 @@
+#!/usr/bin/env zsh
+
+if [ "${TERM}" != "linux" ]
+then
+    ZGENOM_DIR="${HOME}/.zsh.d/zgenom"
+
+    if [ ! -d "${ZGENOM_DIR}" ]
+    then
+        git clone "https://github.com/jandamm/zgenom.git" "${ZGENOM_DIR}"
+    fi
+
+    source "${ZGENOM_DIR}/zgenom.zsh"
+    if ! zgen saved
+    then
+        zgenom load hlissner/zsh-autopair
+
+        zgenom load zsh-users/zsh-autosuggestions
+
+        zgenom load zsh-users/zsh-history-substring-search
+
+        zgenom load zsh-users/zsh-syntax-highlighting
+
+        zgenom load zsh-users/zsh-completions
+
+        zgenom load jeffreytse/zsh-vi-mode
+
+        zgenom save
+    fi
+
+    # zsh-users/zsh-autosuggestions
+    bindkey '^ ' autosuggest-accept
+fi
diff --git a/zsh/.zsh.d/90_external.zsh b/zsh/.zsh.d/90_external.zsh
new file mode 100644
index 0000000..bc79027
--- /dev/null
+++ b/zsh/.zsh.d/90_external.zsh
@@ -0,0 +1,6 @@
+#!/usr/bin/env zsh
+
+# https://github.com/garabik/grc {{{
+[[ -s "/usr/share/grc/grc.zsh" ]] && \
+    source /usr/share/grc/grc.zsh
+# }}}
diff --git a/zsh/.zshenv b/zsh/.zshenv
new file mode 100644
index 0000000..e4be411
--- /dev/null
+++ b/zsh/.zshenv
@@ -0,0 +1,18 @@
+#!/usr/bin/env zsh
+
+skip_global_compinit=1
+
+setopt NO_GLOBAL_RCS
+
+export ZDOTDIR="${HOME}"
+export ZCOMPDUMP="${ZDOTDIR}/.zsh.d/.zcompdump"
+export ZLOGIN="${ZDOTDIR}/.zlogin"
+export ZLOGOUT="${ZDOTDIR}/.zlogout"
+export ZPROFILE="${ZDOTDIR}/.zprofile"
+export ZSHENV="${ZDOTDIR}/.zshenv"
+export ZSHRC="${ZDOTDIR}/.zshrc"
+
+if [[ "${SHLVL}" -eq 1 && ! -o LOGIN && -s "${ZPROFILE}" ]]
+then
+    source "${ZPROFILE}"
+fi
diff --git a/zsh/.zshrc b/zsh/.zshrc
new file mode 100644
index 0000000..a66d52e
--- /dev/null
+++ b/zsh/.zshrc
@@ -0,0 +1,12 @@
+#!/usr/bin/env zsh
+
+if [[ $TERM == "dumb" ]]; then
+    unsetopt zle
+    return
+fi
+
+for i in "${HOME}"/.zsh.d/*.zsh
+do
+    [[ -r "$i" ]] && . "$i"
+done
+unset i
diff --git a/zsh/@install b/zsh/@install
new file mode 100755
index 0000000..daf7ad6
--- /dev/null
+++ b/zsh/@install
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+[ ! -d "${HOME}/.zsh.d" ] &&
+    mkdir -p "${HOME}/.zsh.d"
+
+stow \
+    --target="${HOME}" \
+    --ignore="^@.*" \
+    --verbose \
+    zsh

Consider giving Nix/NixOS a try! <3