about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorkurb42 <kurb42@riseup.net>2021-11-02 17:34:59 -0300
committerkurb42 <kurb42@riseup.net>2021-11-02 17:34:59 -0300
commit03beceb4f1208bc59af4c1433ae01acfc3d1fe1b (patch)
treeee029ecc291cddc86296b3cdb6e9d71507a0ae2f
downloaddots-03beceb4f1208bc59af4c1433ae01acfc3d1fe1b.tar.gz
first upload
-rw-r--r--README.md27
-rw-r--r--etc/doas.conf1
-rw-r--r--etc/portage/make.conf51
-rw-r--r--etc/portage/package.license1
-rw-r--r--home/kurb42/.Xdefaults36
-rw-r--r--home/kurb42/.config/i3/config198
-rw-r--r--home/kurb42/.config/i3status/config36
-rw-r--r--home/kurb42/.config/qutebrowser/bookmarks/urls11
-rw-r--r--home/kurb42/.config/qutebrowser/config.py130
-rw-r--r--home/kurb42/.config/suckless/dmenu/LICENSE30
-rw-r--r--home/kurb42/.config/suckless/dmenu/Makefile64
-rw-r--r--home/kurb42/.config/suckless/dmenu/README24
-rw-r--r--home/kurb42/.config/suckless/dmenu/arg.h49
-rw-r--r--home/kurb42/.config/suckless/dmenu/config.def.h23
-rw-r--r--home/kurb42/.config/suckless/dmenu/config.mk31
-rw-r--r--home/kurb42/.config/suckless/dmenu/dmenu.1194
-rw-r--r--home/kurb42/.config/suckless/dmenu/dmenu.c771
-rw-r--r--home/kurb42/.config/suckless/dmenu/dmenu_path13
-rw-r--r--home/kurb42/.config/suckless/dmenu/dmenu_run2
-rw-r--r--home/kurb42/.config/suckless/dmenu/drw.c436
-rw-r--r--home/kurb42/.config/suckless/dmenu/drw.h57
-rw-r--r--home/kurb42/.config/suckless/dmenu/stest.190
-rw-r--r--home/kurb42/.config/suckless/dmenu/stest.c109
-rw-r--r--home/kurb42/.config/suckless/dmenu/util.c35
-rw-r--r--home/kurb42/.config/suckless/dmenu/util.h8
-rw-r--r--home/kurb42/.config/suckless/dwm/LICENSE37
-rw-r--r--home/kurb42/.config/suckless/dwm/Makefile51
-rw-r--r--home/kurb42/.config/suckless/dwm/README48
-rw-r--r--home/kurb42/.config/suckless/dwm/config.def.h111
-rw-r--r--home/kurb42/.config/suckless/dwm/config.mk38
-rw-r--r--home/kurb42/.config/suckless/dwm/drw.c435
-rw-r--r--home/kurb42/.config/suckless/dwm/drw.h57
-rw-r--r--home/kurb42/.config/suckless/dwm/dwm.1176
-rw-r--r--home/kurb42/.config/suckless/dwm/dwm.c2139
-rw-r--r--home/kurb42/.config/suckless/dwm/dwm.pngbin0 -> 373 bytes
-rw-r--r--home/kurb42/.config/suckless/dwm/transient.c42
-rw-r--r--home/kurb42/.config/suckless/dwm/util.c35
-rw-r--r--home/kurb42/.config/suckless/dwm/util.h8
-rw-r--r--home/kurb42/.emacs.d/init.el16
-rw-r--r--home/kurb42/.emacs.d/themes/nord-theme.el722
-rw-r--r--home/kurb42/.gitconfig3
-rw-r--r--home/kurb42/.mutt/account.net.riseup.kurb4214
-rw-r--r--home/kurb42/.mutt/muttrc11
-rw-r--r--home/kurb42/.vim/autoload/plug.vim2801
-rw-r--r--home/kurb42/.vimrc48
-rw-r--r--home/kurb42/.xinitrc3
-rw-r--r--usr/share/fonts/UbuntuMono/UbuntuMono Bold Italic Nerd Font Complete.ttfbin0 -> 975060 bytes
-rw-r--r--usr/share/fonts/UbuntuMono/UbuntuMono Bold Nerd Font Complete.ttfbin0 -> 950184 bytes
-rw-r--r--usr/share/fonts/UbuntuMono/UbuntuMono Italic Nerd Font Complete.ttfbin0 -> 971096 bytes
-rw-r--r--usr/share/fonts/UbuntuMono/UbuntuMono Nerd Font Complete.ttfbin0 -> 964540 bytes
50 files changed, 9222 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5171032
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+# kurb42's dotfiles
+
+## Current setup
+| Type | Program |
+| :--- | :--- |
+| OS | [Gentoo Linux](https://www.gentoo.org) |
+| Shell | [Bash](https://www.gnu.org/software/bash) |
+| Terminal Emulator | [URxvt](http://software.schmorp.de/pkg/rxvt-unicode.html) |
+| Window Manager | [dwm](https://dwm.suckless.org) |
+| Editor | [Emacs](https://www.gnu.org/software/emacs) |
+| Program Launcher | [dmenu](https://tools.suckless.org/dmenu) |
+| Web Browser | [Firefox](https://www.mozilla.org/firefox) |
+| Video Player | [ffplay](https://ffmpeg.org/ffplay.html) |
+| Image Viewer | [feh](https://github.com/derf/feh) |
+| E-mail Client | [Mutt](http://www.mutt.org) |
+| XMPP Client | [Profanity](https://profanity-im.github.io) |
+
+## Firefox setup
+### Extensions
+[uMatrix](https://addons.mozilla.org/firefox/addon/umatrix)
+
+### Theme
+[Gray](https://addons.mozilla.org/firefox/addon/gray132)
+
+### Hardening Process
+[Guide Online Spyware Watchdog](https://spyware.neocities.org/guides/firefox.html)
+[Extensions DigDeeper](https://digdeeper.neocities.org/ghost/addons.html)
\ No newline at end of file
diff --git a/etc/doas.conf b/etc/doas.conf
new file mode 100644
index 0000000..46a9c0d
--- /dev/null
+++ b/etc/doas.conf
@@ -0,0 +1 @@
+permit persist kurb42
diff --git a/etc/portage/make.conf b/etc/portage/make.conf
new file mode 100644
index 0000000..2c5caf2
--- /dev/null
+++ b/etc/portage/make.conf
@@ -0,0 +1,51 @@
+# These settings were set by the catalyst build script that automatically
+# built this stage.
+# Please consult /usr/share/portage/config/make.conf.example for a more
+# detailed example.
+COMMON_FLAGS="-march=native -O2 -pipe"
+CFLAGS="${COMMON_FLAGS}"
+CXXFLAGS="${COMMON_FLAGS}"
+FCFLAGS="${COMMON_FLAGS}"
+FFLAGS="${COMMON_FLAGS}"
+MAKEOPTS="-j4 -l4"
+CHOST="x86_64-pc-linux-gnu"
+CPU_FLAGS_X86="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sse sse2 sse3 sse4_1 sse4_2 ssse3"
+INPUT_DEVICES="libinput"
+VIDEO_CARDS="intel i965"
+L10N="en-US"
+ACCEPT_LICENSE="-* @FREE"
+
+# Disable useless things
+USE="-kde -gnome -systemd"
+
+# Use Xorg
+USE="$USE X elogind -wayland"
+
+# Use PulseAudio
+USE="$USE alsa pulseaudio"
+
+# Use OpenSSL
+USE="$USE openssl -libressl"
+
+# Use Firefox
+USE="$USE dbus postproc apng"
+
+# Use Emacs
+USE="$USE gui gtk libxml2 ssl png xwidgets"
+
+# Use Misc
+USE="$USE icu harfbuzz xft unicode3"
+
+# NOTE: This stage was built with the bindist Use flag enabled
+PORTDIR="/var/db/repos/gentoo"
+DISTDIR="/var/cache/distfiles"
+PKGDIR="/var/cache/binpkgs"
+
+EMERGE_DEFAULT_OPTS="--ask --jobs 4"
+
+# This sets the language of build output to English.
+# Please keep this setting intact when reporting bugs.
+LC_MESSAGES=C
+
+GENTOO_MIRRORS="https://gentoo.c3sl.ufpr.br/"
+GRUB_PLATFORMS="efi-64"
diff --git a/etc/portage/package.license b/etc/portage/package.license
new file mode 100644
index 0000000..2a9024f
--- /dev/null
+++ b/etc/portage/package.license
@@ -0,0 +1 @@
+sys-kernel/linux-firmware @BINARY-REDISTRIBUTABLE
diff --git a/home/kurb42/.Xdefaults b/home/kurb42/.Xdefaults
new file mode 100644
index 0000000..bc0d927
--- /dev/null
+++ b/home/kurb42/.Xdefaults
@@ -0,0 +1,36 @@
+! -- Colors -- !
+URxvt.foreground:   #d8dee9
+URxvt.background:   #2e3440
+URxvt.cursorColor:  #d8dee9
+URxvt.fading: 35
+URxvt.fadeColor: #4c566a
+
+URxvt.color0: #3b4252
+URxvt.color1: #bf616a
+URxvt.color2: #a3be8c
+URxvt.color3: #ebcb8b
+URxvt.color4: #81a1c1
+URxvt.color5: #b48ead
+URxvt.color6: #88c0d0
+URxvt.color7: #e5e9f0
+URxvt.color8: #4c566a
+URxvt.color9: #bf616a
+URxvt.color10: #a3be8c
+URxvt.color11: #ebcb8b
+URxvt.color12: #81a1c1
+URxvt.color13: #b48ead
+URxvt.color14: #8fbcbb
+URxvt.color15: #eceff4
+
+! -- General -- !
+URxvt.scrollBar: false
+URxvt.cursorBlink: true
+
+! -- Fonts -- !
+URxvt.font: xft:UbuntuMono Nerd Font:pixelsize=14:antialias=true
+
+! -- Restore Ctrl+Shift+(C|V) -- !
+URxvt.keysym.Shift-Control-V: eval:paste_clipboard
+URxvt.keysym.Shift-Control-C: eval:selection_to_clipboard
+URxvt.iso14755: false
+URxvt.iso14755_52: false
diff --git a/home/kurb42/.config/i3/config b/home/kurb42/.config/i3/config
new file mode 100644
index 0000000..965a7ae
--- /dev/null
+++ b/home/kurb42/.config/i3/config
@@ -0,0 +1,198 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see https://i3wm.org/docs/userguide.html for a complete reference!
+
+set $mod Mod4
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+font pango: UbuntuMono Nerd Font 10
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# Use pactl to adjust volume in PulseAudio.
+set $refresh_i3status killall -SIGUSR1 i3status
+bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
+bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
+bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
+bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# start a terminal
+bindsym $mod+Return exec urxvt
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+# start dmenu (a program launcher)
+bindsym $mod+d exec dmenu_run
+# There also is the (new) i3-dmenu-desktop which only displays applications
+# shipping a .desktop file. It is a wrapper around dmenu, so you need that
+# installed.
+# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
+
+# change focus
+bindsym $mod+j focus left
+bindsym $mod+k focus down
+bindsym $mod+l focus up
+bindsym $mod+ccedilla focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+j move left
+bindsym $mod+Shift+k move down
+bindsym $mod+Shift+l move up
+bindsym $mod+Shift+ccedilla move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+h split h
+
+# split in vertical orientation
+bindsym $mod+v split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+
+# Define names for default workspaces for which we configure key bindings later on.
+# We use variables to avoid repeating the names in multiple places.
+set $ws1 "1"
+set $ws2 "2"
+set $ws3 "3"
+set $ws4 "4"
+set $ws5 "5"
+set $ws6 "6"
+set $ws7 "7"
+set $ws8 "8"
+set $ws9 "9"
+set $ws10 "10"
+
+# switch to workspace
+bindsym $mod+1 workspace number $ws1
+bindsym $mod+2 workspace number $ws2
+bindsym $mod+3 workspace number $ws3
+bindsym $mod+4 workspace number $ws4
+bindsym $mod+5 workspace number $ws5
+bindsym $mod+6 workspace number $ws6
+bindsym $mod+7 workspace number $ws7
+bindsym $mod+8 workspace number $ws8
+bindsym $mod+9 workspace number $ws9
+bindsym $mod+0 workspace number $ws10
+
+# move focused container to workspace
+bindsym $mod+Shift+1 move container to workspace number $ws1
+bindsym $mod+Shift+2 move container to workspace number $ws2
+bindsym $mod+Shift+3 move container to workspace number $ws3
+bindsym $mod+Shift+4 move container to workspace number $ws4
+bindsym $mod+Shift+5 move container to workspace number $ws5
+bindsym $mod+Shift+6 move container to workspace number $ws6
+bindsym $mod+Shift+7 move container to workspace number $ws7
+bindsym $mod+Shift+8 move container to workspace number $ws8
+bindsym $mod+Shift+9 move container to workspace number $ws9
+bindsym $mod+Shift+0 move container to workspace number $ws10
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+        # These bindings trigger as soon as you enter the resize mode
+
+        # Pressing left will shrink the window’s width.
+        # Pressing right will grow the window’s width.
+        # Pressing up will shrink the window’s height.
+        # Pressing down will grow the window’s height.
+        bindsym j resize shrink width 10 px or 10 ppt
+        bindsym k resize grow height 10 px or 10 ppt
+        bindsym l resize shrink height 10 px or 10 ppt
+        bindsym ccedilla resize grow width 10 px or 10 ppt
+
+        # same bindings, but for the arrow keys
+        bindsym Left resize shrink width 10 px or 10 ppt
+        bindsym Down resize grow height 10 px or 10 ppt
+        bindsym Up resize shrink height 10 px or 10 ppt
+        bindsym Right resize grow width 10 px or 10 ppt
+
+        # back to normal: Enter or Escape or $mod+r
+        bindsym Return mode "default"
+        bindsym Escape mode "default"
+        bindsym $mod+r mode "default"
+}
+
+bindsym $mod+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+bar {
+	font pango: UbuntuMono Nerd Font 10
+        status_command i3status
+
+    colors {
+            separator  #1f222d
+            background #1f222d
+            statusline #81a1c1
+              
+            #                   border  background text
+            focused_workspace  #1f222d #1f222d    #81a1c1 
+            active_workspace   #1f222d #252936    #5e81ac
+            inactive_workspace #1f222d #1f222d    #4c566a
+            urgent_workspace   #1f222d #1f222d    #ee829f
+            binding_mode       #1f222d #81a1c1    #2e3440
+    }
+}
+
+
+# Window color settings
+# class                 border  backgr. text    indicator
+client.focused          #81a1c1 #81a1c1 #ffffff #81a1c1
+client.unfocused        #2e3440 #2e3440 #888888 #2e3440
+client.focused_inactive #2e3440 #2e3440 #888888 #2e3440
+client.placeholder      #2e3440 #2e3440 #888888 #2e3440
+client.urgent           #900000 #900000 #ffffff #900000
+
+client.background       #242424
+
+# Start programs
+exec xsetroot -solid "#1f222d"
diff --git a/home/kurb42/.config/i3status/config b/home/kurb42/.config/i3status/config
new file mode 100644
index 0000000..206e279
--- /dev/null
+++ b/home/kurb42/.config/i3status/config
@@ -0,0 +1,36 @@
+# i3status configuration file.
+# see "man i3status" for documentation.
+
+# It is important that this file is edited as UTF-8.
+# The following line should contain a sharp s:
+# ß
+# If the above line is not correctly displayed, fix your editor first!
+
+general {
+        colors = true
+	color_good = "#81a1c1"
+        color_degraded = "#fafe7c"
+        color_bad = "#ff7770"
+}
+
+# order += "wireless _first_"
+# order += "battery all"
+order += "tztime local"
+
+# wireless _first_ {
+#        format_up = "connected |"
+#        format_down = "down |"
+# }
+
+# battery all {
+#        format = "%status %percentage %remaining |"
+#	 hide_seconds = true
+#
+#        status_chr = "chr"
+#        status_bat = "chr"
+#        status_full = "full"
+# }
+
+tztime local {
+        format = "%Y-%m-%d | %H:%M:%S"
+}
diff --git a/home/kurb42/.config/qutebrowser/bookmarks/urls b/home/kurb42/.config/qutebrowser/bookmarks/urls
new file mode 100644
index 0000000..5fd1c0b
--- /dev/null
+++ b/home/kurb42/.config/qutebrowser/bookmarks/urls
@@ -0,0 +1,11 @@
+https://doc.dustri.org about:papers
+https://digdeeper.neocities.org dig deeper
+https://spyware.neocities.org spyware watchdog
+https://kill-9.xyz kill -9
+http://cat-v.org cat-v
+https://stallman.org richard stallman
+https://mizik.sk marián mižik
+https://mha.fi mico hautaluoma
+https://tilde.team/~novaburst ~novaburst
+https://locky.neocities.org [locky]
+https://madaidans-insecurities.github.io madaidan
diff --git a/home/kurb42/.config/qutebrowser/config.py b/home/kurb42/.config/qutebrowser/config.py
new file mode 100644
index 0000000..70090b8
--- /dev/null
+++ b/home/kurb42/.config/qutebrowser/config.py
@@ -0,0 +1,130 @@
+# general
+c.content.default_encoding = "utf-8"
+config.load_autoconfig()
+c.tabs.last_close = "close"
+c.tabs.mousewheel_switching = False
+
+# disable js
+config.set('content.javascript.enabled', True, '*://fosstodon.org/*')
+config.set('content.javascript.enabled', True, '*://b-ok.lat/*')
+config.set('content.javascript.enabled', True, '*://videos.lukesmith.xyz/*')
+c.content.javascript.enabled = False
+
+# search engine and homepage
+
+## search engine
+c.url.searchengines = {
+                       'DEFAULT': 'https://wiby.me/?q={}',
+                       'mj'	    : 'https://mojeek.com/search?q={}',
+                       'bk'     : 'https://b-ok.lat/s/{}',
+                       'aw'     : 'https://wiki.alpinelinux.org/w/index.php?search={}',
+                       }
+
+## homepage
+c.url.start_pages = 'https://wiby.me'
+c.url.default_page = 'https://wiby.me'
+
+# appearance
+
+## ui
+c.tabs.title.format = "{perc}{current_title}"
+c.tabs.position = "bottom"
+c.downloads.position = "bottom"
+c.statusbar.widgets = ["progress", "keypress", "url", "history"]
+
+## colors
+colors = {
+    'base0': '#2e3440',
+    'base1': '#3b4252',
+    'base2': '#434c5e',
+    'base3': '#4c566a',
+    'base4': '#d8dee9',
+    'base5': '#e5e9f0',
+    'base6': '#eceff4',
+    'base7': '#8fbcbb',
+    'base8': '#88c0d0',
+    'base9': '#81a1c1',
+    'base10': '#5e81ac',
+    'base11': '#bf616a',
+    'base12': '#d08770',
+    'base13': '#ebcb8b',
+    'base14': '#a3be8c',
+    'base15': '#b48ead',
+}
+
+c.colors.completion.category.bg = colors['base0']
+c.colors.completion.category.border.bottom = colors['base0']
+c.colors.completion.category.border.top = colors['base0']
+c.colors.completion.category.fg = colors['base5']
+c.colors.completion.even.bg = colors['base1']
+c.colors.completion.odd.bg = colors['base1']
+c.colors.completion.fg = colors['base4']
+c.colors.completion.item.selected.bg = colors['base3']
+c.colors.completion.item.selected.border.bottom = colors['base3']
+c.colors.completion.item.selected.border.top = colors['base3']
+c.colors.completion.item.selected.fg = colors['base6']
+c.colors.completion.match.fg = colors['base13']
+c.colors.completion.scrollbar.bg = colors['base1']
+c.colors.completion.scrollbar.fg = colors['base5']
+c.colors.downloads.bar.bg = colors['base0']
+c.colors.downloads.error.bg = colors['base11']
+c.colors.downloads.error.fg = colors['base5']
+c.colors.downloads.stop.bg = colors['base15']
+c.colors.downloads.system.bg = 'none'
+c.colors.hints.bg = colors['base13']
+c.colors.hints.fg = colors['base0']
+c.colors.hints.match.fg = colors['base10']
+c.colors.keyhint.bg = colors['base1']
+c.colors.keyhint.fg = colors['base5']
+c.colors.keyhint.suffix.fg = colors['base13']
+c.colors.messages.error.bg = colors['base11']
+c.colors.messages.error.border = colors['base11']
+c.colors.messages.error.fg = colors['base5']
+c.colors.messages.info.bg = colors['base8']
+c.colors.messages.info.border = colors['base8']
+c.colors.messages.info.fg = colors['base5']
+c.colors.messages.warning.bg = colors['base12']
+c.colors.messages.warning.border = colors['base12']
+c.colors.messages.warning.fg = colors['base5']
+c.colors.prompts.bg = colors['base2']
+c.colors.prompts.border = '1px solid ' + colors['base0']
+c.colors.prompts.fg = colors['base5']
+c.colors.prompts.selected.bg = colors['base3']
+c.colors.statusbar.caret.bg = colors['base15']
+c.colors.statusbar.caret.fg = colors['base5']
+c.colors.statusbar.caret.selection.bg = colors['base15']
+c.colors.statusbar.caret.selection.fg = colors['base5']
+c.colors.statusbar.command.bg = colors['base2']
+c.colors.statusbar.command.fg = colors['base5']
+c.colors.statusbar.command.private.bg = colors['base2']
+c.colors.statusbar.command.private.fg = colors['base5']
+c.colors.statusbar.insert.bg = colors['base14']
+c.colors.statusbar.insert.fg = colors['base1']
+c.colors.statusbar.normal.bg = colors['base0']
+c.colors.statusbar.normal.fg = colors['base5']
+c.colors.statusbar.passthrough.bg = colors['base10']
+c.colors.statusbar.passthrough.fg = colors['base5']
+c.colors.statusbar.private.bg = colors['base3']
+c.colors.statusbar.private.fg = colors['base5']
+c.colors.statusbar.progress.bg = colors['base5']
+c.colors.statusbar.url.error.fg = colors['base11']
+c.colors.statusbar.url.fg = colors['base5']
+c.colors.statusbar.url.hover.fg = colors['base8']
+c.colors.statusbar.url.success.http.fg = colors['base5']
+c.colors.statusbar.url.success.https.fg = colors['base14']
+c.colors.statusbar.url.warn.fg = colors['base12']
+c.colors.tabs.bar.bg = colors['base3']
+c.colors.tabs.even.bg = colors['base3']
+c.colors.tabs.even.fg = colors['base5']
+c.colors.tabs.indicator.error = colors['base11']
+c.colors.tabs.indicator.system = 'none'
+c.colors.tabs.odd.bg = colors['base3']
+c.colors.tabs.odd.fg = colors['base5']
+c.colors.tabs.selected.even.bg = colors['base0']
+c.colors.tabs.selected.even.fg = colors['base5']
+c.colors.tabs.selected.odd.bg = colors['base0']
+c.colors.tabs.selected.odd.fg = colors['base5']
+
+## fonts
+c.fonts.default_family = 'UbuntuMono Nerd Font'
+c.fonts.default_size = '10px'
diff --git a/home/kurb42/.config/suckless/dmenu/LICENSE b/home/kurb42/.config/suckless/dmenu/LICENSE
new file mode 100644
index 0000000..3afd28e
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/LICENSE
@@ -0,0 +1,30 @@
+MIT/X Consortium License
+
+© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
+© 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com>
+© 2006-2007 Michał Janeczek <janeczek@gmail.com>
+© 2007 Kris Maglione <jg@suckless.org>
+© 2009 Gottox <gottox@s01.de>
+© 2009 Markus Schnalke <meillo@marmaro.de>
+© 2009 Evan Gates <evan.gates@gmail.com>
+© 2010-2012 Connor Lane Smith <cls@lubutu.com>
+© 2014-2020 Hiltjo Posthuma <hiltjo@codemadness.org>
+© 2015-2019 Quentin Rameau <quinq@fifth.space>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/home/kurb42/.config/suckless/dmenu/Makefile b/home/kurb42/.config/suckless/dmenu/Makefile
new file mode 100644
index 0000000..a03a95c
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/Makefile
@@ -0,0 +1,64 @@
+# dmenu - dynamic menu
+# See LICENSE file for copyright and license details.
+
+include config.mk
+
+SRC = drw.c dmenu.c stest.c util.c
+OBJ = $(SRC:.c=.o)
+
+all: options dmenu stest
+
+options:
+	@echo dmenu build options:
+	@echo "CFLAGS   = $(CFLAGS)"
+	@echo "LDFLAGS  = $(LDFLAGS)"
+	@echo "CC       = $(CC)"
+
+.c.o:
+	$(CC) -c $(CFLAGS) $<
+
+config.h:
+	cp config.def.h $@
+
+$(OBJ): arg.h config.h config.mk drw.h
+
+dmenu: dmenu.o drw.o util.o
+	$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
+
+stest: stest.o
+	$(CC) -o $@ stest.o $(LDFLAGS)
+
+clean:
+	rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
+
+dist: clean
+	mkdir -p dmenu-$(VERSION)
+	cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
+		drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
+		dmenu-$(VERSION)
+	tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
+	gzip dmenu-$(VERSION).tar
+	rm -rf dmenu-$(VERSION)
+
+install: all
+	mkdir -p $(DESTDIR)$(PREFIX)/bin
+	cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
+	mkdir -p $(DESTDIR)$(MANPREFIX)/man1
+	sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
+	sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
+	chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
+	chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
+
+uninstall:
+	rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
+		$(DESTDIR)$(PREFIX)/bin/dmenu_path\
+		$(DESTDIR)$(PREFIX)/bin/dmenu_run\
+		$(DESTDIR)$(PREFIX)/bin/stest\
+		$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
+		$(DESTDIR)$(MANPREFIX)/man1/stest.1
+
+.PHONY: all options clean dist install uninstall
diff --git a/home/kurb42/.config/suckless/dmenu/README b/home/kurb42/.config/suckless/dmenu/README
new file mode 100644
index 0000000..a8fcdfe
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/README
@@ -0,0 +1,24 @@
+dmenu - dynamic menu
+====================
+dmenu is an efficient dynamic menu for X.
+
+
+Requirements
+------------
+In order to build dmenu you need the Xlib header files.
+
+
+Installation
+------------
+Edit config.mk to match your local setup (dmenu is installed into
+the /usr/local namespace by default).
+
+Afterwards enter the following command to build and install dmenu
+(if necessary as root):
+
+    make clean install
+
+
+Running dmenu
+-------------
+See the man page for details.
diff --git a/home/kurb42/.config/suckless/dmenu/arg.h b/home/kurb42/.config/suckless/dmenu/arg.h
new file mode 100644
index 0000000..e94e02b
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/arg.h
@@ -0,0 +1,49 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN	for (argv0 = *argv, argv++, argc--;\
+					argv[0] && argv[0][0] == '-'\
+					&& argv[0][1];\
+					argc--, argv++) {\
+				char argc_;\
+				char **argv_;\
+				int brk_;\
+				if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+					argv++;\
+					argc--;\
+					break;\
+				}\
+				for (brk_ = 0, argv[0]++, argv_ = argv;\
+						argv[0][0] && !brk_;\
+						argv[0]++) {\
+					if (argv_ != argv)\
+						break;\
+					argc_ = argv[0][0];\
+					switch (argc_)
+
+#define ARGEND			}\
+			}
+
+#define ARGC()		argc_
+
+#define EARGF(x)	((argv[0][1] == '\0' && argv[1] == NULL)?\
+				((x), abort(), (char *)0) :\
+				(brk_ = 1, (argv[0][1] != '\0')?\
+					(&argv[0][1]) :\
+					(argc--, argv++, argv[0])))
+
+#define ARGF()		((argv[0][1] == '\0' && argv[1] == NULL)?\
+				(char *)0 :\
+				(brk_ = 1, (argv[0][1] != '\0')?\
+					(&argv[0][1]) :\
+					(argc--, argv++, argv[0])))
+
+#endif
diff --git a/home/kurb42/.config/suckless/dmenu/config.def.h b/home/kurb42/.config/suckless/dmenu/config.def.h
new file mode 100644
index 0000000..285c879
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/config.def.h
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+/* Default settings; can be overriden by command line. */
+
+static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
+/* -fn option overrides fonts[0]; default X11 font or font set */
+static const char *fonts[] = {
+	"UbuntuMono Nerd Font:size=10"
+};
+static const char *prompt      = NULL;      /* -p  option; prompt to the left of input field */
+static const char *colors[SchemeLast][2] = {
+	/*     fg         bg       */
+        [SchemeNorm] = { "#c0c0c0", "#202020" },
+        [SchemeSel] = { "#f0f0f0", "#404040" },
+	[SchemeOut] = { "#000000", "#00ffff" },
+};
+/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
+static unsigned int lines      = 0;
+
+/*
+ * Characters not considered part of a word while deleting words
+ * for example: " /?\"&[]"
+ */
+static const char worddelimiters[] = " ";
diff --git a/home/kurb42/.config/suckless/dmenu/config.mk b/home/kurb42/.config/suckless/dmenu/config.mk
new file mode 100644
index 0000000..05d5a3e
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/config.mk
@@ -0,0 +1,31 @@
+# dmenu version
+VERSION = 5.0
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
+
+# Xinerama, comment if you don't want it
+XINERAMALIBS  = -lXinerama
+XINERAMAFLAGS = -DXINERAMA
+
+# freetype
+FREETYPELIBS = -lfontconfig -lXft
+FREETYPEINC = /usr/include/freetype2
+# OpenBSD (uncomment)
+#FREETYPEINC = $(X11INC)/freetype2
+
+# includes and libs
+INCS = -I$(X11INC) -I$(FREETYPEINC)
+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
+
+# flags
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
+CFLAGS   = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
+LDFLAGS  = $(LIBS)
+
+# compiler and linker
+CC = cc
diff --git a/home/kurb42/.config/suckless/dmenu/dmenu.1 b/home/kurb42/.config/suckless/dmenu/dmenu.1
new file mode 100644
index 0000000..323f93c
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/dmenu.1
@@ -0,0 +1,194 @@
+.TH DMENU 1 dmenu\-VERSION
+.SH NAME
+dmenu \- dynamic menu
+.SH SYNOPSIS
+.B dmenu
+.RB [ \-bfiv ]
+.RB [ \-l
+.IR lines ]
+.RB [ \-m
+.IR monitor ]
+.RB [ \-p
+.IR prompt ]
+.RB [ \-fn
+.IR font ]
+.RB [ \-nb
+.IR color ]
+.RB [ \-nf
+.IR color ]
+.RB [ \-sb
+.IR color ]
+.RB [ \-sf
+.IR color ]
+.RB [ \-w
+.IR windowid ]
+.P
+.BR dmenu_run " ..."
+.SH DESCRIPTION
+.B dmenu
+is a dynamic menu for X, which reads a list of newline\-separated items from
+stdin.  When the user selects an item and presses Return, their choice is printed
+to stdout and dmenu terminates.  Entering text will narrow the items to those
+matching the tokens in the input.
+.P
+.B dmenu_run
+is a script used by
+.IR dwm (1)
+which lists programs in the user's $PATH and runs the result in their $SHELL.
+.SH OPTIONS
+.TP
+.B \-b
+dmenu appears at the bottom of the screen.
+.TP
+.B \-f
+dmenu grabs the keyboard before reading stdin if not reading from a tty. This
+is faster, but will lock up X until stdin reaches end\-of\-file.
+.TP
+.B \-i
+dmenu matches menu items case insensitively.
+.TP
+.BI \-l " lines"
+dmenu lists items vertically, with the given number of lines.
+.TP
+.BI \-m " monitor"
+dmenu is displayed on the monitor number supplied. Monitor numbers are starting
+from 0.
+.TP
+.BI \-p " prompt"
+defines the prompt to be displayed to the left of the input field.
+.TP
+.BI \-fn " font"
+defines the font or font set used.
+.TP
+.BI \-nb " color"
+defines the normal background color.
+.IR #RGB ,
+.IR #RRGGBB ,
+and X color names are supported.
+.TP
+.BI \-nf " color"
+defines the normal foreground color.
+.TP
+.BI \-sb " color"
+defines the selected background color.
+.TP
+.BI \-sf " color"
+defines the selected foreground color.
+.TP
+.B \-v
+prints version information to stdout, then exits.
+.TP
+.BI \-w " windowid"
+embed into windowid.
+.SH USAGE
+dmenu is completely controlled by the keyboard.  Items are selected using the
+arrow keys, page up, page down, home, and end.
+.TP
+.B Tab
+Copy the selected item to the input field.
+.TP
+.B Return
+Confirm selection.  Prints the selected item to stdout and exits, returning
+success.
+.TP
+.B Ctrl-Return
+Confirm selection.  Prints the selected item to stdout and continues.
+.TP
+.B Shift\-Return
+Confirm input.  Prints the input text to stdout and exits, returning success.
+.TP
+.B Escape
+Exit without selecting an item, returning failure.
+.TP
+.B Ctrl-Left
+Move cursor to the start of the current word
+.TP
+.B Ctrl-Right
+Move cursor to the end of the current word
+.TP
+.B C\-a
+Home
+.TP
+.B C\-b
+Left
+.TP
+.B C\-c
+Escape
+.TP
+.B C\-d
+Delete
+.TP
+.B C\-e
+End
+.TP
+.B C\-f
+Right
+.TP
+.B C\-g
+Escape
+.TP
+.B C\-h
+Backspace
+.TP
+.B C\-i
+Tab
+.TP
+.B C\-j
+Return
+.TP
+.B C\-J
+Shift-Return
+.TP
+.B C\-k
+Delete line right
+.TP
+.B C\-m
+Return
+.TP
+.B C\-M
+Shift-Return
+.TP
+.B C\-n
+Down
+.TP
+.B C\-p
+Up
+.TP
+.B C\-u
+Delete line left
+.TP
+.B C\-w
+Delete word left
+.TP
+.B C\-y
+Paste from primary X selection
+.TP
+.B C\-Y
+Paste from X clipboard
+.TP
+.B M\-b
+Move cursor to the start of the current word
+.TP
+.B M\-f
+Move cursor to the end of the current word
+.TP
+.B M\-g
+Home
+.TP
+.B M\-G
+End
+.TP
+.B M\-h
+Up
+.TP
+.B M\-j
+Page down
+.TP
+.B M\-k
+Page up
+.TP
+.B M\-l
+Down
+.SH SEE ALSO
+.IR dwm (1),
+.IR stest (1)
diff --git a/home/kurb42/.config/suckless/dmenu/dmenu.c b/home/kurb42/.config/suckless/dmenu/dmenu.c
new file mode 100644
index 0000000..65f25ce
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/dmenu.c
@@ -0,0 +1,771 @@
+/* See LICENSE file for copyright and license details. */
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#ifdef XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+#include <X11/Xft/Xft.h>
+
+#include "drw.h"
+#include "util.h"
+
+/* macros */
+#define INTERSECT(x,y,w,h,r)  (MAX(0, MIN((x)+(w),(r).x_org+(r).width)  - MAX((x),(r).x_org)) \
+                             * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
+#define LENGTH(X)             (sizeof X / sizeof X[0])
+#define TEXTW(X)              (drw_fontset_getwidth(drw, (X)) + lrpad)
+
+/* enums */
+enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
+
+struct item {
+	char *text;
+	struct item *left, *right;
+	int out;
+};
+
+static char text[BUFSIZ] = "";
+static char *embed;
+static int bh, mw, mh;
+static int inputw = 0, promptw;
+static int lrpad; /* sum of left and right padding */
+static size_t cursor;
+static struct item *items = NULL;
+static struct item *matches, *matchend;
+static struct item *prev, *curr, *next, *sel;
+static int mon = -1, screen;
+
+static Atom clip, utf8;
+static Display *dpy;
+static Window root, parentwin, win;
+static XIC xic;
+
+static Drw *drw;
+static Clr *scheme[SchemeLast];
+
+#include "config.h"
+
+static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
+static char *(*fstrstr)(const char *, const char *) = strstr;
+
+static void
+appenditem(struct item *item, struct item **list, struct item **last)
+{
+	if (*last)
+		(*last)->right = item;
+	else
+		*list = item;
+
+	item->left = *last;
+	item->right = NULL;
+	*last = item;
+}
+
+static void
+calcoffsets(void)
+{
+	int i, n;
+
+	if (lines > 0)
+		n = lines * bh;
+	else
+		n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
+	/* calculate which items will begin the next page and previous page */
+	for (i = 0, next = curr; next; next = next->right)
+		if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
+			break;
+	for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
+		if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
+			break;
+}
+
+static void
+cleanup(void)
+{
+	size_t i;
+
+	XUngrabKey(dpy, AnyKey, AnyModifier, root);
+	for (i = 0; i < SchemeLast; i++)
+		free(scheme[i]);
+	drw_free(drw);
+	XSync(dpy, False);
+	XCloseDisplay(dpy);
+}
+
+static char *
+cistrstr(const char *s, const char *sub)
+{
+	size_t len;
+
+	for (len = strlen(sub); *s; s++)
+		if (!strncasecmp(s, sub, len))
+			return (char *)s;
+	return NULL;
+}
+
+static int
+drawitem(struct item *item, int x, int y, int w)
+{
+	if (item == sel)
+		drw_setscheme(drw, scheme[SchemeSel]);
+	else if (item->out)
+		drw_setscheme(drw, scheme[SchemeOut]);
+	else
+		drw_setscheme(drw, scheme[SchemeNorm]);
+
+	return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
+}
+
+static void
+drawmenu(void)
+{
+	unsigned int curpos;
+	struct item *item;
+	int x = 0, y = 0, w;
+
+	drw_setscheme(drw, scheme[SchemeNorm]);
+	drw_rect(drw, 0, 0, mw, mh, 1, 1);
+
+	if (prompt && *prompt) {
+		drw_setscheme(drw, scheme[SchemeSel]);
+		x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0);
+	}
+	/* draw input field */
+	w = (lines > 0 || !matches) ? mw - x : inputw;
+	drw_setscheme(drw, scheme[SchemeNorm]);
+	drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
+
+	curpos = TEXTW(text) - TEXTW(&text[cursor]);
+	if ((curpos += lrpad / 2 - 1) < w) {
+		drw_setscheme(drw, scheme[SchemeNorm]);
+		drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
+	}
+
+	if (lines > 0) {
+		/* draw vertical list */
+		for (item = curr; item != next; item = item->right)
+			drawitem(item, x, y += bh, mw - x);
+	} else if (matches) {
+		/* draw horizontal list */
+		x += inputw;
+		w = TEXTW("<");
+		if (curr->left) {
+			drw_setscheme(drw, scheme[SchemeNorm]);
+			drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0);
+		}
+		x += w;
+		for (item = curr; item != next; item = item->right)
+			x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">")));
+		if (next) {
+			w = TEXTW(">");
+			drw_setscheme(drw, scheme[SchemeNorm]);
+			drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
+		}
+	}
+	drw_map(drw, win, 0, 0, mw, mh);
+}
+
+static void
+grabfocus(void)
+{
+	struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000  };
+	Window focuswin;
+	int i, revertwin;
+
+	for (i = 0; i < 100; ++i) {
+		XGetInputFocus(dpy, &focuswin, &revertwin);
+		if (focuswin == win)
+			return;
+		XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
+		nanosleep(&ts, NULL);
+	}
+	die("cannot grab focus");
+}
+
+static void
+grabkeyboard(void)
+{
+	struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000  };
+	int i;
+
+	if (embed)
+		return;
+	/* try to grab keyboard, we may have to wait for another process to ungrab */
+	for (i = 0; i < 1000; i++) {
+		if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
+		                  GrabModeAsync, CurrentTime) == GrabSuccess)
+			return;
+		nanosleep(&ts, NULL);
+	}
+	die("cannot grab keyboard");
+}
+
+static void
+match(void)
+{
+	static char **tokv = NULL;
+	static int tokn = 0;
+
+	char buf[sizeof text], *s;
+	int i, tokc = 0;
+	size_t len, textsize;
+	struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
+
+	strcpy(buf, text);
+	/* separate input text into tokens to be matched individually */
+	for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
+		if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
+			die("cannot realloc %u bytes:", tokn * sizeof *tokv);
+	len = tokc ? strlen(tokv[0]) : 0;
+
+	matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
+	textsize = strlen(text) + 1;
+	for (item = items; item && item->text; item++) {
+		for (i = 0; i < tokc; i++)
+			if (!fstrstr(item->text, tokv[i]))
+				break;
+		if (i != tokc) /* not all tokens match */
+			continue;
+		/* exact matches go first, then prefixes, then substrings */
+		if (!tokc || !fstrncmp(text, item->text, textsize))
+			appenditem(item, &matches, &matchend);
+		else if (!fstrncmp(tokv[0], item->text, len))
+			appenditem(item, &lprefix, &prefixend);
+		else
+			appenditem(item, &lsubstr, &substrend);
+	}
+	if (lprefix) {
+		if (matches) {
+			matchend->right = lprefix;
+			lprefix->left = matchend;
+		} else
+			matches = lprefix;
+		matchend = prefixend;
+	}
+	if (lsubstr) {
+		if (matches) {
+			matchend->right = lsubstr;
+			lsubstr->left = matchend;
+		} else
+			matches = lsubstr;
+		matchend = substrend;
+	}
+	curr = sel = matches;
+	calcoffsets();
+}
+
+static void
+insert(const char *str, ssize_t n)
+{
+	if (strlen(text) + n > sizeof text - 1)
+		return;
+	/* move existing text out of the way, insert new text, and update cursor */
+	memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
+	if (n > 0)
+		memcpy(&text[cursor], str, n);
+	cursor += n;
+	match();
+}
+
+static size_t
+nextrune(int inc)
+{
+	ssize_t n;
+
+	/* return location of next utf8 rune in the given direction (+1 or -1) */
+	for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc)
+		;
+	return n;
+}
+
+static void
+movewordedge(int dir)
+{
+	if (dir < 0) { /* move cursor to the start of the word*/
+		while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
+			cursor = nextrune(-1);
+		while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
+			cursor = nextrune(-1);
+	} else { /* move cursor to the end of the word */
+		while (text[cursor] && strchr(worddelimiters, text[cursor]))
+			cursor = nextrune(+1);
+		while (text[cursor] && !strchr(worddelimiters, text[cursor]))
+			cursor = nextrune(+1);
+	}
+}
+
+static void
+keypress(XKeyEvent *ev)
+{
+	char buf[32];
+	int len;
+	KeySym ksym;
+	Status status;
+
+	len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
+	switch (status) {
+	default: /* XLookupNone, XBufferOverflow */
+		return;
+	case XLookupChars:
+		goto insert;
+	case XLookupKeySym:
+	case XLookupBoth:
+		break;
+	}
+
+	if (ev->state & ControlMask) {
+		switch(ksym) {
+		case XK_a: ksym = XK_Home;      break;
+		case XK_b: ksym = XK_Left;      break;
+		case XK_c: ksym = XK_Escape;    break;
+		case XK_d: ksym = XK_Delete;    break;
+		case XK_e: ksym = XK_End;       break;
+		case XK_f: ksym = XK_Right;     break;
+		case XK_g: ksym = XK_Escape;    break;
+		case XK_h: ksym = XK_BackSpace; break;
+		case XK_i: ksym = XK_Tab;       break;
+		case XK_j: /* fallthrough */
+		case XK_J: /* fallthrough */
+		case XK_m: /* fallthrough */
+		case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
+		case XK_n: ksym = XK_Down;      break;
+		case XK_p: ksym = XK_Up;        break;
+
+		case XK_k: /* delete right */
+			text[cursor] = '\0';
+			match();
+			break;
+		case XK_u: /* delete left */
+			insert(NULL, 0 - cursor);
+			break;
+		case XK_w: /* delete word */
+			while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
+				insert(NULL, nextrune(-1) - cursor);
+			while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
+				insert(NULL, nextrune(-1) - cursor);
+			break;
+		case XK_y: /* paste selection */
+		case XK_Y:
+			XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
+			                  utf8, utf8, win, CurrentTime);
+			return;
+		case XK_Left:
+			movewordedge(-1);
+			goto draw;
+		case XK_Right:
+			movewordedge(+1);
+			goto draw;
+		case XK_Return:
+		case XK_KP_Enter:
+			break;
+		case XK_bracketleft:
+			cleanup();
+			exit(1);
+		default:
+			return;
+		}
+	} else if (ev->state & Mod1Mask) {
+		switch(ksym) {
+		case XK_b:
+			movewordedge(-1);
+			goto draw;
+		case XK_f:
+			movewordedge(+1);
+			goto draw;
+		case XK_g: ksym = XK_Home;  break;
+		case XK_G: ksym = XK_End;   break;
+		case XK_h: ksym = XK_Up;    break;
+		case XK_j: ksym = XK_Next;  break;
+		case XK_k: ksym = XK_Prior; break;
+		case XK_l: ksym = XK_Down;  break;
+		default:
+			return;
+		}
+	}
+
+	switch(ksym) {
+	default:
+insert:
+		if (!iscntrl(*buf))
+			insert(buf, len);
+		break;
+	case XK_Delete:
+		if (text[cursor] == '\0')
+			return;
+		cursor = nextrune(+1);
+		/* fallthrough */
+	case XK_BackSpace:
+		if (cursor == 0)
+			return;
+		insert(NULL, nextrune(-1) - cursor);
+		break;
+	case XK_End:
+		if (text[cursor] != '\0') {
+			cursor = strlen(text);
+			break;
+		}
+		if (next) {
+			/* jump to end of list and position items in reverse */
+			curr = matchend;
+			calcoffsets();
+			curr = prev;
+			calcoffsets();
+			while (next && (curr = curr->right))
+				calcoffsets();
+		}
+		sel = matchend;
+		break;
+	case XK_Escape:
+		cleanup();
+		exit(1);
+	case XK_Home:
+		if (sel == matches) {
+			cursor = 0;
+			break;
+		}
+		sel = curr = matches;
+		calcoffsets();
+		break;
+	case XK_Left:
+		if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
+			cursor = nextrune(-1);
+			break;
+		}
+		if (lines > 0)
+			return;
+		/* fallthrough */
+	case XK_Up:
+		if (sel && sel->left && (sel = sel->left)->right == curr) {
+			curr = prev;
+			calcoffsets();
+		}
+		break;
+	case XK_Next:
+		if (!next)
+			return;
+		sel = curr = next;
+		calcoffsets();
+		break;
+	case XK_Prior:
+		if (!prev)
+			return;
+		sel = curr = prev;
+		calcoffsets();
+		break;
+	case XK_Return:
+	case XK_KP_Enter:
+		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
+		if (!(ev->state & ControlMask)) {
+			cleanup();
+			exit(0);
+		}
+		if (sel)
+			sel->out = 1;
+		break;
+	case XK_Right:
+		if (text[cursor] != '\0') {
+			cursor = nextrune(+1);
+			break;
+		}
+		if (lines > 0)
+			return;
+		/* fallthrough */
+	case XK_Down:
+		if (sel && sel->right && (sel = sel->right) == next) {
+			curr = next;
+			calcoffsets();
+		}
+		break;
+	case XK_Tab:
+		if (!sel)
+			return;
+		strncpy(text, sel->text, sizeof text - 1);
+		text[sizeof text - 1] = '\0';
+		cursor = strlen(text);
+		match();
+		break;
+	}
+
+draw:
+	drawmenu();
+}
+
+static void
+paste(void)
+{
+	char *p, *q;
+	int di;
+	unsigned long dl;
+	Atom da;
+
+	/* we have been given the current selection, now insert it into input */
+	if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
+	                   utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
+	    == Success && p) {
+		insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
+		XFree(p);
+	}
+	drawmenu();
+}
+
+static void
+readstdin(void)
+{
+	char buf[sizeof text], *p;
+	size_t i, imax = 0, size = 0;
+	unsigned int tmpmax = 0;
+
+	/* read each line from stdin and add it to the item list */
+	for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
+		if (i + 1 >= size / sizeof *items)
+			if (!(items = realloc(items, (size += BUFSIZ))))
+				die("cannot realloc %u bytes:", size);
+		if ((p = strchr(buf, '\n')))
+			*p = '\0';
+		if (!(items[i].text = strdup(buf)))
+			die("cannot strdup %u bytes:", strlen(buf) + 1);
+		items[i].out = 0;
+		drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
+		if (tmpmax > inputw) {
+			inputw = tmpmax;
+			imax = i;
+		}
+	}
+	if (items)
+		items[i].text = NULL;
+	inputw = items ? TEXTW(items[imax].text) : 0;
+	lines = MIN(lines, i);
+}
+
+static void
+run(void)
+{
+	XEvent ev;
+
+	while (!XNextEvent(dpy, &ev)) {
+		if (XFilterEvent(&ev, win))
+			continue;
+		switch(ev.type) {
+		case DestroyNotify:
+			if (ev.xdestroywindow.window != win)
+				break;
+			cleanup();
+			exit(1);
+		case Expose:
+			if (ev.xexpose.count == 0)
+				drw_map(drw, win, 0, 0, mw, mh);
+			break;
+		case FocusIn:
+			/* regrab focus from parent window */
+			if (ev.xfocus.window != win)
+				grabfocus();
+			break;
+		case KeyPress:
+			keypress(&ev.xkey);
+			break;
+		case SelectionNotify:
+			if (ev.xselection.property == utf8)
+				paste();
+			break;
+		case VisibilityNotify:
+			if (ev.xvisibility.state != VisibilityUnobscured)
+				XRaiseWindow(dpy, win);
+			break;
+		}
+	}
+}
+
+static void
+setup(void)
+{
+	int x, y, i, j;
+	unsigned int du;
+	XSetWindowAttributes swa;
+	XIM xim;
+	Window w, dw, *dws;
+	XWindowAttributes wa;
+	XClassHint ch = {"dmenu", "dmenu"};
+#ifdef XINERAMA
+	XineramaScreenInfo *info;
+	Window pw;
+	int a, di, n, area = 0;
+#endif
+	/* init appearance */
+	for (j = 0; j < SchemeLast; j++)
+		scheme[j] = drw_scm_create(drw, colors[j], 2);
+
+	clip = XInternAtom(dpy, "CLIPBOARD",   False);
+	utf8 = XInternAtom(dpy, "UTF8_STRING", False);
+
+	/* calculate menu geometry */
+	bh = drw->fonts->h + 2;
+	lines = MAX(lines, 0);
+	mh = (lines + 1) * bh;
+#ifdef XINERAMA
+	i = 0;
+	if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
+		XGetInputFocus(dpy, &w, &di);
+		if (mon >= 0 && mon < n)
+			i = mon;
+		else if (w != root && w != PointerRoot && w != None) {
+			/* find top-level window containing current input focus */
+			do {
+				if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
+					XFree(dws);
+			} while (w != root && w != pw);
+			/* find xinerama screen with which the window intersects most */
+			if (XGetWindowAttributes(dpy, pw, &wa))
+				for (j = 0; j < n; j++)
+					if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
+						area = a;
+						i = j;
+					}
+		}
+		/* no focused window is on screen, so use pointer location instead */
+		if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
+			for (i = 0; i < n; i++)
+				if (INTERSECT(x, y, 1, 1, info[i]))
+					break;
+
+		x = info[i].x_org;
+		y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
+		mw = info[i].width;
+		XFree(info);
+	} else
+#endif
+	{
+		if (!XGetWindowAttributes(dpy, parentwin, &wa))
+			die("could not get embedding window attributes: 0x%lx",
+			    parentwin);
+		x = 0;
+		y = topbar ? 0 : wa.height - mh;
+		mw = wa.width;
+	}
+	promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
+	inputw = MIN(inputw, mw/3);
+	match();
+
+	/* create menu window */
+	swa.override_redirect = True;
+	swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
+	win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
+	                    CopyFromParent, CopyFromParent, CopyFromParent,
+	                    CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
+	XSetClassHint(dpy, win, &ch);
+
+
+	/* input methods */
+	if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
+		die("XOpenIM failed: could not open input device");
+
+	xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+	                XNClientWindow, win, XNFocusWindow, win, NULL);
+
+	XMapRaised(dpy, win);
+	if (embed) {
+		XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
+		if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
+			for (i = 0; i < du && dws[i] != win; ++i)
+				XSelectInput(dpy, dws[i], FocusChangeMask);
+			XFree(dws);
+		}
+		grabfocus();
+	}
+	drw_resize(drw, mw, mh);
+	drawmenu();
+}
+
+static void
+usage(void)
+{
+	fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
+	      "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	XWindowAttributes wa;
+	int i, fast = 0;
+
+	for (i = 1; i < argc; i++)
+		/* these options take no arguments */
+		if (!strcmp(argv[i], "-v")) {      /* prints version information */
+			puts("dmenu-"VERSION);
+			exit(0);
+		} else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
+			topbar = 0;
+		else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
+			fast = 1;
+		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
+			fstrncmp = strncasecmp;
+			fstrstr = cistrstr;
+		} else if (i + 1 == argc)
+			usage();
+		/* these options take one argument */
+		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
+			lines = atoi(argv[++i]);
+		else if (!strcmp(argv[i], "-m"))
+			mon = atoi(argv[++i]);
+		else if (!strcmp(argv[i], "-p"))   /* adds prompt to left of input field */
+			prompt = argv[++i];
+		else if (!strcmp(argv[i], "-fn"))  /* font or font set */
+			fonts[0] = argv[++i];
+		else if (!strcmp(argv[i], "-nb"))  /* normal background color */
+			colors[SchemeNorm][ColBg] = argv[++i];
+		else if (!strcmp(argv[i], "-nf"))  /* normal foreground color */
+			colors[SchemeNorm][ColFg] = argv[++i];
+		else if (!strcmp(argv[i], "-sb"))  /* selected background color */
+			colors[SchemeSel][ColBg] = argv[++i];
+		else if (!strcmp(argv[i], "-sf"))  /* selected foreground color */
+			colors[SchemeSel][ColFg] = argv[++i];
+		else if (!strcmp(argv[i], "-w"))   /* embedding window id */
+			embed = argv[++i];
+		else
+			usage();
+
+	if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
+		fputs("warning: no locale support\n", stderr);
+	if (!(dpy = XOpenDisplay(NULL)))
+		die("cannot open display");
+	screen = DefaultScreen(dpy);
+	root = RootWindow(dpy, screen);
+	if (!embed || !(parentwin = strtol(embed, NULL, 0)))
+		parentwin = root;
+	if (!XGetWindowAttributes(dpy, parentwin, &wa))
+		die("could not get embedding window attributes: 0x%lx",
+		    parentwin);
+	drw = drw_create(dpy, screen, root, wa.width, wa.height);
+	if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+		die("no fonts could be loaded.");
+	lrpad = drw->fonts->h;
+
+#ifdef __OpenBSD__
+	if (pledge("stdio rpath", NULL) == -1)
+		die("pledge");
+#endif
+
+	if (fast && !isatty(0)) {
+		grabkeyboard();
+		readstdin();
+	} else {
+		readstdin();
+		grabkeyboard();
+	}
+	setup();
+	run();
+
+	return 1; /* unreachable */
+}
diff --git a/home/kurb42/.config/suckless/dmenu/dmenu_path b/home/kurb42/.config/suckless/dmenu/dmenu_path
new file mode 100644
index 0000000..3a7cda7
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/dmenu_path
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
+cache="$cachedir/dmenu_run"
+
+[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
+
+IFS=:
+if stest -dqr -n "$cache" $PATH; then
+	stest -flx $PATH | sort -u | tee "$cache"
+else
+	cat "$cache"
+fi
diff --git a/home/kurb42/.config/suckless/dmenu/dmenu_run b/home/kurb42/.config/suckless/dmenu/dmenu_run
new file mode 100644
index 0000000..834ede5
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/dmenu_run
@@ -0,0 +1,2 @@
+#!/bin/sh
+dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
diff --git a/home/kurb42/.config/suckless/dmenu/drw.c b/home/kurb42/.config/suckless/dmenu/drw.c
new file mode 100644
index 0000000..4cdbcbe
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/drw.c
@@ -0,0 +1,436 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xft/Xft.h>
+
+#include "drw.h"
+#include "util.h"
+
+#define UTF_INVALID 0xFFFD
+#define UTF_SIZ     4
+
+static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};
+static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+static const long utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000};
+static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+
+static long
+utf8decodebyte(const char c, size_t *i)
+{
+	for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
+		if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
+			return (unsigned char)c & ~utfmask[*i];
+	return 0;
+}
+
+static size_t
+utf8validate(long *u, size_t i)
+{
+	if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
+		*u = UTF_INVALID;
+	for (i = 1; *u > utfmax[i]; ++i)
+		;
+	return i;
+}
+
+static size_t
+utf8decode(const char *c, long *u, size_t clen)
+{
+	size_t i, j, len, type;
+	long udecoded;
+
+	*u = UTF_INVALID;
+	if (!clen)
+		return 0;
+	udecoded = utf8decodebyte(c[0], &len);
+	if (!BETWEEN(len, 1, UTF_SIZ))
+		return 1;
+	for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+		udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
+		if (type)
+			return j;
+	}
+	if (j < len)
+		return 0;
+	*u = udecoded;
+	utf8validate(u, len);
+
+	return len;
+}
+
+Drw *
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+{
+	Drw *drw = ecalloc(1, sizeof(Drw));
+
+	drw->dpy = dpy;
+	drw->screen = screen;
+	drw->root = root;
+	drw->w = w;
+	drw->h = h;
+	drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
+	drw->gc = XCreateGC(dpy, root, 0, NULL);
+	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+
+	return drw;
+}
+
+void
+drw_resize(Drw *drw, unsigned int w, unsigned int h)
+{
+	if (!drw)
+		return;
+
+	drw->w = w;
+	drw->h = h;
+	if (drw->drawable)
+		XFreePixmap(drw->dpy, drw->drawable);
+	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+}
+
+void
+drw_free(Drw *drw)
+{
+	XFreePixmap(drw->dpy, drw->drawable);
+	XFreeGC(drw->dpy, drw->gc);
+	drw_fontset_free(drw->fonts);
+	free(drw);
+}
+
+/* This function is an implementation detail. Library users should use
+ * drw_fontset_create instead.
+ */
+static Fnt *
+xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
+{
+	Fnt *font;
+	XftFont *xfont = NULL;
+	FcPattern *pattern = NULL;
+
+	if (fontname) {
+		/* Using the pattern found at font->xfont->pattern does not yield the
+		 * same substitution results as using the pattern returned by
+		 * FcNameParse; using the latter results in the desired fallback
+		 * behaviour whereas the former just results in missing-character
+		 * rectangles being drawn, at least with some fonts. */
+		if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
+			fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
+			return NULL;
+		}
+		if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
+			fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
+			XftFontClose(drw->dpy, xfont);
+			return NULL;
+		}
+	} else if (fontpattern) {
+		if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
+			fprintf(stderr, "error, cannot load font from pattern.\n");
+			return NULL;
+		}
+	} else {
+		die("no font specified.");
+	}
+
+	/* Do not allow using color fonts. This is a workaround for a BadLength
+	 * error from Xft with color glyphs. Modelled on the Xterm workaround. See
+	 * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
+	 * https://lists.suckless.org/dev/1701/30932.html
+	 * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
+	 * and lots more all over the internet.
+	 */
+	FcBool iscol;
+	if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
+		XftFontClose(drw->dpy, xfont);
+		return NULL;
+	}
+
+	font = ecalloc(1, sizeof(Fnt));
+	font->xfont = xfont;
+	font->pattern = pattern;
+	font->h = xfont->ascent + xfont->descent;
+	font->dpy = drw->dpy;
+
+	return font;
+}
+
+static void
+xfont_free(Fnt *font)
+{
+	if (!font)
+		return;
+	if (font->pattern)
+		FcPatternDestroy(font->pattern);
+	XftFontClose(font->dpy, font->xfont);
+	free(font);
+}
+
+Fnt*
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
+{
+	Fnt *cur, *ret = NULL;
+	size_t i;
+
+	if (!drw || !fonts)
+		return NULL;
+
+	for (i = 1; i <= fontcount; i++) {
+		if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
+			cur->next = ret;
+			ret = cur;
+		}
+	}
+	return (drw->fonts = ret);
+}
+
+void
+drw_fontset_free(Fnt *font)
+{
+	if (font) {
+		drw_fontset_free(font->next);
+		xfont_free(font);
+	}
+}
+
+void
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+{
+	if (!drw || !dest || !clrname)
+		return;
+
+	if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
+	                       DefaultColormap(drw->dpy, drw->screen),
+	                       clrname, dest))
+		die("error, cannot allocate color '%s'", clrname);
+}
+
+/* Wrapper to create color schemes. The caller has to call free(3) on the
+ * returned color scheme when done using it. */
+Clr *
+drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+{
+	size_t i;
+	Clr *ret;
+
+	/* need at least two colors for a scheme */
+	if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
+		return NULL;
+
+	for (i = 0; i < clrcount; i++)
+		drw_clr_create(drw, &ret[i], clrnames[i]);
+	return ret;
+}
+
+void
+drw_setfontset(Drw *drw, Fnt *set)
+{
+	if (drw)
+		drw->fonts = set;
+}
+
+void
+drw_setscheme(Drw *drw, Clr *scm)
+{
+	if (drw)
+		drw->scheme = scm;
+}
+
+void
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
+{
+	if (!drw || !drw->scheme)
+		return;
+	XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
+	if (filled)
+		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+	else
+		XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
+}
+
+int
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
+{
+	char buf[1024];
+	int ty;
+	unsigned int ew;
+	XftDraw *d = NULL;
+	Fnt *usedfont, *curfont, *nextfont;
+	size_t i, len;
+	int utf8strlen, utf8charlen, render = x || y || w || h;
+	long utf8codepoint = 0;
+	const char *utf8str;
+	FcCharSet *fccharset;
+	FcPattern *fcpattern;
+	FcPattern *match;
+	XftResult result;
+	int charexists = 0;
+
+	if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
+		return 0;
+
+	if (!render) {
+		w = ~w;
+	} else {
+		XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
+		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+		d = XftDrawCreate(drw->dpy, drw->drawable,
+		                  DefaultVisual(drw->dpy, drw->screen),
+		                  DefaultColormap(drw->dpy, drw->screen));
+		x += lpad;
+		w -= lpad;
+	}
+
+	usedfont = drw->fonts;
+	while (1) {
+		utf8strlen = 0;
+		utf8str = text;
+		nextfont = NULL;
+		while (*text) {
+			utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
+			for (curfont = drw->fonts; curfont; curfont = curfont->next) {
+				charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
+				if (charexists) {
+					if (curfont == usedfont) {
+						utf8strlen += utf8charlen;
+						text += utf8charlen;
+					} else {
+						nextfont = curfont;
+					}
+					break;
+				}
+			}
+
+			if (!charexists || nextfont)
+				break;
+			else
+				charexists = 0;
+		}
+
+		if (utf8strlen) {
+			drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
+			/* shorten text if necessary */
+			for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
+				drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
+
+			if (len) {
+				memcpy(buf, utf8str, len);
+				buf[len] = '\0';
+				if (len < utf8strlen)
+					for (i = len; i && i > len - 3; buf[--i] = '.')
+						; /* NOP */
+
+				if (render) {
+					ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
+					XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
+					                  usedfont->xfont, x, ty, (XftChar8 *)buf, len);
+				}
+				x += ew;
+				w -= ew;
+			}
+		}
+
+		if (!*text) {
+			break;
+		} else if (nextfont) {
+			charexists = 0;
+			usedfont = nextfont;
+		} else {
+			/* Regardless of whether or not a fallback font is found, the
+			 * character must be drawn. */
+			charexists = 1;
+
+			fccharset = FcCharSetCreate();
+			FcCharSetAddChar(fccharset, utf8codepoint);
+
+			if (!drw->fonts->pattern) {
+				/* Refer to the comment in xfont_create for more information. */
+				die("the first font in the cache must be loaded from a font string.");
+			}
+
+			fcpattern = FcPatternDuplicate(drw->fonts->pattern);
+			FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
+			FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
+			FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
+
+			FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
+			FcDefaultSubstitute(fcpattern);
+			match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
+
+			FcCharSetDestroy(fccharset);
+			FcPatternDestroy(fcpattern);
+
+			if (match) {
+				usedfont = xfont_create(drw, NULL, match);
+				if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
+					for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
+						; /* NOP */
+					curfont->next = usedfont;
+				} else {
+					xfont_free(usedfont);
+					usedfont = drw->fonts;
+				}
+			}
+		}
+	}
+	if (d)
+		XftDrawDestroy(d);
+
+	return x + (render ? w : 0);
+}
+
+void
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
+{
+	if (!drw)
+		return;
+
+	XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
+	XSync(drw->dpy, False);
+}
+
+unsigned int
+drw_fontset_getwidth(Drw *drw, const char *text)
+{
+	if (!drw || !drw->fonts || !text)
+		return 0;
+	return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
+}
+
+void
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
+{
+	XGlyphInfo ext;
+
+	if (!font || !text)
+		return;
+
+	XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
+	if (w)
+		*w = ext.xOff;
+	if (h)
+		*h = font->h;
+}
+
+Cur *
+drw_cur_create(Drw *drw, int shape)
+{
+	Cur *cur;
+
+	if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
+		return NULL;
+
+	cur->cursor = XCreateFontCursor(drw->dpy, shape);
+
+	return cur;
+}
+
+void
+drw_cur_free(Drw *drw, Cur *cursor)
+{
+	if (!cursor)
+		return;
+
+	XFreeCursor(drw->dpy, cursor->cursor);
+	free(cursor);
+}
diff --git a/home/kurb42/.config/suckless/dmenu/drw.h b/home/kurb42/.config/suckless/dmenu/drw.h
new file mode 100644
index 0000000..4c67419
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/drw.h
@@ -0,0 +1,57 @@
+/* See LICENSE file for copyright and license details. */
+
+typedef struct {
+	Cursor cursor;
+} Cur;
+
+typedef struct Fnt {
+	Display *dpy;
+	unsigned int h;
+	XftFont *xfont;
+	FcPattern *pattern;
+	struct Fnt *next;
+} Fnt;
+
+enum { ColFg, ColBg }; /* Clr scheme index */
+typedef XftColor Clr;
+
+typedef struct {
+	unsigned int w, h;
+	Display *dpy;
+	int screen;
+	Window root;
+	Drawable drawable;
+	GC gc;
+	Clr *scheme;
+	Fnt *fonts;
+} Drw;
+
+/* Drawable abstraction */
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+void drw_free(Drw *drw);
+
+/* Fnt abstraction */
+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
+void drw_fontset_free(Fnt* set);
+unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
+void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
+
+/* Colorscheme abstraction */
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+
+/* Cursor abstraction */
+Cur *drw_cur_create(Drw *drw, int shape);
+void drw_cur_free(Drw *drw, Cur *cursor);
+
+/* Drawing context manipulation */
+void drw_setfontset(Drw *drw, Fnt *set);
+void drw_setscheme(Drw *drw, Clr *scm);
+
+/* Drawing functions */
+void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
+int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
+
+/* Map functions */
+void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
diff --git a/home/kurb42/.config/suckless/dmenu/stest.1 b/home/kurb42/.config/suckless/dmenu/stest.1
new file mode 100644
index 0000000..2667d8a
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/stest.1
@@ -0,0 +1,90 @@
+.TH STEST 1 dmenu\-VERSION
+.SH NAME
+stest \- filter a list of files by properties
+.SH SYNOPSIS
+.B stest
+.RB [ -abcdefghlpqrsuwx ]
+.RB [ -n
+.IR file ]
+.RB [ -o
+.IR file ]
+.RI [ file ...]
+.SH DESCRIPTION
+.B stest
+takes a list of files and filters by the files' properties, analogous to
+.IR test (1).
+Files which pass all tests are printed to stdout. If no files are given, stest
+reads files from stdin.
+.SH OPTIONS
+.TP
+.B \-a
+Test hidden files.
+.TP
+.B \-b
+Test that files are block specials.
+.TP
+.B \-c
+Test that files are character specials.
+.TP
+.B \-d
+Test that files are directories.
+.TP
+.B \-e
+Test that files exist.
+.TP
+.B \-f
+Test that files are regular files.
+.TP
+.B \-g
+Test that files have their set-group-ID flag set.
+.TP
+.B \-h
+Test that files are symbolic links.
+.TP
+.B \-l
+Test the contents of a directory given as an argument.
+.TP
+.BI \-n " file"
+Test that files are newer than
+.IR file .
+.TP
+.BI \-o " file"
+Test that files are older than
+.IR file .
+.TP
+.B \-p
+Test that files are named pipes.
+.TP
+.B \-q
+No files are printed, only the exit status is returned.
+.TP
+.B \-r
+Test that files are readable.
+.TP
+.B \-s
+Test that files are not empty.
+.TP
+.B \-u
+Test that files have their set-user-ID flag set.
+.TP
+.B \-v
+Invert the sense of tests, only failing files pass.
+.TP
+.B \-w
+Test that files are writable.
+.TP
+.B \-x
+Test that files are executable.
+.SH EXIT STATUS
+.TP
+.B 0
+At least one file passed all tests.
+.TP
+.B 1
+No files passed all tests.
+.TP
+.B 2
+An error occurred.
+.SH SEE ALSO
+.IR dmenu (1),
+.IR test (1)
diff --git a/home/kurb42/.config/suckless/dmenu/stest.c b/home/kurb42/.config/suckless/dmenu/stest.c
new file mode 100644
index 0000000..7a7b0bc
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/stest.c
@@ -0,0 +1,109 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "arg.h"
+char *argv0;
+
+#define FLAG(x)  (flag[(x)-'a'])
+
+static void test(const char *, const char *);
+static void usage(void);
+
+static int match = 0;
+static int flag[26];
+static struct stat old, new;
+
+static void
+test(const char *path, const char *name)
+{
+	struct stat st, ln;
+
+	if ((!stat(path, &st) && (FLAG('a') || name[0] != '.')        /* hidden files      */
+	&& (!FLAG('b') || S_ISBLK(st.st_mode))                        /* block special     */
+	&& (!FLAG('c') || S_ISCHR(st.st_mode))                        /* character special */
+	&& (!FLAG('d') || S_ISDIR(st.st_mode))                        /* directory         */
+	&& (!FLAG('e') || access(path, F_OK) == 0)                    /* exists            */
+	&& (!FLAG('f') || S_ISREG(st.st_mode))                        /* regular file      */
+	&& (!FLAG('g') || st.st_mode & S_ISGID)                       /* set-group-id flag */
+	&& (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link     */
+	&& (!FLAG('n') || st.st_mtime > new.st_mtime)                 /* newer than file   */
+	&& (!FLAG('o') || st.st_mtime < old.st_mtime)                 /* older than file   */
+	&& (!FLAG('p') || S_ISFIFO(st.st_mode))                       /* named pipe        */
+	&& (!FLAG('r') || access(path, R_OK) == 0)                    /* readable          */
+	&& (!FLAG('s') || st.st_size > 0)                             /* not empty         */
+	&& (!FLAG('u') || st.st_mode & S_ISUID)                       /* set-user-id flag  */
+	&& (!FLAG('w') || access(path, W_OK) == 0)                    /* writable          */
+	&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) {   /* executable        */
+		if (FLAG('q'))
+			exit(0);
+		match = 1;
+		puts(name);
+	}
+}
+
+static void
+usage(void)
+{
+	fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
+	        "[-n file] [-o file] [file...]\n", argv0);
+	exit(2); /* like test(1) return > 1 on error */
+}
+
+int
+main(int argc, char *argv[])
+{
+	struct dirent *d;
+	char path[PATH_MAX], *line = NULL, *file;
+	size_t linesiz = 0;
+	ssize_t n;
+	DIR *dir;
+	int r;
+
+	ARGBEGIN {
+	case 'n': /* newer than file */
+	case 'o': /* older than file */
+		file = EARGF(usage());
+		if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
+			perror(file);
+		break;
+	default:
+		/* miscellaneous operators */
+		if (strchr("abcdefghlpqrsuvwx", ARGC()))
+			FLAG(ARGC()) = 1;
+		else
+			usage(); /* unknown flag */
+	} ARGEND;
+
+	if (!argc) {
+		/* read list from stdin */
+		while ((n = getline(&line, &linesiz, stdin)) > 0) {
+			if (n && line[n - 1] == '\n')
+				line[n - 1] = '\0';
+			test(line, line);
+		}
+		free(line);
+	} else {
+		for (; argc; argc--, argv++) {
+			if (FLAG('l') && (dir = opendir(*argv))) {
+				/* test directory contents */
+				while ((d = readdir(dir))) {
+					r = snprintf(path, sizeof path, "%s/%s",
+					             *argv, d->d_name);
+					if (r >= 0 && (size_t)r < sizeof path)
+						test(path, d->d_name);
+				}
+				closedir(dir);
+			} else {
+				test(*argv, *argv);
+			}
+		}
+	}
+	return match ? 0 : 1;
+}
diff --git a/home/kurb42/.config/suckless/dmenu/util.c b/home/kurb42/.config/suckless/dmenu/util.c
new file mode 100644
index 0000000..fe044fc
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/util.c
@@ -0,0 +1,35 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+void *
+ecalloc(size_t nmemb, size_t size)
+{
+	void *p;
+
+	if (!(p = calloc(nmemb, size)))
+		die("calloc:");
+	return p;
+}
+
+void
+die(const char *fmt, ...) {
+	va_list ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+		fputc(' ', stderr);
+		perror(NULL);
+	} else {
+		fputc('\n', stderr);
+	}
+
+	exit(1);
+}
diff --git a/home/kurb42/.config/suckless/dmenu/util.h b/home/kurb42/.config/suckless/dmenu/util.h
new file mode 100644
index 0000000..f633b51
--- /dev/null
+++ b/home/kurb42/.config/suckless/dmenu/util.h
@@ -0,0 +1,8 @@
+/* See LICENSE file for copyright and license details. */
+
+#define MAX(A, B)               ((A) > (B) ? (A) : (B))
+#define MIN(A, B)               ((A) < (B) ? (A) : (B))
+#define BETWEEN(X, A, B)        ((A) <= (X) && (X) <= (B))
+
+void die(const char *fmt, ...);
+void *ecalloc(size_t nmemb, size_t size);
diff --git a/home/kurb42/.config/suckless/dwm/LICENSE b/home/kurb42/.config/suckless/dwm/LICENSE
new file mode 100644
index 0000000..d221f09
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/LICENSE
@@ -0,0 +1,37 @@
+MIT/X Consortium License
+
+© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
+© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
+© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
+© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
+© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
+© 2007-2009 Christof Musik <christof at sendfax dot de>
+© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
+© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
+© 2008 Martin Hurton <martin dot hurton at gmail dot com>
+© 2008 Neale Pickett <neale dot woozle dot org>
+© 2009 Mate Nagy <mnagy at port70 dot net>
+© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
+© 2010-2012 Connor Lane Smith <cls@lubutu.com>
+© 2011 Christoph Lohmann <20h@r-36.net>
+© 2015-2016 Quentin Rameau <quinq@fifth.space>
+© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
+© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/home/kurb42/.config/suckless/dwm/Makefile b/home/kurb42/.config/suckless/dwm/Makefile
new file mode 100644
index 0000000..77bcbc0
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/Makefile
@@ -0,0 +1,51 @@
+# dwm - dynamic window manager
+# See LICENSE file for copyright and license details.
+
+include config.mk
+
+SRC = drw.c dwm.c util.c
+OBJ = ${SRC:.c=.o}
+
+all: options dwm
+
+options:
+	@echo dwm build options:
+	@echo "CFLAGS   = ${CFLAGS}"
+	@echo "LDFLAGS  = ${LDFLAGS}"
+	@echo "CC       = ${CC}"
+
+.c.o:
+	${CC} -c ${CFLAGS} $<
+
+${OBJ}: config.h config.mk
+
+config.h:
+	cp config.def.h $@
+
+dwm: ${OBJ}
+	${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+clean:
+	rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
+
+dist: clean
+	mkdir -p dwm-${VERSION}
+	cp -R LICENSE Makefile README config.def.h config.mk\
+		dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
+	tar -cf dwm-${VERSION}.tar dwm-${VERSION}
+	gzip dwm-${VERSION}.tar
+	rm -rf dwm-${VERSION}
+
+install: all
+	mkdir -p ${DESTDIR}${PREFIX}/bin
+	cp -f dwm ${DESTDIR}${PREFIX}/bin
+	chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
+	mkdir -p ${DESTDIR}${MANPREFIX}/man1
+	sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
+	chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
+
+uninstall:
+	rm -f ${DESTDIR}${PREFIX}/bin/dwm\
+		${DESTDIR}${MANPREFIX}/man1/dwm.1
+
+.PHONY: all options clean dist install uninstall
diff --git a/home/kurb42/.config/suckless/dwm/README b/home/kurb42/.config/suckless/dwm/README
new file mode 100644
index 0000000..95d4fd0
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/README
@@ -0,0 +1,48 @@
+dwm - dynamic window manager
+============================
+dwm is an extremely fast, small, and dynamic window manager for X.
+
+
+Requirements
+------------
+In order to build dwm you need the Xlib header files.
+
+
+Installation
+------------
+Edit config.mk to match your local setup (dwm is installed into
+the /usr/local namespace by default).
+
+Afterwards enter the following command to build and install dwm (if
+necessary as root):
+
+    make clean install
+
+
+Running dwm
+-----------
+Add the following line to your .xinitrc to start dwm using startx:
+
+    exec dwm
+
+In order to connect dwm to a specific display, make sure that
+the DISPLAY environment variable is set correctly, e.g.:
+
+    DISPLAY=foo.bar:1 exec dwm
+
+(This will start dwm on display :1 of the host foo.bar.)
+
+In order to display status info in the bar, you can do something
+like this in your .xinitrc:
+
+    while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
+    do
+    	sleep 1
+    done &
+    exec dwm
+
+
+Configuration
+-------------
+The configuration of dwm is done by creating a custom config.h
+and (re)compiling the source code.
diff --git a/home/kurb42/.config/suckless/dwm/config.def.h b/home/kurb42/.config/suckless/dwm/config.def.h
new file mode 100644
index 0000000..ecd5ce0
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/config.def.h
@@ -0,0 +1,111 @@
+/* See LICENSE file for copyright and license details. */
+
+/* appearance */
+static const unsigned int borderpx  = 1;        /* border pixel of windows */
+static const unsigned int snap      = 32;       /* snap pixel */
+static const int showbar            = 1;        /* 0 means no bar */
+static const int topbar             = 1;        /* 0 means bottom bar */
+static const char *fonts[]          = { "UbuntuMono Nerd Font:size=10" };
+static const char col_gray1[]       = "#202020";
+static const char col_gray2[]       = "#404040";
+static const char col_gray3[]       = "#c0c0c0";
+static const char col_gray4[]       = "#f0f0f0";
+static const char col_cyan[]        = "#a0a0aa";
+static const char *colors[][3]      = {
+  /*               fg         bg         border   */
+  [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+  [SchemeSel]  = { col_gray4, col_gray2, col_cyan  },
+};
+
+/* tagging */
+static const char *tags[] = { "I", "II", "III", "IV", "V" };
+
+static const Rule rules[] = {
+	/* xprop(1):
+	 *	WM_CLASS(STRING) = instance, class
+	 *	WM_NAME(STRING) = title
+	 */
+	/* class      instance    title       tags mask     isfloating   monitor */
+	{ "Firefox",    NULL,       NULL,       1 << 0,            0,           -1 },
+	{ "URxvt",      NULL,       NULL,       1 << 1,       0,           -1 },
+	{ "Emacs",      NULL,       NULL,       1 << 2,       0,           -1 },
+};
+
+/* layout(s) */
+static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
+static const int nmaster     = 1;    /* number of clients in master area */
+static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */
+
+static const Layout layouts[] = {
+	/* symbol     arrange function */
+	{ "[]=",      tile },    /* first entry is default */
+	{ "><>",      NULL },    /* no layout function means floating behavior */
+	{ "[M]",      monocle },
+};
+
+/* key definitions */
+#define MODKEY Mod4Mask
+#define TAGKEYS(KEY,TAG) \
+	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
+	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
+	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
+	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
+
+/* helper for spawning shell commands in the pre dwm-5.0 fashion */
+#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
+/* commands */
+static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, NULL };
+static const char *termcmd[]  = { "urxvt", NULL };
+
+static Key keys[] = {
+	/* modifier                     key        function        argument */
+	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
+	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
+	{ MODKEY,                       XK_b,      togglebar,      {0} },
+	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
+	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
+	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
+	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
+	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
+	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
+	{ MODKEY,                       XK_Return, zoom,           {0} },
+	{ MODKEY,                       XK_Tab,    view,           {0} },
+	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
+	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
+	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
+	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
+	{ MODKEY,                       XK_space,  setlayout,      {0} },
+	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
+	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
+	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
+	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
+	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
+	TAGKEYS(                        XK_1,                      0)
+	TAGKEYS(                        XK_2,                      1)
+	TAGKEYS(                        XK_3,                      2)
+	TAGKEYS(                        XK_4,                      3)
+	TAGKEYS(                        XK_5,                      4)
+	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
+};
+
+/* button definitions */
+/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
+static Button buttons[] = {
+	/* click                event mask      button          function        argument */
+	{ ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
+	{ ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
+	{ ClkWinTitle,          0,              Button2,        zoom,           {0} },
+	{ ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
+	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
+	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
+	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
+	{ ClkTagBar,            0,              Button1,        view,           {0} },
+	{ ClkTagBar,            0,              Button3,        toggleview,     {0} },
+	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
+	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
+};
+
diff --git a/home/kurb42/.config/suckless/dwm/config.mk b/home/kurb42/.config/suckless/dwm/config.mk
new file mode 100644
index 0000000..6d36cb7
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/config.mk
@@ -0,0 +1,38 @@
+# dwm version
+VERSION = 6.2
+
+# Customize below to fit your system
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = ${PREFIX}/share/man
+
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
+
+# Xinerama, comment if you don't want it
+XINERAMALIBS  = -lXinerama
+XINERAMAFLAGS = -DXINERAMA
+
+# freetype
+FREETYPELIBS = -lfontconfig -lXft
+FREETYPEINC = /usr/include/freetype2
+# OpenBSD (uncomment)
+#FREETYPEINC = ${X11INC}/freetype2
+
+# includes and libs
+INCS = -I${X11INC} -I${FREETYPEINC}
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
+
+# flags
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+#CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
+CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
+LDFLAGS  = ${LIBS}
+
+# Solaris
+#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
+#LDFLAGS = ${LIBS}
+
+# compiler and linker
+CC = cc
diff --git a/home/kurb42/.config/suckless/dwm/drw.c b/home/kurb42/.config/suckless/dwm/drw.c
new file mode 100644
index 0000000..8fd1ca4
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/drw.c
@@ -0,0 +1,435 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xft/Xft.h>
+
+#include "drw.h"
+#include "util.h"
+
+#define UTF_INVALID 0xFFFD
+#define UTF_SIZ     4
+
+static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};
+static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+static const long utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000};
+static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+
+static long
+utf8decodebyte(const char c, size_t *i)
+{
+	for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
+		if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
+			return (unsigned char)c & ~utfmask[*i];
+	return 0;
+}
+
+static size_t
+utf8validate(long *u, size_t i)
+{
+	if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
+		*u = UTF_INVALID;
+	for (i = 1; *u > utfmax[i]; ++i)
+		;
+	return i;
+}
+
+static size_t
+utf8decode(const char *c, long *u, size_t clen)
+{
+	size_t i, j, len, type;
+	long udecoded;
+
+	*u = UTF_INVALID;
+	if (!clen)
+		return 0;
+	udecoded = utf8decodebyte(c[0], &len);
+	if (!BETWEEN(len, 1, UTF_SIZ))
+		return 1;
+	for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+		udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
+		if (type)
+			return j;
+	}
+	if (j < len)
+		return 0;
+	*u = udecoded;
+	utf8validate(u, len);
+
+	return len;
+}
+
+Drw *
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+{
+	Drw *drw = ecalloc(1, sizeof(Drw));
+
+	drw->dpy = dpy;
+	drw->screen = screen;
+	drw->root = root;
+	drw->w = w;
+	drw->h = h;
+	drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
+	drw->gc = XCreateGC(dpy, root, 0, NULL);
+	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+
+	return drw;
+}
+
+void
+drw_resize(Drw *drw, unsigned int w, unsigned int h)
+{
+	if (!drw)
+		return;
+
+	drw->w = w;
+	drw->h = h;
+	if (drw->drawable)
+		XFreePixmap(drw->dpy, drw->drawable);
+	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+}
+
+void
+drw_free(Drw *drw)
+{
+	XFreePixmap(drw->dpy, drw->drawable);
+	XFreeGC(drw->dpy, drw->gc);
+	free(drw);
+}
+
+/* This function is an implementation detail. Library users should use
+ * drw_fontset_create instead.
+ */
+static Fnt *
+xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
+{
+	Fnt *font;
+	XftFont *xfont = NULL;
+	FcPattern *pattern = NULL;
+
+	if (fontname) {
+		/* Using the pattern found at font->xfont->pattern does not yield the
+		 * same substitution results as using the pattern returned by
+		 * FcNameParse; using the latter results in the desired fallback
+		 * behaviour whereas the former just results in missing-character
+		 * rectangles being drawn, at least with some fonts. */
+		if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
+			fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
+			return NULL;
+		}
+		if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
+			fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
+			XftFontClose(drw->dpy, xfont);
+			return NULL;
+		}
+	} else if (fontpattern) {
+		if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
+			fprintf(stderr, "error, cannot load font from pattern.\n");
+			return NULL;
+		}
+	} else {
+		die("no font specified.");
+	}
+
+	/* Do not allow using color fonts. This is a workaround for a BadLength
+	 * error from Xft with color glyphs. Modelled on the Xterm workaround. See
+	 * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
+	 * https://lists.suckless.org/dev/1701/30932.html
+	 * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
+	 * and lots more all over the internet.
+	 */
+	FcBool iscol;
+	if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
+		XftFontClose(drw->dpy, xfont);
+		return NULL;
+	}
+
+	font = ecalloc(1, sizeof(Fnt));
+	font->xfont = xfont;
+	font->pattern = pattern;
+	font->h = xfont->ascent + xfont->descent;
+	font->dpy = drw->dpy;
+
+	return font;
+}
+
+static void
+xfont_free(Fnt *font)
+{
+	if (!font)
+		return;
+	if (font->pattern)
+		FcPatternDestroy(font->pattern);
+	XftFontClose(font->dpy, font->xfont);
+	free(font);
+}
+
+Fnt*
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
+{
+	Fnt *cur, *ret = NULL;
+	size_t i;
+
+	if (!drw || !fonts)
+		return NULL;
+
+	for (i = 1; i <= fontcount; i++) {
+		if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
+			cur->next = ret;
+			ret = cur;
+		}
+	}
+	return (drw->fonts = ret);
+}
+
+void
+drw_fontset_free(Fnt *font)
+{
+	if (font) {
+		drw_fontset_free(font->next);
+		xfont_free(font);
+	}
+}
+
+void
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+{
+	if (!drw || !dest || !clrname)
+		return;
+
+	if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
+	                       DefaultColormap(drw->dpy, drw->screen),
+	                       clrname, dest))
+		die("error, cannot allocate color '%s'", clrname);
+}
+
+/* Wrapper to create color schemes. The caller has to call free(3) on the
+ * returned color scheme when done using it. */
+Clr *
+drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+{
+	size_t i;
+	Clr *ret;
+
+	/* need at least two colors for a scheme */
+	if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
+		return NULL;
+
+	for (i = 0; i < clrcount; i++)
+		drw_clr_create(drw, &ret[i], clrnames[i]);
+	return ret;
+}
+
+void
+drw_setfontset(Drw *drw, Fnt *set)
+{
+	if (drw)
+		drw->fonts = set;
+}
+
+void
+drw_setscheme(Drw *drw, Clr *scm)
+{
+	if (drw)
+		drw->scheme = scm;
+}
+
+void
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
+{
+	if (!drw || !drw->scheme)
+		return;
+	XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
+	if (filled)
+		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+	else
+		XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
+}
+
+int
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
+{
+	char buf[1024];
+	int ty;
+	unsigned int ew;
+	XftDraw *d = NULL;
+	Fnt *usedfont, *curfont, *nextfont;
+	size_t i, len;
+	int utf8strlen, utf8charlen, render = x || y || w || h;
+	long utf8codepoint = 0;
+	const char *utf8str;
+	FcCharSet *fccharset;
+	FcPattern *fcpattern;
+	FcPattern *match;
+	XftResult result;
+	int charexists = 0;
+
+	if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
+		return 0;
+
+	if (!render) {
+		w = ~w;
+	} else {
+		XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
+		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+		d = XftDrawCreate(drw->dpy, drw->drawable,
+		                  DefaultVisual(drw->dpy, drw->screen),
+		                  DefaultColormap(drw->dpy, drw->screen));
+		x += lpad;
+		w -= lpad;
+	}
+
+	usedfont = drw->fonts;
+	while (1) {
+		utf8strlen = 0;
+		utf8str = text;
+		nextfont = NULL;
+		while (*text) {
+			utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
+			for (curfont = drw->fonts; curfont; curfont = curfont->next) {
+				charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
+				if (charexists) {
+					if (curfont == usedfont) {
+						utf8strlen += utf8charlen;
+						text += utf8charlen;
+					} else {
+						nextfont = curfont;
+					}
+					break;
+				}
+			}
+
+			if (!charexists || nextfont)
+				break;
+			else
+				charexists = 0;
+		}
+
+		if (utf8strlen) {
+			drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
+			/* shorten text if necessary */
+			for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
+				drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
+
+			if (len) {
+				memcpy(buf, utf8str, len);
+				buf[len] = '\0';
+				if (len < utf8strlen)
+					for (i = len; i && i > len - 3; buf[--i] = '.')
+						; /* NOP */
+
+				if (render) {
+					ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
+					XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
+					                  usedfont->xfont, x, ty, (XftChar8 *)buf, len);
+				}
+				x += ew;
+				w -= ew;
+			}
+		}
+
+		if (!*text) {
+			break;
+		} else if (nextfont) {
+			charexists = 0;
+			usedfont = nextfont;
+		} else {
+			/* Regardless of whether or not a fallback font is found, the
+			 * character must be drawn. */
+			charexists = 1;
+
+			fccharset = FcCharSetCreate();
+			FcCharSetAddChar(fccharset, utf8codepoint);
+
+			if (!drw->fonts->pattern) {
+				/* Refer to the comment in xfont_create for more information. */
+				die("the first font in the cache must be loaded from a font string.");
+			}
+
+			fcpattern = FcPatternDuplicate(drw->fonts->pattern);
+			FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
+			FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
+			FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
+
+			FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
+			FcDefaultSubstitute(fcpattern);
+			match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
+
+			FcCharSetDestroy(fccharset);
+			FcPatternDestroy(fcpattern);
+
+			if (match) {
+				usedfont = xfont_create(drw, NULL, match);
+				if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
+					for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
+						; /* NOP */
+					curfont->next = usedfont;
+				} else {
+					xfont_free(usedfont);
+					usedfont = drw->fonts;
+				}
+			}
+		}
+	}
+	if (d)
+		XftDrawDestroy(d);
+
+	return x + (render ? w : 0);
+}
+
+void
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
+{
+	if (!drw)
+		return;
+
+	XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
+	XSync(drw->dpy, False);
+}
+
+unsigned int
+drw_fontset_getwidth(Drw *drw, const char *text)
+{
+	if (!drw || !drw->fonts || !text)
+		return 0;
+	return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
+}
+
+void
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
+{
+	XGlyphInfo ext;
+
+	if (!font || !text)
+		return;
+
+	XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
+	if (w)
+		*w = ext.xOff;
+	if (h)
+		*h = font->h;
+}
+
+Cur *
+drw_cur_create(Drw *drw, int shape)
+{
+	Cur *cur;
+
+	if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
+		return NULL;
+
+	cur->cursor = XCreateFontCursor(drw->dpy, shape);
+
+	return cur;
+}
+
+void
+drw_cur_free(Drw *drw, Cur *cursor)
+{
+	if (!cursor)
+		return;
+
+	XFreeCursor(drw->dpy, cursor->cursor);
+	free(cursor);
+}
diff --git a/home/kurb42/.config/suckless/dwm/drw.h b/home/kurb42/.config/suckless/dwm/drw.h
new file mode 100644
index 0000000..4bcd5ad
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/drw.h
@@ -0,0 +1,57 @@
+/* See LICENSE file for copyright and license details. */
+
+typedef struct {
+	Cursor cursor;
+} Cur;
+
+typedef struct Fnt {
+	Display *dpy;
+	unsigned int h;
+	XftFont *xfont;
+	FcPattern *pattern;
+	struct Fnt *next;
+} Fnt;
+
+enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
+typedef XftColor Clr;
+
+typedef struct {
+	unsigned int w, h;
+	Display *dpy;
+	int screen;
+	Window root;
+	Drawable drawable;
+	GC gc;
+	Clr *scheme;
+	Fnt *fonts;
+} Drw;
+
+/* Drawable abstraction */
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+void drw_free(Drw *drw);
+
+/* Fnt abstraction */
+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
+void drw_fontset_free(Fnt* set);
+unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
+void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
+
+/* Colorscheme abstraction */
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+
+/* Cursor abstraction */
+Cur *drw_cur_create(Drw *drw, int shape);
+void drw_cur_free(Drw *drw, Cur *cursor);
+
+/* Drawing context manipulation */
+void drw_setfontset(Drw *drw, Fnt *set);
+void drw_setscheme(Drw *drw, Clr *scm);
+
+/* Drawing functions */
+void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
+int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
+
+/* Map functions */
+void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
diff --git a/home/kurb42/.config/suckless/dwm/dwm.1 b/home/kurb42/.config/suckless/dwm/dwm.1
new file mode 100644
index 0000000..13b3729
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/dwm.1
@@ -0,0 +1,176 @@
+.TH DWM 1 dwm\-VERSION
+.SH NAME
+dwm \- dynamic window manager
+.SH SYNOPSIS
+.B dwm
+.RB [ \-v ]
+.SH DESCRIPTION
+dwm is a dynamic window manager for X. It manages windows in tiled, monocle
+and floating layouts. Either layout can be applied dynamically, optimising the
+environment for the application in use and the task performed.
+.P
+In tiled layouts windows are managed in a master and stacking area. The master
+area on the left contains one window by default, and the stacking area on the
+right contains all other windows. The number of master area windows can be
+adjusted from zero to an arbitrary number. In monocle layout all windows are
+maximised to the screen size. In floating layout windows can be resized and
+moved freely. Dialog windows are always managed floating, regardless of the
+layout applied.
+.P
+Windows are grouped by tags. Each window can be tagged with one or multiple
+tags. Selecting certain tags displays all windows with these tags.
+.P
+Each screen contains a small status bar which displays all available tags, the
+layout, the title of the focused window, and the text read from the root window
+name property, if the screen is focused. A floating window is indicated with an
+empty square and a maximised floating window is indicated with a filled square
+before the windows title.  The selected tags are indicated with a different
+color. The tags of the focused window are indicated with a filled square in the
+top left corner.  The tags which are applied to one or more windows are
+indicated with an empty square in the top left corner.
+.P
+dwm draws a small border around windows to indicate the focus state.
+.SH OPTIONS
+.TP
+.B \-v
+prints version information to standard output, then exits.
+.SH USAGE
+.SS Status bar
+.TP
+.B X root window name
+is read and displayed in the status text area. It can be set with the
+.BR xsetroot (1)
+command.
+.TP
+.B Button1
+click on a tag label to display all windows with that tag, click on the layout
+label toggles between tiled and floating layout.
+.TP
+.B Button3
+click on a tag label adds/removes all windows with that tag to/from the view.
+.TP
+.B Mod1\-Button1
+click on a tag label applies that tag to the focused window.
+.TP
+.B Mod1\-Button3
+click on a tag label adds/removes that tag to/from the focused window.
+.SS Keyboard commands
+.TP
+.B Mod1\-Shift\-Return
+Start
+.BR st(1).
+.TP
+.B Mod1\-p
+Spawn
+.BR dmenu(1)
+for launching other programs.
+.TP
+.B Mod1\-,
+Focus previous screen, if any.
+.TP
+.B Mod1\-.
+Focus next screen, if any.
+.TP
+.B Mod1\-Shift\-,
+Send focused window to previous screen, if any.
+.TP
+.B Mod1\-Shift\-.
+Send focused window to next screen, if any.
+.TP
+.B Mod1\-b
+Toggles bar on and off.
+.TP
+.B Mod1\-t
+Sets tiled layout.
+.TP
+.B Mod1\-f
+Sets floating layout.
+.TP
+.B Mod1\-m
+Sets monocle layout.
+.TP
+.B Mod1\-space
+Toggles between current and previous layout.
+.TP
+.B Mod1\-j
+Focus next window.
+.TP
+.B Mod1\-k
+Focus previous window.
+.TP
+.B Mod1\-i
+Increase number of windows in master area.
+.TP
+.B Mod1\-d
+Decrease number of windows in master area.
+.TP
+.B Mod1\-l
+Increase master area size.
+.TP
+.B Mod1\-h
+Decrease master area size.
+.TP
+.B Mod1\-Return
+Zooms/cycles focused window to/from master area (tiled layouts only).
+.TP
+.B Mod1\-Shift\-c
+Close focused window.
+.TP
+.B Mod1\-Shift\-space
+Toggle focused window between tiled and floating state.
+.TP
+.B Mod1\-Tab
+Toggles to the previously selected tags.
+.TP
+.B Mod1\-Shift\-[1..n]
+Apply nth tag to focused window.
+.TP
+.B Mod1\-Shift\-0
+Apply all tags to focused window.
+.TP
+.B Mod1\-Control\-Shift\-[1..n]
+Add/remove nth tag to/from focused window.
+.TP
+.B Mod1\-[1..n]
+View all windows with nth tag.
+.TP
+.B Mod1\-0
+View all windows with any tag.
+.TP
+.B Mod1\-Control\-[1..n]
+Add/remove all windows with nth tag to/from the view.
+.TP
+.B Mod1\-Shift\-q
+Quit dwm.
+.SS Mouse commands
+.TP
+.B Mod1\-Button1
+Move focused window while dragging. Tiled windows will be toggled to the floating state.
+.TP
+.B Mod1\-Button2
+Toggles focused window between floating and tiled state.
+.TP
+.B Mod1\-Button3
+Resize focused window while dragging. Tiled windows will be toggled to the floating state.
+.SH CUSTOMIZATION
+dwm is customized by creating a custom config.h and (re)compiling the source
+code. This keeps it fast, secure and simple.
+.SH SEE ALSO
+.BR dmenu (1),
+.BR st (1)
+.SH ISSUES
+Java applications which use the XToolkit/XAWT backend may draw grey windows
+only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
+JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
+are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
+environment variable
+.BR AWT_TOOLKIT=MToolkit
+(to use the older Motif backend instead) or running
+.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
+or
+.B wmname LG3D
+(to pretend that a non-reparenting window manager is running that the
+XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
+.BR _JAVA_AWT_WM_NONREPARENTING=1 .
+.SH BUGS
+Send all bug reports with a patch to hackers@suckless.org.
diff --git a/home/kurb42/.config/suckless/dwm/dwm.c b/home/kurb42/.config/suckless/dwm/dwm.c
new file mode 100644
index 0000000..3bad326
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/dwm.c
@@ -0,0 +1,2139 @@
+/* See LICENSE file for copyright and license details.
+ *
+ * dynamic window manager is designed like any other X client as well. It is
+ * driven through handling X events. In contrast to other X clients, a window
+ * manager selects for SubstructureRedirectMask on the root window, to receive
+ * events about window (dis-)appearance. Only one X connection at a time is
+ * allowed to select for this event mask.
+ *
+ * The event handlers of dwm are organized in an array which is accessed
+ * whenever a new event has been fetched. This allows event dispatching
+ * in O(1) time.
+ *
+ * Each child of the root window is called a client, except windows which have
+ * set the override_redirect flag. Clients are organized in a linked client
+ * list on each monitor, the focus history is remembered through a stack list
+ * on each monitor. Each client contains a bit array to indicate the tags of a
+ * client.
+ *
+ * Keys and tagging rules are organized as arrays and defined in config.h.
+ *
+ * To understand everything else, start reading main().
+ */
+#include <errno.h>
+#include <locale.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
+#ifdef XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif /* XINERAMA */
+#include <X11/Xft/Xft.h>
+
+#include "drw.h"
+#include "util.h"
+
+/* macros */
+#define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
+#define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
+#define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
+                               * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
+#define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
+#define LENGTH(X)               (sizeof X / sizeof X[0])
+#define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+#define WIDTH(X)                ((X)->w + 2 * (X)->bw)
+#define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
+#define TAGMASK                 ((1 << LENGTH(tags)) - 1)
+#define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
+
+/* enums */
+enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+enum { SchemeNorm, SchemeSel }; /* color schemes */
+enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+       NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+       NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+       ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+
+typedef union {
+	int i;
+	unsigned int ui;
+	float f;
+	const void *v;
+} Arg;
+
+typedef struct {
+	unsigned int click;
+	unsigned int mask;
+	unsigned int button;
+	void (*func)(const Arg *arg);
+	const Arg arg;
+} Button;
+
+typedef struct Monitor Monitor;
+typedef struct Client Client;
+struct Client {
+	char name[256];
+	float mina, maxa;
+	int x, y, w, h;
+	int oldx, oldy, oldw, oldh;
+	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+	int bw, oldbw;
+	unsigned int tags;
+	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+	Client *next;
+	Client *snext;
+	Monitor *mon;
+	Window win;
+};
+
+typedef struct {
+	unsigned int mod;
+	KeySym keysym;
+	void (*func)(const Arg *);
+	const Arg arg;
+} Key;
+
+typedef struct {
+	const char *symbol;
+	void (*arrange)(Monitor *);
+} Layout;
+
+struct Monitor {
+	char ltsymbol[16];
+	float mfact;
+	int nmaster;
+	int num;
+	int by;               /* bar geometry */
+	int mx, my, mw, mh;   /* screen size */
+	int wx, wy, ww, wh;   /* window area  */
+	unsigned int seltags;
+	unsigned int sellt;
+	unsigned int tagset[2];
+	int showbar;
+	int topbar;
+	Client *clients;
+	Client *sel;
+	Client *stack;
+	Monitor *next;
+	Window barwin;
+	const Layout *lt[2];
+};
+
+typedef struct {
+	const char *class;
+	const char *instance;
+	const char *title;
+	unsigned int tags;
+	int isfloating;
+	int monitor;
+} Rule;
+
+/* function declarations */
+static void applyrules(Client *c);
+static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
+static void arrange(Monitor *m);
+static void arrangemon(Monitor *m);
+static void attach(Client *c);
+static void attachstack(Client *c);
+static void buttonpress(XEvent *e);
+static void checkotherwm(void);
+static void cleanup(void);
+static void cleanupmon(Monitor *mon);
+static void clientmessage(XEvent *e);
+static void configure(Client *c);
+static void configurenotify(XEvent *e);
+static void configurerequest(XEvent *e);
+static Monitor *createmon(void);
+static void destroynotify(XEvent *e);
+static void detach(Client *c);
+static void detachstack(Client *c);
+static Monitor *dirtomon(int dir);
+static void drawbar(Monitor *m);
+static void drawbars(void);
+static void enternotify(XEvent *e);
+static void expose(XEvent *e);
+static void focus(Client *c);
+static void focusin(XEvent *e);
+static void focusmon(const Arg *arg);
+static void focusstack(const Arg *arg);
+static int getrootptr(int *x, int *y);
+static long getstate(Window w);
+static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+static void grabbuttons(Client *c, int focused);
+static void grabkeys(void);
+static void incnmaster(const Arg *arg);
+static void keypress(XEvent *e);
+static void killclient(const Arg *arg);
+static void manage(Window w, XWindowAttributes *wa);
+static void mappingnotify(XEvent *e);
+static void maprequest(XEvent *e);
+static void monocle(Monitor *m);
+static void motionnotify(XEvent *e);
+static void movemouse(const Arg *arg);
+static Client *nexttiled(Client *c);
+static void pop(Client *);
+static void propertynotify(XEvent *e);
+static void quit(const Arg *arg);
+static Monitor *recttomon(int x, int y, int w, int h);
+static void resize(Client *c, int x, int y, int w, int h, int interact);
+static void resizeclient(Client *c, int x, int y, int w, int h);
+static void resizemouse(const Arg *arg);
+static void restack(Monitor *m);
+static void run(void);
+static void scan(void);
+static int sendevent(Client *c, Atom proto);
+static void sendmon(Client *c, Monitor *m);
+static void setclientstate(Client *c, long state);
+static void setfocus(Client *c);
+static void setfullscreen(Client *c, int fullscreen);
+static void setlayout(const Arg *arg);
+static void setmfact(const Arg *arg);
+static void setup(void);
+static void seturgent(Client *c, int urg);
+static void showhide(Client *c);
+static void sigchld(int unused);
+static void spawn(const Arg *arg);
+static void tag(const Arg *arg);
+static void tagmon(const Arg *arg);
+static void tile(Monitor *);
+static void togglebar(const Arg *arg);
+static void togglefloating(const Arg *arg);
+static void toggletag(const Arg *arg);
+static void toggleview(const Arg *arg);
+static void unfocus(Client *c, int setfocus);
+static void unmanage(Client *c, int destroyed);
+static void unmapnotify(XEvent *e);
+static void updatebarpos(Monitor *m);
+static void updatebars(void);
+static void updateclientlist(void);
+static int updategeom(void);
+static void updatenumlockmask(void);
+static void updatesizehints(Client *c);
+static void updatetitle(Client *c);
+static void updatewindowtype(Client *c);
+static void updatewmhints(Client *c);
+static void view(const Arg *arg);
+static Client *wintoclient(Window w);
+static Monitor *wintomon(Window w);
+static int xerror(Display *dpy, XErrorEvent *ee);
+static int xerrordummy(Display *dpy, XErrorEvent *ee);
+static int xerrorstart(Display *dpy, XErrorEvent *ee);
+static void zoom(const Arg *arg);
+
+/* variables */
+static const char broken[] = "broken";
+static char stext[256];
+static int screen;
+static int sw, sh;           /* X display screen geometry width, height */
+static int bh, blw = 0;      /* bar geometry */
+static int lrpad;            /* sum of left and right padding for text */
+static int (*xerrorxlib)(Display *, XErrorEvent *);
+static unsigned int numlockmask = 0;
+static void (*handler[LASTEvent]) (XEvent *) = {
+	[ButtonPress] = buttonpress,
+	[ClientMessage] = clientmessage,
+	[ConfigureRequest] = configurerequest,
+	[ConfigureNotify] = configurenotify,
+	[DestroyNotify] = destroynotify,
+	[EnterNotify] = enternotify,
+	[Expose] = expose,
+	[FocusIn] = focusin,
+	[KeyPress] = keypress,
+	[MappingNotify] = mappingnotify,
+	[MapRequest] = maprequest,
+	[MotionNotify] = motionnotify,
+	[PropertyNotify] = propertynotify,
+	[UnmapNotify] = unmapnotify
+};
+static Atom wmatom[WMLast], netatom[NetLast];
+static int running = 1;
+static Cur *cursor[CurLast];
+static Clr **scheme;
+static Display *dpy;
+static Drw *drw;
+static Monitor *mons, *selmon;
+static Window root, wmcheckwin;
+
+/* configuration, allows nested code to access above variables */
+#include "config.h"
+
+/* compile-time check if all tags fit into an unsigned int bit array. */
+struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+
+/* function implementations */
+void
+applyrules(Client *c)
+{
+	const char *class, *instance;
+	unsigned int i;
+	const Rule *r;
+	Monitor *m;
+	XClassHint ch = { NULL, NULL };
+
+	/* rule matching */
+	c->isfloating = 0;
+	c->tags = 0;
+	XGetClassHint(dpy, c->win, &ch);
+	class    = ch.res_class ? ch.res_class : broken;
+	instance = ch.res_name  ? ch.res_name  : broken;
+
+	for (i = 0; i < LENGTH(rules); i++) {
+		r = &rules[i];
+		if ((!r->title || strstr(c->name, r->title))
+		&& (!r->class || strstr(class, r->class))
+		&& (!r->instance || strstr(instance, r->instance)))
+		{
+			c->isfloating = r->isfloating;
+			c->tags |= r->tags;
+			for (m = mons; m && m->num != r->monitor; m = m->next);
+			if (m)
+				c->mon = m;
+		}
+	}
+	if (ch.res_class)
+		XFree(ch.res_class);
+	if (ch.res_name)
+		XFree(ch.res_name);
+	c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
+}
+
+int
+applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
+{
+	int baseismin;
+	Monitor *m = c->mon;
+
+	/* set minimum possible */
+	*w = MAX(1, *w);
+	*h = MAX(1, *h);
+	if (interact) {
+		if (*x > sw)
+			*x = sw - WIDTH(c);
+		if (*y > sh)
+			*y = sh - HEIGHT(c);
+		if (*x + *w + 2 * c->bw < 0)
+			*x = 0;
+		if (*y + *h + 2 * c->bw < 0)
+			*y = 0;
+	} else {
+		if (*x >= m->wx + m->ww)
+			*x = m->wx + m->ww - WIDTH(c);
+		if (*y >= m->wy + m->wh)
+			*y = m->wy + m->wh - HEIGHT(c);
+		if (*x + *w + 2 * c->bw <= m->wx)
+			*x = m->wx;
+		if (*y + *h + 2 * c->bw <= m->wy)
+			*y = m->wy;
+	}
+	if (*h < bh)
+		*h = bh;
+	if (*w < bh)
+		*w = bh;
+	if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
+		/* see last two sentences in ICCCM 4.1.2.3 */
+		baseismin = c->basew == c->minw && c->baseh == c->minh;
+		if (!baseismin) { /* temporarily remove base dimensions */
+			*w -= c->basew;
+			*h -= c->baseh;
+		}
+		/* adjust for aspect limits */
+		if (c->mina > 0 && c->maxa > 0) {
+			if (c->maxa < (float)*w / *h)
+				*w = *h * c->maxa + 0.5;
+			else if (c->mina < (float)*h / *w)
+				*h = *w * c->mina + 0.5;
+		}
+		if (baseismin) { /* increment calculation requires this */
+			*w -= c->basew;
+			*h -= c->baseh;
+		}
+		/* adjust for increment value */
+		if (c->incw)
+			*w -= *w % c->incw;
+		if (c->inch)
+			*h -= *h % c->inch;
+		/* restore base dimensions */
+		*w = MAX(*w + c->basew, c->minw);
+		*h = MAX(*h + c->baseh, c->minh);
+		if (c->maxw)
+			*w = MIN(*w, c->maxw);
+		if (c->maxh)
+			*h = MIN(*h, c->maxh);
+	}
+	return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
+}
+
+void
+arrange(Monitor *m)
+{
+	if (m)
+		showhide(m->stack);
+	else for (m = mons; m; m = m->next)
+		showhide(m->stack);
+	if (m) {
+		arrangemon(m);
+		restack(m);
+	} else for (m = mons; m; m = m->next)
+		arrangemon(m);
+}
+
+void
+arrangemon(Monitor *m)
+{
+	strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
+	if (m->lt[m->sellt]->arrange)
+		m->lt[m->sellt]->arrange(m);
+}
+
+void
+attach(Client *c)
+{
+	c->next = c->mon->clients;
+	c->mon->clients = c;
+}
+
+void
+attachstack(Client *c)
+{
+	c->snext = c->mon->stack;
+	c->mon->stack = c;
+}
+
+void
+buttonpress(XEvent *e)
+{
+	unsigned int i, x, click;
+	Arg arg = {0};
+	Client *c;
+	Monitor *m;
+	XButtonPressedEvent *ev = &e->xbutton;
+
+	click = ClkRootWin;
+	/* focus monitor if necessary */
+	if ((m = wintomon(ev->window)) && m != selmon) {
+		unfocus(selmon->sel, 1);
+		selmon = m;
+		focus(NULL);
+	}
+	if (ev->window == selmon->barwin) {
+		i = x = 0;
+		do
+			x += TEXTW(tags[i]);
+		while (ev->x >= x && ++i < LENGTH(tags));
+		if (i < LENGTH(tags)) {
+			click = ClkTagBar;
+			arg.ui = 1 << i;
+		} else if (ev->x < x + blw)
+			click = ClkLtSymbol;
+		else if (ev->x > selmon->ww - TEXTW(stext))
+			click = ClkStatusText;
+		else
+			click = ClkWinTitle;
+	} else if ((c = wintoclient(ev->window))) {
+		focus(c);
+		restack(selmon);
+		XAllowEvents(dpy, ReplayPointer, CurrentTime);
+		click = ClkClientWin;
+	}
+	for (i = 0; i < LENGTH(buttons); i++)
+		if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
+		&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
+			buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
+}
+
+void
+checkotherwm(void)
+{
+	xerrorxlib = XSetErrorHandler(xerrorstart);
+	/* this causes an error if some other window manager is running */
+	XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
+	XSync(dpy, False);
+	XSetErrorHandler(xerror);
+	XSync(dpy, False);
+}
+
+void
+cleanup(void)
+{
+	Arg a = {.ui = ~0};
+	Layout foo = { "", NULL };
+	Monitor *m;
+	size_t i;
+
+	view(&a);
+	selmon->lt[selmon->sellt] = &foo;
+	for (m = mons; m; m = m->next)
+		while (m->stack)
+			unmanage(m->stack, 0);
+	XUngrabKey(dpy, AnyKey, AnyModifier, root);
+	while (mons)
+		cleanupmon(mons);
+	for (i = 0; i < CurLast; i++)
+		drw_cur_free(drw, cursor[i]);
+	for (i = 0; i < LENGTH(colors); i++)
+		free(scheme[i]);
+	XDestroyWindow(dpy, wmcheckwin);
+	drw_free(drw);
+	XSync(dpy, False);
+	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
+	XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+}
+
+void
+cleanupmon(Monitor *mon)
+{
+	Monitor *m;
+
+	if (mon == mons)
+		mons = mons->next;
+	else {
+		for (m = mons; m && m->next != mon; m = m->next);
+		m->next = mon->next;
+	}
+	XUnmapWindow(dpy, mon->barwin);
+	XDestroyWindow(dpy, mon->barwin);
+	free(mon);
+}
+
+void
+clientmessage(XEvent *e)
+{
+	XClientMessageEvent *cme = &e->xclient;
+	Client *c = wintoclient(cme->window);
+
+	if (!c)
+		return;
+	if (cme->message_type == netatom[NetWMState]) {
+		if (cme->data.l[1] == netatom[NetWMFullscreen]
+		|| cme->data.l[2] == netatom[NetWMFullscreen])
+			setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD    */
+				|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
+	} else if (cme->message_type == netatom[NetActiveWindow]) {
+		if (c != selmon->sel && !c->isurgent)
+			seturgent(c, 1);
+	}
+}
+
+void
+configure(Client *c)
+{
+	XConfigureEvent ce;
+
+	ce.type = ConfigureNotify;
+	ce.display = dpy;
+	ce.event = c->win;
+	ce.window = c->win;
+	ce.x = c->x;
+	ce.y = c->y;
+	ce.width = c->w;
+	ce.height = c->h;
+	ce.border_width = c->bw;
+	ce.above = None;
+	ce.override_redirect = False;
+	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
+}
+
+void
+configurenotify(XEvent *e)
+{
+	Monitor *m;
+	Client *c;
+	XConfigureEvent *ev = &e->xconfigure;
+	int dirty;
+
+	/* TODO: updategeom handling sucks, needs to be simplified */
+	if (ev->window == root) {
+		dirty = (sw != ev->width || sh != ev->height);
+		sw = ev->width;
+		sh = ev->height;
+		if (updategeom() || dirty) {
+			drw_resize(drw, sw, bh);
+			updatebars();
+			for (m = mons; m; m = m->next) {
+				for (c = m->clients; c; c = c->next)
+					if (c->isfullscreen)
+						resizeclient(c, m->mx, m->my, m->mw, m->mh);
+				XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+			}
+			focus(NULL);
+			arrange(NULL);
+		}
+	}
+}
+
+void
+configurerequest(XEvent *e)
+{
+	Client *c;
+	Monitor *m;
+	XConfigureRequestEvent *ev = &e->xconfigurerequest;
+	XWindowChanges wc;
+
+	if ((c = wintoclient(ev->window))) {
+		if (ev->value_mask & CWBorderWidth)
+			c->bw = ev->border_width;
+		else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
+			m = c->mon;
+			if (ev->value_mask & CWX) {
+				c->oldx = c->x;
+				c->x = m->mx + ev->x;
+			}
+			if (ev->value_mask & CWY) {
+				c->oldy = c->y;
+				c->y = m->my + ev->y;
+			}
+			if (ev->value_mask & CWWidth) {
+				c->oldw = c->w;
+				c->w = ev->width;
+			}
+			if (ev->value_mask & CWHeight) {
+				c->oldh = c->h;
+				c->h = ev->height;
+			}
+			if ((c->x + c->w) > m->mx + m->mw && c->isfloating)
+				c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */
+			if ((c->y + c->h) > m->my + m->mh && c->isfloating)
+				c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */
+			if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
+				configure(c);
+			if (ISVISIBLE(c))
+				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
+		} else
+			configure(c);
+	} else {
+		wc.x = ev->x;
+		wc.y = ev->y;
+		wc.width = ev->width;
+		wc.height = ev->height;
+		wc.border_width = ev->border_width;
+		wc.sibling = ev->above;
+		wc.stack_mode = ev->detail;
+		XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
+	}
+	XSync(dpy, False);
+}
+
+Monitor *
+createmon(void)
+{
+	Monitor *m;
+
+	m = ecalloc(1, sizeof(Monitor));
+	m->tagset[0] = m->tagset[1] = 1;
+	m->mfact = mfact;
+	m->nmaster = nmaster;
+	m->showbar = showbar;
+	m->topbar = topbar;
+	m->lt[0] = &layouts[0];
+	m->lt[1] = &layouts[1 % LENGTH(layouts)];
+	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+	return m;
+}
+
+void
+destroynotify(XEvent *e)
+{
+	Client *c;
+	XDestroyWindowEvent *ev = &e->xdestroywindow;
+
+	if ((c = wintoclient(ev->window)))
+		unmanage(c, 1);
+}
+
+void
+detach(Client *c)
+{
+	Client **tc;
+
+	for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
+	*tc = c->next;
+}
+
+void
+detachstack(Client *c)
+{
+	Client **tc, *t;
+
+	for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
+	*tc = c->snext;
+
+	if (c == c->mon->sel) {
+		for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
+		c->mon->sel = t;
+	}
+}
+
+Monitor *
+dirtomon(int dir)
+{
+	Monitor *m = NULL;
+
+	if (dir > 0) {
+		if (!(m = selmon->next))
+			m = mons;
+	} else if (selmon == mons)
+		for (m = mons; m->next; m = m->next);
+	else
+		for (m = mons; m->next != selmon; m = m->next);
+	return m;
+}
+
+void
+drawbar(Monitor *m)
+{
+	int x, w, sw = 0;
+	int boxs = drw->fonts->h / 9;
+	int boxw = drw->fonts->h / 6 + 2;
+	unsigned int i, occ = 0, urg = 0;
+	Client *c;
+
+	/* draw status first so it can be overdrawn by tags later */
+	if (m == selmon) { /* status is only drawn on selected monitor */
+		drw_setscheme(drw, scheme[SchemeNorm]);
+		sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+		drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
+	}
+
+	for (c = m->clients; c; c = c->next) {
+		occ |= c->tags;
+		if (c->isurgent)
+			urg |= c->tags;
+	}
+	x = 0;
+	for (i = 0; i < LENGTH(tags); i++) {
+		w = TEXTW(tags[i]);
+		drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+		drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+		if (occ & 1 << i)
+			drw_rect(drw, x + boxs, boxs, boxw, boxw,
+				m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+				urg & 1 << i);
+		x += w;
+	}
+	w = blw = TEXTW(m->ltsymbol);
+	drw_setscheme(drw, scheme[SchemeNorm]);
+	x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+
+	if ((w = m->ww - sw - x) > bh) {
+		if (m->sel) {
+			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+			drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+			if (m->sel->isfloating)
+				drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+		} else {
+			drw_setscheme(drw, scheme[SchemeNorm]);
+			drw_rect(drw, x, 0, w, bh, 1, 1);
+		}
+	}
+	drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+}
+
+void
+drawbars(void)
+{
+	Monitor *m;
+
+	for (m = mons; m; m = m->next)
+		drawbar(m);
+}
+
+void
+enternotify(XEvent *e)
+{
+	Client *c;
+	Monitor *m;
+	XCrossingEvent *ev = &e->xcrossing;
+
+	if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
+		return;
+	c = wintoclient(ev->window);
+	m = c ? c->mon : wintomon(ev->window);
+	if (m != selmon) {
+		unfocus(selmon->sel, 1);
+		selmon = m;
+	} else if (!c || c == selmon->sel)
+		return;
+	focus(c);
+}
+
+void
+expose(XEvent *e)
+{
+	Monitor *m;
+	XExposeEvent *ev = &e->xexpose;
+
+	if (ev->count == 0 && (m = wintomon(ev->window)))
+		drawbar(m);
+}
+
+void
+focus(Client *c)
+{
+	if (!c || !ISVISIBLE(c))
+		for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
+	if (selmon->sel && selmon->sel != c)
+		unfocus(selmon->sel, 0);
+	if (c) {
+		if (c->mon != selmon)
+			selmon = c->mon;
+		if (c->isurgent)
+			seturgent(c, 0);
+		detachstack(c);
+		attachstack(c);
+		grabbuttons(c, 1);
+		XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
+		setfocus(c);
+	} else {
+		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+	}
+	selmon->sel = c;
+	drawbars();
+}
+
+/* there are some broken focus acquiring clients needing extra handling */
+void
+focusin(XEvent *e)
+{
+	XFocusChangeEvent *ev = &e->xfocus;
+
+	if (selmon->sel && ev->window != selmon->sel->win)
+		setfocus(selmon->sel);
+}
+
+void
+focusmon(const Arg *arg)
+{
+	Monitor *m;
+
+	if (!mons->next)
+		return;
+	if ((m = dirtomon(arg->i)) == selmon)
+		return;
+	unfocus(selmon->sel, 0);
+	selmon = m;
+	focus(NULL);
+}
+
+void
+focusstack(const Arg *arg)
+{
+	Client *c = NULL, *i;
+
+	if (!selmon->sel)
+		return;
+	if (arg->i > 0) {
+		for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
+		if (!c)
+			for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
+	} else {
+		for (i = selmon->clients; i != selmon->sel; i = i->next)
+			if (ISVISIBLE(i))
+				c = i;
+		if (!c)
+			for (; i; i = i->next)
+				if (ISVISIBLE(i))
+					c = i;
+	}
+	if (c) {
+		focus(c);
+		restack(selmon);
+	}
+}
+
+Atom
+getatomprop(Client *c, Atom prop)
+{
+	int di;
+	unsigned long dl;
+	unsigned char *p = NULL;
+	Atom da, atom = None;
+
+	if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
+		&da, &di, &dl, &dl, &p) == Success && p) {
+		atom = *(Atom *)p;
+		XFree(p);
+	}
+	return atom;
+}
+
+int
+getrootptr(int *x, int *y)
+{
+	int di;
+	unsigned int dui;
+	Window dummy;
+
+	return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
+}
+
+long
+getstate(Window w)
+{
+	int format;
+	long result = -1;
+	unsigned char *p = NULL;
+	unsigned long n, extra;
+	Atom real;
+
+	if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
+		&real, &format, &n, &extra, (unsigned char **)&p) != Success)
+		return -1;
+	if (n != 0)
+		result = *p;
+	XFree(p);
+	return result;
+}
+
+int
+gettextprop(Window w, Atom atom, char *text, unsigned int size)
+{
+	char **list = NULL;
+	int n;
+	XTextProperty name;
+
+	if (!text || size == 0)
+		return 0;
+	text[0] = '\0';
+	if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
+		return 0;
+	if (name.encoding == XA_STRING)
+		strncpy(text, (char *)name.value, size - 1);
+	else {
+		if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
+			strncpy(text, *list, size - 1);
+			XFreeStringList(list);
+		}
+	}
+	text[size - 1] = '\0';
+	XFree(name.value);
+	return 1;
+}
+
+void
+grabbuttons(Client *c, int focused)
+{
+	updatenumlockmask();
+	{
+		unsigned int i, j;
+		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+		XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+		if (!focused)
+			XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
+				BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
+		for (i = 0; i < LENGTH(buttons); i++)
+			if (buttons[i].click == ClkClientWin)
+				for (j = 0; j < LENGTH(modifiers); j++)
+					XGrabButton(dpy, buttons[i].button,
+						buttons[i].mask | modifiers[j],
+						c->win, False, BUTTONMASK,
+						GrabModeAsync, GrabModeSync, None, None);
+	}
+}
+
+void
+grabkeys(void)
+{
+	updatenumlockmask();
+	{
+		unsigned int i, j;
+		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+		KeyCode code;
+
+		XUngrabKey(dpy, AnyKey, AnyModifier, root);
+		for (i = 0; i < LENGTH(keys); i++)
+			if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
+				for (j = 0; j < LENGTH(modifiers); j++)
+					XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
+						True, GrabModeAsync, GrabModeAsync);
+	}
+}
+
+void
+incnmaster(const Arg *arg)
+{
+	selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
+	arrange(selmon);
+}
+
+#ifdef XINERAMA
+static int
+isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
+{
+	while (n--)
+		if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
+		&& unique[n].width == info->width && unique[n].height == info->height)
+			return 0;
+	return 1;
+}
+#endif /* XINERAMA */
+
+void
+keypress(XEvent *e)
+{
+	unsigned int i;
+	KeySym keysym;
+	XKeyEvent *ev;
+
+	ev = &e->xkey;
+	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
+	for (i = 0; i < LENGTH(keys); i++)
+		if (keysym == keys[i].keysym
+		&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
+		&& keys[i].func)
+			keys[i].func(&(keys[i].arg));
+}
+
+void
+killclient(const Arg *arg)
+{
+	if (!selmon->sel)
+		return;
+	if (!sendevent(selmon->sel, wmatom[WMDelete])) {
+		XGrabServer(dpy);
+		XSetErrorHandler(xerrordummy);
+		XSetCloseDownMode(dpy, DestroyAll);
+		XKillClient(dpy, selmon->sel->win);
+		XSync(dpy, False);
+		XSetErrorHandler(xerror);
+		XUngrabServer(dpy);
+	}
+}
+
+void
+manage(Window w, XWindowAttributes *wa)
+{
+	Client *c, *t = NULL;
+	Window trans = None;
+	XWindowChanges wc;
+
+	c = ecalloc(1, sizeof(Client));
+	c->win = w;
+	/* geometry */
+	c->x = c->oldx = wa->x;
+	c->y = c->oldy = wa->y;
+	c->w = c->oldw = wa->width;
+	c->h = c->oldh = wa->height;
+	c->oldbw = wa->border_width;
+
+	updatetitle(c);
+	if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
+		c->mon = t->mon;
+		c->tags = t->tags;
+	} else {
+		c->mon = selmon;
+		applyrules(c);
+	}
+
+	if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
+		c->x = c->mon->mx + c->mon->mw - WIDTH(c);
+	if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
+		c->y = c->mon->my + c->mon->mh - HEIGHT(c);
+	c->x = MAX(c->x, c->mon->mx);
+	/* only fix client y-offset, if the client center might cover the bar */
+	c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
+		&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
+	c->bw = borderpx;
+
+	wc.border_width = c->bw;
+	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+	XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
+	configure(c); /* propagates border_width, if size doesn't change */
+	updatewindowtype(c);
+	updatesizehints(c);
+	updatewmhints(c);
+	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+	grabbuttons(c, 0);
+	if (!c->isfloating)
+		c->isfloating = c->oldstate = trans != None || c->isfixed;
+	if (c->isfloating)
+		XRaiseWindow(dpy, c->win);
+	attach(c);
+	attachstack(c);
+	XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
+		(unsigned char *) &(c->win), 1);
+	XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
+	setclientstate(c, NormalState);
+	if (c->mon == selmon)
+		unfocus(selmon->sel, 0);
+	c->mon->sel = c;
+	arrange(c->mon);
+	XMapWindow(dpy, c->win);
+	focus(NULL);
+}
+
+void
+mappingnotify(XEvent *e)
+{
+	XMappingEvent *ev = &e->xmapping;
+
+	XRefreshKeyboardMapping(ev);
+	if (ev->request == MappingKeyboard)
+		grabkeys();
+}
+
+void
+maprequest(XEvent *e)
+{
+	static XWindowAttributes wa;
+	XMapRequestEvent *ev = &e->xmaprequest;
+
+	if (!XGetWindowAttributes(dpy, ev->window, &wa))
+		return;
+	if (wa.override_redirect)
+		return;
+	if (!wintoclient(ev->window))
+		manage(ev->window, &wa);
+}
+
+void
+monocle(Monitor *m)
+{
+	unsigned int n = 0;
+	Client *c;
+
+	for (c = m->clients; c; c = c->next)
+		if (ISVISIBLE(c))
+			n++;
+	if (n > 0) /* override layout symbol */
+		snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
+	for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
+		resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
+}
+
+void
+motionnotify(XEvent *e)
+{
+	static Monitor *mon = NULL;
+	Monitor *m;
+	XMotionEvent *ev = &e->xmotion;
+
+	if (ev->window != root)
+		return;
+	if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
+		unfocus(selmon->sel, 1);
+		selmon = m;
+		focus(NULL);
+	}
+	mon = m;
+}
+
+void
+movemouse(const Arg *arg)
+{
+	int x, y, ocx, ocy, nx, ny;
+	Client *c;
+	Monitor *m;
+	XEvent ev;
+	Time lasttime = 0;
+
+	if (!(c = selmon->sel))
+		return;
+	if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
+		return;
+	restack(selmon);
+	ocx = c->x;
+	ocy = c->y;
+	if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+		None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
+		return;
+	if (!getrootptr(&x, &y))
+		return;
+	do {
+		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+		switch(ev.type) {
+		case ConfigureRequest:
+		case Expose:
+		case MapRequest:
+			handler[ev.type](&ev);
+			break;
+		case MotionNotify:
+			if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+				continue;
+			lasttime = ev.xmotion.time;
+
+			nx = ocx + (ev.xmotion.x - x);
+			ny = ocy + (ev.xmotion.y - y);
+			if (abs(selmon->wx - nx) < snap)
+				nx = selmon->wx;
+			else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
+				nx = selmon->wx + selmon->ww - WIDTH(c);
+			if (abs(selmon->wy - ny) < snap)
+				ny = selmon->wy;
+			else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
+				ny = selmon->wy + selmon->wh - HEIGHT(c);
+			if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
+			&& (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
+				togglefloating(NULL);
+			if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
+				resize(c, nx, ny, c->w, c->h, 1);
+			break;
+		}
+	} while (ev.type != ButtonRelease);
+	XUngrabPointer(dpy, CurrentTime);
+	if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
+		sendmon(c, m);
+		selmon = m;
+		focus(NULL);
+	}
+}
+
+Client *
+nexttiled(Client *c)
+{
+	for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
+	return c;
+}
+
+void
+pop(Client *c)
+{
+	detach(c);
+	attach(c);
+	focus(c);
+	arrange(c->mon);
+}
+
+void
+propertynotify(XEvent *e)
+{
+	Client *c;
+	Window trans;
+	XPropertyEvent *ev = &e->xproperty;
+
+	if ((ev->window == root) && (ev->atom == XA_WM_NAME))
+		return; /* ignore */
+	else if (ev->state == PropertyDelete)
+		return; /* ignore */
+	else if ((c = wintoclient(ev->window))) {
+		switch(ev->atom) {
+		default: break;
+		case XA_WM_TRANSIENT_FOR:
+			if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) &&
+				(c->isfloating = (wintoclient(trans)) != NULL))
+				arrange(c->mon);
+			break;
+		case XA_WM_NORMAL_HINTS:
+			updatesizehints(c);
+			break;
+		case XA_WM_HINTS:
+			updatewmhints(c);
+			drawbars();
+			break;
+		}
+		if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
+			updatetitle(c);
+			if (c == c->mon->sel)
+				drawbar(c->mon);
+		}
+		if (ev->atom == netatom[NetWMWindowType])
+			updatewindowtype(c);
+	}
+}
+
+void
+quit(const Arg *arg)
+{
+	running = 0;
+}
+
+Monitor *
+recttomon(int x, int y, int w, int h)
+{
+	Monitor *m, *r = selmon;
+	int a, area = 0;
+
+	for (m = mons; m; m = m->next)
+		if ((a = INTERSECT(x, y, w, h, m)) > area) {
+			area = a;
+			r = m;
+		}
+	return r;
+}
+
+void
+resize(Client *c, int x, int y, int w, int h, int interact)
+{
+	if (applysizehints(c, &x, &y, &w, &h, interact))
+		resizeclient(c, x, y, w, h);
+}
+
+void
+resizeclient(Client *c, int x, int y, int w, int h)
+{
+	XWindowChanges wc;
+
+	c->oldx = c->x; c->x = wc.x = x;
+	c->oldy = c->y; c->y = wc.y = y;
+	c->oldw = c->w; c->w = wc.width = w;
+	c->oldh = c->h; c->h = wc.height = h;
+	wc.border_width = c->bw;
+	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+	configure(c);
+	XSync(dpy, False);
+}
+
+void
+resizemouse(const Arg *arg)
+{
+	int ocx, ocy, nw, nh;
+	Client *c;
+	Monitor *m;
+	XEvent ev;
+	Time lasttime = 0;
+
+	if (!(c = selmon->sel))
+		return;
+	if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
+		return;
+	restack(selmon);
+	ocx = c->x;
+	ocy = c->y;
+	if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+		None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
+		return;
+	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+	do {
+		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+		switch(ev.type) {
+		case ConfigureRequest:
+		case Expose:
+		case MapRequest:
+			handler[ev.type](&ev);
+			break;
+		case MotionNotify:
+			if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+				continue;
+			lasttime = ev.xmotion.time;
+
+			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
+			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
+			if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
+			&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
+			{
+				if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
+				&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
+					togglefloating(NULL);
+			}
+			if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
+				resize(c, c->x, c->y, nw, nh, 1);
+			break;
+		}
+	} while (ev.type != ButtonRelease);
+	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+	XUngrabPointer(dpy, CurrentTime);
+	while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+	if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
+		sendmon(c, m);
+		selmon = m;
+		focus(NULL);
+	}
+}
+
+void
+restack(Monitor *m)
+{
+	Client *c;
+	XEvent ev;
+	XWindowChanges wc;
+
+	drawbar(m);
+	if (!m->sel)
+		return;
+	if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
+		XRaiseWindow(dpy, m->sel->win);
+	if (m->lt[m->sellt]->arrange) {
+		wc.stack_mode = Below;
+		wc.sibling = m->barwin;
+		for (c = m->stack; c; c = c->snext)
+			if (!c->isfloating && ISVISIBLE(c)) {
+				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
+				wc.sibling = c->win;
+			}
+	}
+	XSync(dpy, False);
+	while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+}
+
+void
+run(void)
+{
+	XEvent ev;
+	/* main event loop */
+	XSync(dpy, False);
+	while (running && !XNextEvent(dpy, &ev))
+		if (handler[ev.type])
+			handler[ev.type](&ev); /* call handler */
+}
+
+void
+scan(void)
+{
+	unsigned int i, num;
+	Window d1, d2, *wins = NULL;
+	XWindowAttributes wa;
+
+	if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
+		for (i = 0; i < num; i++) {
+			if (!XGetWindowAttributes(dpy, wins[i], &wa)
+			|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
+				continue;
+			if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
+				manage(wins[i], &wa);
+		}
+		for (i = 0; i < num; i++) { /* now the transients */
+			if (!XGetWindowAttributes(dpy, wins[i], &wa))
+				continue;
+			if (XGetTransientForHint(dpy, wins[i], &d1)
+			&& (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
+				manage(wins[i], &wa);
+		}
+		if (wins)
+			XFree(wins);
+	}
+}
+
+void
+sendmon(Client *c, Monitor *m)
+{
+	if (c->mon == m)
+		return;
+	unfocus(c, 1);
+	detach(c);
+	detachstack(c);
+	c->mon = m;
+	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+	attach(c);
+	attachstack(c);
+	focus(NULL);
+	arrange(NULL);
+}
+
+void
+setclientstate(Client *c, long state)
+{
+	long data[] = { state, None };
+
+	XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
+		PropModeReplace, (unsigned char *)data, 2);
+}
+
+int
+sendevent(Client *c, Atom proto)
+{
+	int n;
+	Atom *protocols;
+	int exists = 0;
+	XEvent ev;
+
+	if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
+		while (!exists && n--)
+			exists = protocols[n] == proto;
+		XFree(protocols);
+	}
+	if (exists) {
+		ev.type = ClientMessage;
+		ev.xclient.window = c->win;
+		ev.xclient.message_type = wmatom[WMProtocols];
+		ev.xclient.format = 32;
+		ev.xclient.data.l[0] = proto;
+		ev.xclient.data.l[1] = CurrentTime;
+		XSendEvent(dpy, c->win, False, NoEventMask, &ev);
+	}
+	return exists;
+}
+
+void
+setfocus(Client *c)
+{
+	if (!c->neverfocus) {
+		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+		XChangeProperty(dpy, root, netatom[NetActiveWindow],
+			XA_WINDOW, 32, PropModeReplace,
+			(unsigned char *) &(c->win), 1);
+	}
+	sendevent(c, wmatom[WMTakeFocus]);
+}
+
+void
+setfullscreen(Client *c, int fullscreen)
+{
+	if (fullscreen && !c->isfullscreen) {
+		XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
+			PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
+		c->isfullscreen = 1;
+		c->oldstate = c->isfloating;
+		c->oldbw = c->bw;
+		c->bw = 0;
+		c->isfloating = 1;
+		resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
+		XRaiseWindow(dpy, c->win);
+	} else if (!fullscreen && c->isfullscreen){
+		XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
+			PropModeReplace, (unsigned char*)0, 0);
+		c->isfullscreen = 0;
+		c->isfloating = c->oldstate;
+		c->bw = c->oldbw;
+		c->x = c->oldx;
+		c->y = c->oldy;
+		c->w = c->oldw;
+		c->h = c->oldh;
+		resizeclient(c, c->x, c->y, c->w, c->h);
+		arrange(c->mon);
+	}
+}
+
+void
+setlayout(const Arg *arg)
+{
+	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+		selmon->sellt ^= 1;
+	if (arg && arg->v)
+		selmon->lt[selmon->sellt] = (Layout *)arg->v;
+	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+	if (selmon->sel)
+		arrange(selmon);
+	else
+		drawbar(selmon);
+}
+
+/* arg > 1.0 will set mfact absolutely */
+void
+setmfact(const Arg *arg)
+{
+	float f;
+
+	if (!arg || !selmon->lt[selmon->sellt]->arrange)
+		return;
+	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
+	if (f < 0.1 || f > 0.9)
+		return;
+	selmon->mfact = f;
+	arrange(selmon);
+}
+
+void
+setup(void)
+{
+	int i;
+	XSetWindowAttributes wa;
+	Atom utf8string;
+
+	/* clean up any zombies immediately */
+	sigchld(0);
+
+	/* init screen */
+	screen = DefaultScreen(dpy);
+	sw = DisplayWidth(dpy, screen);
+	sh = DisplayHeight(dpy, screen);
+	root = RootWindow(dpy, screen);
+	drw = drw_create(dpy, screen, root, sw, sh);
+	if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+		die("no fonts could be loaded.");
+	lrpad = drw->fonts->h;
+	bh = drw->fonts->h + 2;
+	updategeom();
+	/* init atoms */
+	utf8string = XInternAtom(dpy, "UTF8_STRING", False);
+	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
+	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
+	wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+	netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
+	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
+	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
+	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
+	netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
+	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+	netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+	netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+	netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+	/* init cursors */
+	cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+	cursor[CurResize] = drw_cur_create(drw, XC_sizing);
+	cursor[CurMove] = drw_cur_create(drw, XC_fleur);
+	/* init appearance */
+	scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+	for (i = 0; i < LENGTH(colors); i++)
+		scheme[i] = drw_scm_create(drw, colors[i], 3);
+	/* init bars */
+	updatebars();
+	/* supporting window for NetWMCheck */
+	wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
+	XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
+		PropModeReplace, (unsigned char *) &wmcheckwin, 1);
+	XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
+		PropModeReplace, (unsigned char *) "dwm", 3);
+	XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
+		PropModeReplace, (unsigned char *) &wmcheckwin, 1);
+	/* EWMH support per view */
+	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
+		PropModeReplace, (unsigned char *) netatom, NetLast);
+	XDeleteProperty(dpy, root, netatom[NetClientList]);
+	/* select events */
+	wa.cursor = cursor[CurNormal]->cursor;
+	wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
+		|ButtonPressMask|PointerMotionMask|EnterWindowMask
+		|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
+	XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
+	XSelectInput(dpy, root, wa.event_mask);
+	grabkeys();
+	focus(NULL);
+}
+
+
+void
+seturgent(Client *c, int urg)
+{
+	XWMHints *wmh;
+
+	c->isurgent = urg;
+	if (!(wmh = XGetWMHints(dpy, c->win)))
+		return;
+	wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint);
+	XSetWMHints(dpy, c->win, wmh);
+	XFree(wmh);
+}
+
+void
+showhide(Client *c)
+{
+	if (!c)
+		return;
+	if (ISVISIBLE(c)) {
+		/* show clients top down */
+		XMoveWindow(dpy, c->win, c->x, c->y);
+		if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
+			resize(c, c->x, c->y, c->w, c->h, 0);
+		showhide(c->snext);
+	} else {
+		/* hide clients bottom up */
+		showhide(c->snext);
+		XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
+	}
+}
+
+void
+sigchld(int unused)
+{
+	if (signal(SIGCHLD, sigchld) == SIG_ERR)
+		die("can't install SIGCHLD handler:");
+	while (0 < waitpid(-1, NULL, WNOHANG));
+}
+
+void
+spawn(const Arg *arg)
+{
+	if (arg->v == dmenucmd)
+		dmenumon[0] = '0' + selmon->num;
+	if (fork() == 0) {
+		if (dpy)
+			close(ConnectionNumber(dpy));
+		setsid();
+		execvp(((char **)arg->v)[0], (char **)arg->v);
+		fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
+		perror(" failed");
+		exit(EXIT_SUCCESS);
+	}
+}
+
+void
+tag(const Arg *arg)
+{
+	if (selmon->sel && arg->ui & TAGMASK) {
+		selmon->sel->tags = arg->ui & TAGMASK;
+		focus(NULL);
+		arrange(selmon);
+	}
+}
+
+void
+tagmon(const Arg *arg)
+{
+	if (!selmon->sel || !mons->next)
+		return;
+	sendmon(selmon->sel, dirtomon(arg->i));
+}
+
+void
+tile(Monitor *m)
+{
+	unsigned int i, n, h, mw, my, ty;
+	Client *c;
+
+	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+	if (n == 0)
+		return;
+
+	if (n > m->nmaster)
+		mw = m->nmaster ? m->ww * m->mfact : 0;
+	else
+		mw = m->ww;
+	for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+		if (i < m->nmaster) {
+			h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+			resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
+			my += HEIGHT(c);
+		} else {
+			h = (m->wh - ty) / (n - i);
+			resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+			ty += HEIGHT(c);
+		}
+}
+
+void
+togglebar(const Arg *arg)
+{
+	selmon->showbar = !selmon->showbar;
+	updatebarpos(selmon);
+	XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+	arrange(selmon);
+}
+
+void
+togglefloating(const Arg *arg)
+{
+	if (!selmon->sel)
+		return;
+	if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
+		return;
+	selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
+	if (selmon->sel->isfloating)
+		resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+			selmon->sel->w, selmon->sel->h, 0);
+	arrange(selmon);
+}
+
+void
+toggletag(const Arg *arg)
+{
+	unsigned int newtags;
+
+	if (!selmon->sel)
+		return;
+	newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+	if (newtags) {
+		selmon->sel->tags = newtags;
+		focus(NULL);
+		arrange(selmon);
+	}
+}
+
+void
+toggleview(const Arg *arg)
+{
+	unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+
+	if (newtagset) {
+		selmon->tagset[selmon->seltags] = newtagset;
+		focus(NULL);
+		arrange(selmon);
+	}
+}
+
+void
+unfocus(Client *c, int setfocus)
+{
+	if (!c)
+		return;
+	grabbuttons(c, 0);
+	XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
+	if (setfocus) {
+		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+	}
+}
+
+void
+unmanage(Client *c, int destroyed)
+{
+	Monitor *m = c->mon;
+	XWindowChanges wc;
+
+	detach(c);
+	detachstack(c);
+	if (!destroyed) {
+		wc.border_width = c->oldbw;
+		XGrabServer(dpy); /* avoid race conditions */
+		XSetErrorHandler(xerrordummy);
+		XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
+		XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+		setclientstate(c, WithdrawnState);
+		XSync(dpy, False);
+		XSetErrorHandler(xerror);
+		XUngrabServer(dpy);
+	}
+	free(c);
+	focus(NULL);
+	updateclientlist();
+	arrange(m);
+}
+
+void
+unmapnotify(XEvent *e)
+{
+	Client *c;
+	XUnmapEvent *ev = &e->xunmap;
+
+	if ((c = wintoclient(ev->window))) {
+		if (ev->send_event)
+			setclientstate(c, WithdrawnState);
+		else
+			unmanage(c, 0);
+	}
+}
+
+void
+updatebars(void)
+{
+	Monitor *m;
+	XSetWindowAttributes wa = {
+		.override_redirect = True,
+		.background_pixmap = ParentRelative,
+		.event_mask = ButtonPressMask|ExposureMask
+	};
+	XClassHint ch = {"dwm", "dwm"};
+	for (m = mons; m; m = m->next) {
+		if (m->barwin)
+			continue;
+		m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+				CopyFromParent, DefaultVisual(dpy, screen),
+				CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+		XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+		XMapRaised(dpy, m->barwin);
+		XSetClassHint(dpy, m->barwin, &ch);
+	}
+}
+
+void
+updatebarpos(Monitor *m)
+{
+	m->wy = m->my;
+	m->wh = m->mh;
+	if (m->showbar) {
+		m->wh -= bh;
+		m->by = m->topbar ? m->wy : m->wy + m->wh;
+		m->wy = m->topbar ? m->wy + bh : m->wy;
+	} else
+		m->by = -bh;
+}
+
+void
+updateclientlist()
+{
+	Client *c;
+	Monitor *m;
+
+	XDeleteProperty(dpy, root, netatom[NetClientList]);
+	for (m = mons; m; m = m->next)
+		for (c = m->clients; c; c = c->next)
+			XChangeProperty(dpy, root, netatom[NetClientList],
+				XA_WINDOW, 32, PropModeAppend,
+				(unsigned char *) &(c->win), 1);
+}
+
+int
+updategeom(void)
+{
+	int dirty = 0;
+
+#ifdef XINERAMA
+	if (XineramaIsActive(dpy)) {
+		int i, j, n, nn;
+		Client *c;
+		Monitor *m;
+		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
+		XineramaScreenInfo *unique = NULL;
+
+		for (n = 0, m = mons; m; m = m->next, n++);
+		/* only consider unique geometries as separate screens */
+		unique = ecalloc(nn, sizeof(XineramaScreenInfo));
+		for (i = 0, j = 0; i < nn; i++)
+			if (isuniquegeom(unique, j, &info[i]))
+				memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
+		XFree(info);
+		nn = j;
+		if (n <= nn) { /* new monitors available */
+			for (i = 0; i < (nn - n); i++) {
+				for (m = mons; m && m->next; m = m->next);
+				if (m)
+					m->next = createmon();
+				else
+					mons = createmon();
+			}
+			for (i = 0, m = mons; i < nn && m; m = m->next, i++)
+				if (i >= n
+				|| unique[i].x_org != m->mx || unique[i].y_org != m->my
+				|| unique[i].width != m->mw || unique[i].height != m->mh)
+				{
+					dirty = 1;
+					m->num = i;
+					m->mx = m->wx = unique[i].x_org;
+					m->my = m->wy = unique[i].y_org;
+					m->mw = m->ww = unique[i].width;
+					m->mh = m->wh = unique[i].height;
+					updatebarpos(m);
+				}
+		} else { /* less monitors available nn < n */
+			for (i = nn; i < n; i++) {
+				for (m = mons; m && m->next; m = m->next);
+				while ((c = m->clients)) {
+					dirty = 1;
+					m->clients = c->next;
+					detachstack(c);
+					c->mon = mons;
+					attach(c);
+					attachstack(c);
+				}
+				if (m == selmon)
+					selmon = mons;
+				cleanupmon(m);
+			}
+		}
+		free(unique);
+	} else
+#endif /* XINERAMA */
+	{ /* default monitor setup */
+		if (!mons)
+			mons = createmon();
+		if (mons->mw != sw || mons->mh != sh) {
+			dirty = 1;
+			mons->mw = mons->ww = sw;
+			mons->mh = mons->wh = sh;
+			updatebarpos(mons);
+		}
+	}
+	if (dirty) {
+		selmon = mons;
+		selmon = wintomon(root);
+	}
+	return dirty;
+}
+
+void
+updatenumlockmask(void)
+{
+	unsigned int i, j;
+	XModifierKeymap *modmap;
+
+	numlockmask = 0;
+	modmap = XGetModifierMapping(dpy);
+	for (i = 0; i < 8; i++)
+		for (j = 0; j < modmap->max_keypermod; j++)
+			if (modmap->modifiermap[i * modmap->max_keypermod + j]
+				== XKeysymToKeycode(dpy, XK_Num_Lock))
+				numlockmask = (1 << i);
+	XFreeModifiermap(modmap);
+}
+
+void
+updatesizehints(Client *c)
+{
+	long msize;
+	XSizeHints size;
+
+	if (!XGetWMNormalHints(dpy, c->win, &size, &msize))
+		/* size is uninitialized, ensure that size.flags aren't used */
+		size.flags = PSize;
+	if (size.flags & PBaseSize) {
+		c->basew = size.base_width;
+		c->baseh = size.base_height;
+	} else if (size.flags & PMinSize) {
+		c->basew = size.min_width;
+		c->baseh = size.min_height;
+	} else
+		c->basew = c->baseh = 0;
+	if (size.flags & PResizeInc) {
+		c->incw = size.width_inc;
+		c->inch = size.height_inc;
+	} else
+		c->incw = c->inch = 0;
+	if (size.flags & PMaxSize) {
+		c->maxw = size.max_width;
+		c->maxh = size.max_height;
+	} else
+		c->maxw = c->maxh = 0;
+	if (size.flags & PMinSize) {
+		c->minw = size.min_width;
+		c->minh = size.min_height;
+	} else if (size.flags & PBaseSize) {
+		c->minw = size.base_width;
+		c->minh = size.base_height;
+	} else
+		c->minw = c->minh = 0;
+	if (size.flags & PAspect) {
+		c->mina = (float)size.min_aspect.y / size.min_aspect.x;
+		c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
+	} else
+		c->maxa = c->mina = 0.0;
+	c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
+}
+
+void
+updatetitle(Client *c)
+{
+	if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
+		gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
+	if (c->name[0] == '\0') /* hack to mark broken clients */
+		strcpy(c->name, broken);
+}
+
+void
+updatewindowtype(Client *c)
+{
+	Atom state = getatomprop(c, netatom[NetWMState]);
+	Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
+
+	if (state == netatom[NetWMFullscreen])
+		setfullscreen(c, 1);
+	if (wtype == netatom[NetWMWindowTypeDialog])
+		c->isfloating = 1;
+}
+
+void
+updatewmhints(Client *c)
+{
+	XWMHints *wmh;
+
+	if ((wmh = XGetWMHints(dpy, c->win))) {
+		if (c == selmon->sel && wmh->flags & XUrgencyHint) {
+			wmh->flags &= ~XUrgencyHint;
+			XSetWMHints(dpy, c->win, wmh);
+		} else
+			c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
+		if (wmh->flags & InputHint)
+			c->neverfocus = !wmh->input;
+		else
+			c->neverfocus = 0;
+		XFree(wmh);
+	}
+}
+
+void
+view(const Arg *arg)
+{
+	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+		return;
+	selmon->seltags ^= 1; /* toggle sel tagset */
+	if (arg->ui & TAGMASK)
+		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+	focus(NULL);
+	arrange(selmon);
+}
+
+Client *
+wintoclient(Window w)
+{
+	Client *c;
+	Monitor *m;
+
+	for (m = mons; m; m = m->next)
+		for (c = m->clients; c; c = c->next)
+			if (c->win == w)
+				return c;
+	return NULL;
+}
+
+Monitor *
+wintomon(Window w)
+{
+	int x, y;
+	Client *c;
+	Monitor *m;
+
+	if (w == root && getrootptr(&x, &y))
+		return recttomon(x, y, 1, 1);
+	for (m = mons; m; m = m->next)
+		if (w == m->barwin)
+			return m;
+	if ((c = wintoclient(w)))
+		return c->mon;
+	return selmon;
+}
+
+/* There's no way to check accesses to destroyed windows, thus those cases are
+ * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
+ * default error handler, which may call exit. */
+int
+xerror(Display *dpy, XErrorEvent *ee)
+{
+	if (ee->error_code == BadWindow
+	|| (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch)
+	|| (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable)
+	|| (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable)
+	|| (ee->request_code == X_PolySegment && ee->error_code == BadDrawable)
+	|| (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch)
+	|| (ee->request_code == X_GrabButton && ee->error_code == BadAccess)
+	|| (ee->request_code == X_GrabKey && ee->error_code == BadAccess)
+	|| (ee->request_code == X_CopyArea && ee->error_code == BadDrawable))
+		return 0;
+	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
+		ee->request_code, ee->error_code);
+	return xerrorxlib(dpy, ee); /* may call exit */
+}
+
+int
+xerrordummy(Display *dpy, XErrorEvent *ee)
+{
+	return 0;
+}
+
+/* Startup Error handler to check if another window manager
+ * is already running. */
+int
+xerrorstart(Display *dpy, XErrorEvent *ee)
+{
+	die("dwm: another window manager is already running");
+	return -1;
+}
+
+void
+zoom(const Arg *arg)
+{
+	Client *c = selmon->sel;
+
+	if (!selmon->lt[selmon->sellt]->arrange
+	|| (selmon->sel && selmon->sel->isfloating))
+		return;
+	if (c == nexttiled(selmon->clients))
+		if (!c || !(c = nexttiled(c->next)))
+			return;
+	pop(c);
+}
+
+int
+main(int argc, char *argv[])
+{
+	if (argc == 2 && !strcmp("-v", argv[1]))
+		die("dwm-"VERSION);
+	else if (argc != 1)
+		die("usage: dwm [-v]");
+	if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
+		fputs("warning: no locale support\n", stderr);
+	if (!(dpy = XOpenDisplay(NULL)))
+		die("dwm: cannot open display");
+	checkotherwm();
+	setup();
+#ifdef __OpenBSD__
+	if (pledge("stdio rpath proc exec", NULL) == -1)
+		die("pledge");
+#endif /* __OpenBSD__ */
+	scan();
+	run();
+	cleanup();
+	XCloseDisplay(dpy);
+	return EXIT_SUCCESS;
+}
diff --git a/home/kurb42/.config/suckless/dwm/dwm.png b/home/kurb42/.config/suckless/dwm/dwm.png
new file mode 100644
index 0000000..b1f9ba7
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/dwm.png
Binary files differdiff --git a/home/kurb42/.config/suckless/dwm/transient.c b/home/kurb42/.config/suckless/dwm/transient.c
new file mode 100644
index 0000000..040adb5
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/transient.c
@@ -0,0 +1,42 @@
+/* cc transient.c -o transient -lX11 */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+int main(void) {
+	Display *d;
+	Window r, f, t = None;
+	XSizeHints h;
+	XEvent e;
+
+	d = XOpenDisplay(NULL);
+	if (!d)
+		exit(1);
+	r = DefaultRootWindow(d);
+
+	f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
+	h.min_width = h.max_width = h.min_height = h.max_height = 400;
+	h.flags = PMinSize | PMaxSize;
+	XSetWMNormalHints(d, f, &h);
+	XStoreName(d, f, "floating");
+	XMapWindow(d, f);
+
+	XSelectInput(d, f, ExposureMask);
+	while (1) {
+		XNextEvent(d, &e);
+
+		if (t == None) {
+			sleep(5);
+			t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
+			XSetTransientForHint(d, t, f);
+			XStoreName(d, t, "transient");
+			XMapWindow(d, t);
+			XSelectInput(d, t, ExposureMask);
+		}
+	}
+
+	XCloseDisplay(d);
+	exit(0);
+}
diff --git a/home/kurb42/.config/suckless/dwm/util.c b/home/kurb42/.config/suckless/dwm/util.c
new file mode 100644
index 0000000..fe044fc
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/util.c
@@ -0,0 +1,35 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+void *
+ecalloc(size_t nmemb, size_t size)
+{
+	void *p;
+
+	if (!(p = calloc(nmemb, size)))
+		die("calloc:");
+	return p;
+}
+
+void
+die(const char *fmt, ...) {
+	va_list ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+		fputc(' ', stderr);
+		perror(NULL);
+	} else {
+		fputc('\n', stderr);
+	}
+
+	exit(1);
+}
diff --git a/home/kurb42/.config/suckless/dwm/util.h b/home/kurb42/.config/suckless/dwm/util.h
new file mode 100644
index 0000000..f633b51
--- /dev/null
+++ b/home/kurb42/.config/suckless/dwm/util.h
@@ -0,0 +1,8 @@
+/* See LICENSE file for copyright and license details. */
+
+#define MAX(A, B)               ((A) > (B) ? (A) : (B))
+#define MIN(A, B)               ((A) < (B) ? (A) : (B))
+#define BETWEEN(X, A, B)        ((A) <= (X) && (X) <= (B))
+
+void die(const char *fmt, ...);
+void *ecalloc(size_t nmemb, size_t size);
diff --git a/home/kurb42/.emacs.d/init.el b/home/kurb42/.emacs.d/init.el
new file mode 100644
index 0000000..23eb650
--- /dev/null
+++ b/home/kurb42/.emacs.d/init.el
@@ -0,0 +1,16 @@
+(add-to-list 'custom-theme-load-path (expand-file-name "~/.emacs.d/themes/"))
+(load-theme 'nord t)
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(fancy-splash-image "nil")
+ '(scroll-bar-mode nil)
+ '(tool-bar-mode nil))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(default ((t (:family "UbuntuMono Nerd Font" :foundry "DAMA" :slant normal :weight normal :height 98 :width normal)))))
diff --git a/home/kurb42/.emacs.d/themes/nord-theme.el b/home/kurb42/.emacs.d/themes/nord-theme.el
new file mode 100644
index 0000000..d5c5b04
--- /dev/null
+++ b/home/kurb42/.emacs.d/themes/nord-theme.el
@@ -0,0 +1,722 @@
+;;; nord-theme.el --- An arctic, north-bluish clean and elegant theme
+
+;; Copyright (C) 2016-present Arctic Ice Studio <development@arcticicestudio.com> (https://www.arcticicestudio.com)
+;; Copyright (C) 2016-present Sven Greb <development@svengreb.de> (https://www.svengreb.de)
+
+;; Title: Nord Theme
+;; Project: nord-emacs
+;; Version: 0.5.0
+;; URL: https://github.com/arcticicestudio/nord-emacs
+;; Author: Arctic Ice Studio <development@arcticicestudio.com>
+;; Package-Requires: ((emacs "24"))
+;; License: MIT
+
+;;; Commentary:
+
+;; Nord is a 16 colorspace theme build to run in GUI- and terminal
+;; mode with support for many third-party syntax- and UI packages.
+
+;;; References:
+;; Awesome Emacs
+;;   https://github.com/emacs-tw/awesome-emacs
+;; GNU ELPA
+;;   https://elpa.gnu.org
+;; GNU Emacs
+;;   https://www.gnu.org/software/emacs/manual/html_node/emacs/Custom-Themes.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/emacs/Creating-Custom-Themes.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/emacs/Faces.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/emacs/Standard-Faces.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/emacs/Face-Customization.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/elisp/Face-Attributes.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/elisp/Faces-for-Font-Lock.html
+;;   https://www.gnu.org/software/emacs/manual/html_node/elisp/Display-Feature-Testing.html
+;; marmalade repo
+;;   https://marmalade-repo.org
+;; MELPA
+;;   https://melpa.org
+;;   https://stable.melpa.org
+
+;;; Code:
+
+(unless (>= emacs-major-version 24)
+  (error "Nord theme requires Emacs 24 or later!"))
+
+(deftheme nord "An arctic, north-bluish clean and elegant theme")
+
+(defgroup nord nil
+  "Nord theme customizations.
+  The theme has to be reloaded after changing anything in this group."
+  :group 'faces)
+
+(defcustom nord-comment-brightness 10
+  "Allows to define a custom comment color brightness with percentage adjustments from 0% - 20%.
+  As of version 0.4.0, this variable is obsolete/deprecated and has no effect anymore and will be removed in version 1.0.0!
+  The comment color brightness has been increased by 10% by default.
+  Please see https://github.com/arcticicestudio/nord-emacs/issues/73 for more details."
+  :type 'integer
+  :group 'nord)
+
+(make-obsolete-variable
+  'nord-comment-brightness
+  "The custom color brightness feature has been deprecated and will be removed in version 1.0.0!
+  The comment color brightness has been increased by 10% by default.
+  Please see https://github.com/arcticicestudio/nord-emacs/issues/73 for more details."
+  "0.4.0")
+
+(defcustom nord-region-highlight nil
+  "Allows to set a region highlight style based on the Nord components.
+  Valid styles are
+    - 'snowstorm' - Uses 'nord0' as foreground- and 'nord4' as background color
+    - 'frost' - Uses 'nord0' as foreground- and 'nord8' as background color"
+  :type 'string
+  :group 'nord)
+
+(defcustom nord-uniform-mode-lines nil
+  "Enables uniform activate- and inactive mode lines using 'nord3' as background."
+  :type 'boolean
+  :group 'nord)
+
+(setq nord-theme--brightened-comments '("#4c566a" "#4e586d" "#505b70" "#525d73" "#556076" "#576279" "#59647c" "#5b677f" "#5d6982" "#5f6c85" "#616e88" "#63718b" "#66738e" "#687591" "#6a7894" "#6d7a96" "#6f7d98" "#72809a" "#75829c" "#78859e" "#7b88a1"))
+
+(defun nord-theme--brightened-comment-color (percent)
+  "Returns the brightened comment color for the given percent.
+  The value must be greater or equal to 0 and less or equal to 20, otherwise the default 'nord3' color is used.
+  As of version 0.4.0, this function is obsolete/deprecated and has no effect anymore and will be removed in version 1.0.0!
+  The comment color brightness has been increased by 10% by default.
+  Please see https://github.com/arcticicestudio/nord-emacs/issues/73 for more details."
+  (nth 10 nord-theme--brightened-comments))
+
+(make-obsolete
+  'nord-theme--brightened-comment-color
+  "The custom color brightness feature has been deprecated and will be removed in version 1.0.0!\
+  The comment color brightness has been increased by 10% by default.\
+  Please see https://github.com/arcticicestudio/nord-emacs/issues/73 for more details."
+  "0.4.0")
+
+(defun nord-display-truecolor-or-graphic-p ()
+  "Returns whether the display can display nord colors"
+  (or (= (display-color-cells) 16777216) (display-graphic-p)))
+
+;;;; Color Constants
+(let ((class '((class color) (min-colors 89)))
+  (nord0 (if (nord-display-truecolor-or-graphic-p) "#2E3440" nil))
+  (nord1 (if (nord-display-truecolor-or-graphic-p) "#3B4252" "black"))
+  (nord2 (if (nord-display-truecolor-or-graphic-p) "#434C5E" "#434C5E"))
+  (nord3 (if (nord-display-truecolor-or-graphic-p) "#4C566A" "brightblack"))
+  (nord4 (if (nord-display-truecolor-or-graphic-p) "#D8DEE9" "#D8DEE9"))
+  (nord5 (if (nord-display-truecolor-or-graphic-p) "#E5E9F0" "white"))
+  (nord6 (if (nord-display-truecolor-or-graphic-p) "#ECEFF4" "brightwhite"))
+  (nord7 (if (nord-display-truecolor-or-graphic-p) "#8FBCBB" "cyan"))
+  (nord8 (if (nord-display-truecolor-or-graphic-p) "#88C0D0" "brightcyan"))
+  (nord9 (if (nord-display-truecolor-or-graphic-p) "#81A1C1" "blue"))
+  (nord10 (if (nord-display-truecolor-or-graphic-p) "#5E81AC" "brightblue"))
+  (nord11 (if (nord-display-truecolor-or-graphic-p) "#BF616A" "red"))
+  (nord12 (if (nord-display-truecolor-or-graphic-p) "#D08770" "brightyellow"))
+  (nord13 (if (nord-display-truecolor-or-graphic-p) "#EBCB8B" "yellow"))
+  (nord14 (if (nord-display-truecolor-or-graphic-p) "#A3BE8C" "green"))
+  (nord15 (if (nord-display-truecolor-or-graphic-p) "#B48EAD" "magenta"))
+  (nord-annotation (if (nord-display-truecolor-or-graphic-p) "#D08770" "brightyellow"))
+  (nord-attribute (if (nord-display-truecolor-or-graphic-p) "#8FBCBB" "cyan"))
+  (nord-class (if (nord-display-truecolor-or-graphic-p) "#8FBCBB" "cyan"))
+  (nord-comment (if (nord-display-truecolor-or-graphic-p) (nord-theme--brightened-comment-color nord-comment-brightness) "brightblack"))
+  (nord-escape (if (nord-display-truecolor-or-graphic-p) "#D08770" "brightyellow"))
+  (nord-method (if (nord-display-truecolor-or-graphic-p) "#88C0D0" "brightcyan"))
+  (nord-keyword (if (nord-display-truecolor-or-graphic-p) "#81A1C1" "blue"))
+  (nord-numeric (if (nord-display-truecolor-or-graphic-p) "#B48EAD" "magenta"))
+  (nord-operator (if (nord-display-truecolor-or-graphic-p) "#81A1C1" "blue"))
+  (nord-preprocessor (if (nord-display-truecolor-or-graphic-p) "#5E81AC" "brightblue"))
+  (nord-punctuation (if (nord-display-truecolor-or-graphic-p) "#D8DEE9" "#D8DEE9"))
+  (nord-regexp (if (nord-display-truecolor-or-graphic-p) "#EBCB8B" "yellow"))
+  (nord-string (if (nord-display-truecolor-or-graphic-p) "#A3BE8C" "green"))
+  (nord-tag (if (nord-display-truecolor-or-graphic-p) "#81A1C1" "blue"))
+  (nord-variable (if (nord-display-truecolor-or-graphic-p) "#D8DEE9" "#D8DEE9"))
+  (nord-region-highlight-foreground (if (or
+    (string= nord-region-highlight "frost")
+    (string= nord-region-highlight "snowstorm")) "#2E3440" nil))
+  (nord-region-highlight-background (if
+    (string= nord-region-highlight "frost") "#88C0D0"
+      (if (string= nord-region-highlight "snowstorm") "#D8DEE9" "#434C5E")))
+  (nord-uniform-mode-lines-background (if nord-uniform-mode-lines "#4C566A" "#3B4252")))
+
+;;;; +------------+
+;;;; + Core Faces +
+;;;; +------------+
+  (custom-theme-set-faces
+    'nord
+    ;; +--- Base ---+
+    `(bold ((,class (:weight bold))))
+    `(bold-italic ((,class (:weight bold :slant italic))))
+    `(default ((,class (:foreground ,nord4 :background ,nord0))))
+    `(error ((,class (:foreground ,nord11 :weight bold))))
+    `(escape-glyph ((,class (:foreground ,nord12))))
+    `(font-lock-builtin-face ((,class (:foreground ,nord9))))
+    `(font-lock-comment-face ((,class (:foreground ,nord-comment))))
+    `(font-lock-comment-delimiter-face ((,class (:foreground ,nord-comment))))
+    `(font-lock-constant-face ((,class (:foreground ,nord9))))
+    `(font-lock-doc-face ((,class (:foreground ,nord-comment))))
+    `(font-lock-function-name-face ((,class (:foreground ,nord8))))
+    `(font-lock-keyword-face ((,class (:foreground ,nord9))))
+    `(font-lock-negation-char-face ((,class (:foreground ,nord9))))
+    `(font-lock-preprocessor-face ((,class (:foreground ,nord10 :weight bold))))
+    `(font-lock-reference-face ((,class (:foreground ,nord9))))
+    `(font-lock-regexp-grouping-backslash ((,class (:foreground ,nord13))))
+    `(font-lock-regexp-grouping-construct ((,class (:foreground ,nord13))))
+    `(font-lock-string-face ((,class (:foreground ,nord14))))
+    `(font-lock-type-face ((,class (:foreground ,nord7))))
+    `(font-lock-variable-name-face ((,class (:foreground ,nord4))))
+    `(font-lock-warning-face ((,class (:foreground ,nord13))))
+    `(italic ((,class (:slant italic))))
+    `(shadow ((,class (:foreground ,nord3))))
+    `(underline ((,class (:underline t))))
+    `(warning ((,class (:foreground ,nord13 :weight bold))))
+
+    ;; +--- Syntax ---+
+    ;; > C
+    `(c-annotation-face ((,class (:foreground ,nord-annotation))))
+
+    ;; > diff
+    `(diff-added ((,class (:foreground ,nord14))))
+    `(diff-changed ((,class (:foreground ,nord13))))
+    `(diff-context ((,class (:inherit default))))
+    `(diff-file-header ((,class (:foreground ,nord8))))
+    `(diff-function ((,class (:foreground ,nord7))))
+    `(diff-header ((,class (:foreground ,nord9 :weight bold))))
+    `(diff-hunk-header ((,class (:foreground ,nord9 :background ,nord0))))
+    `(diff-indicator-added ((,class (:foreground ,nord14))))
+    `(diff-indicator-changed ((,class (:foreground ,nord13))))
+    `(diff-indicator-removed ((,class (:foreground ,nord11))))
+    `(diff-nonexistent ((,class (:foreground ,nord11))))
+    `(diff-refine-added ((,class (:foreground ,nord14))))
+    `(diff-refine-changed ((,class (:foreground ,nord13))))
+    `(diff-refine-removed ((,class (:foreground ,nord11))))
+    `(diff-removed ((,class (:foreground ,nord11))))
+
+    ;; +--- UI ---+
+    `(border ((,class (:foreground ,nord4))))
+    `(buffer-menu-buffer ((,class (:foreground ,nord4 :weight bold))))
+    `(button ((,class (:background ,nord0 :foreground ,nord8 :box (:line-width 2 :color ,nord4 :style sunken-button)))))
+    `(completions-annotations ((,class (:foreground ,nord9))))
+    `(completions-common-part ((,class (:foreground ,nord8 :weight bold))))
+    `(completions-first-difference ((,class (:foreground ,nord11))))
+    `(custom-button ((,class (:background ,nord0 :foreground ,nord8 :box (:line-width 2 :color ,nord4 :style sunken-button)))))
+    `(custom-button-mouse ((,class (:background ,nord4 :foreground ,nord0 :box (:line-width 2 :color ,nord4 :style sunken-button)))))
+    `(custom-button-pressed ((,class (:background ,nord6 :foreground ,nord0 :box (:line-width 2 :color ,nord4 :style sunken-button)))))
+    `(custom-button-pressed-unraised ((,class (:background ,nord4 :foreground ,nord0 :box (:line-width 2 :color ,nord4 :style sunken-button)))))
+    `(custom-button-unraised ((,class (:background ,nord0 :foreground ,nord8 :box (:line-width 2 :color ,nord4 :style sunken-button)))))
+    `(custom-changed ((,class (:foreground ,nord13))))
+    `(custom-comment ((,class (:foreground ,nord-comment))))
+    `(custom-comment-tag ((,class (:foreground ,nord7))))
+    `(custom-documentation ((,class (:foreground ,nord4))))
+    `(custom-group-tag ((,class (:foreground ,nord8 :weight bold))))
+    `(custom-group-tag-1 ((,class (:foreground ,nord8 :weight bold))))
+    `(custom-invalid ((,class (:foreground ,nord11))))
+    `(custom-modified ((,class (:foreground ,nord13))))
+    `(custom-rogue ((,class (:foreground ,nord12 :background ,nord2))))
+    `(custom-saved ((,class (:foreground ,nord14))))
+    `(custom-set ((,class (:foreground ,nord8))))
+    `(custom-state ((,class (:foreground ,nord14))))
+    `(custom-themed ((,class (:foreground ,nord8 :background ,nord2))))
+    `(cursor ((,class (:background ,nord4))))
+    `(fringe ((,class (:foreground ,nord4 :background ,nord0))))
+    `(file-name-shadow ((,class (:inherit shadow))))
+    `(header-line ((,class (:foreground ,nord4 :background ,nord2))))
+    `(help-argument-name ((,class (:foreground ,nord8))))
+    `(highlight ((,class (:foreground ,nord8 :background ,nord2))))
+    `(hl-line ((,class (:background ,nord1))))
+    `(info-menu-star ((,class (:foreground ,nord9))))
+    `(isearch ((,class (:foreground ,nord0 :background ,nord8))))
+    `(isearch-fail ((,class (:foreground ,nord11))))
+    `(link ((,class (:underline t))))
+    `(link-visited ((,class (:underline t))))
+    `(linum ((,class (:foreground ,nord3 :background ,nord0))))
+    `(linum-relative-current-face ((,class (:foreground ,nord3 :background ,nord0))))
+    `(match ((,class (:inherit isearch))))
+    `(message-cited-text ((,class (:foreground ,nord4))))
+    `(message-header-cc ((,class (:foreground ,nord9))))
+    `(message-header-name ((,class (:foreground ,nord7))))
+    `(message-header-newsgroup ((,class (:foreground ,nord14))))
+    `(message-header-other ((,class (:foreground ,nord4))))
+    `(message-header-subject ((,class (:foreground ,nord8))))
+    `(message-header-to ((,class (:foreground ,nord9))))
+    `(message-header-xheader ((,class (:foreground ,nord13))))
+    `(message-mml ((,class (:foreground ,nord10))))
+    `(message-separator ((,class (:inherit shadow))))
+    `(minibuffer-prompt ((,class (:foreground ,nord8 :weight bold))))
+    `(mm-command-output ((,class (:foreground ,nord8))))
+    `(mode-line ((,class (:foreground ,nord8 :background ,nord3))))
+    `(mode-line-buffer-id ((,class (:weight bold))))
+    `(mode-line-highlight ((,class (:inherit highlight))))
+    `(mode-line-inactive ((,class (:foreground ,nord4 :background ,nord-uniform-mode-lines-background))))
+    `(next-error ((,class (:inherit error))))
+    `(nobreak-space ((,class (:foreground ,nord3))))
+    `(outline-1 ((,class (:foreground ,nord8 :weight bold))))
+    `(outline-2 ((,class (:inherit outline-1))))
+    `(outline-3 ((,class (:inherit outline-1))))
+    `(outline-4 ((,class (:inherit outline-1))))
+    `(outline-5 ((,class (:inherit outline-1))))
+    `(outline-6 ((,class (:inherit outline-1))))
+    `(outline-7 ((,class (:inherit outline-1))))
+    `(outline-8 ((,class (:inherit outline-1))))
+    `(package-description ((,class (:foreground ,nord4))))
+    `(package-help-section-name ((,class (:foreground ,nord8 :weight bold))))
+    `(package-name ((,class (:foreground ,nord8))))
+    `(package-status-available ((,class (:foreground ,nord7))))
+    `(package-status-avail-obso ((,class (:foreground ,nord7 :slant italic))))
+    `(package-status-built-in ((,class (:foreground ,nord9))))
+    `(package-status-dependency ((,class (:foreground ,nord8 :slant italic))))
+    `(package-status-disabled ((,class (:foreground ,nord3))))
+    `(package-status-external ((,class (:foreground ,nord12 :slant italic))))
+    `(package-status-held ((,class (:foreground ,nord4 :weight bold))))
+    `(package-status-new ((,class (:foreground ,nord14))))
+    `(package-status-incompat ((,class (:foreground ,nord11))))
+    `(package-status-installed ((,class (:foreground ,nord7 :weight bold))))
+    `(package-status-unsigned ((,class (:underline ,nord13))))
+    `(query-replace ((,class (:foreground ,nord8 :background ,nord2))))
+    `(region ((,class (:foreground ,nord-region-highlight-foreground :background ,nord-region-highlight-background))))
+    `(scroll-bar ((,class (:background ,nord3))))
+    `(secondary-selection ((,class (:background ,nord2))))
+
+    ;; `show-paren-match-face` and `show-paren-mismatch-face` are deprecated since Emacs version 22.1 and were
+    ;; removed in Emacs 25.
+    ;; https://github.com/arcticicestudio/nord-emacs/issues/75
+    ;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=c430f7e23fc2c22f251ace4254e37dea1452dfc3
+    ;; https://github.com/emacs-mirror/emacs/commit/c430f7e23fc2c22f251ace4254e37dea1452dfc3
+    `(show-paren-match-face ((,class (:foreground ,nord0 :background ,nord8))))
+    `(show-paren-mismatch-face ((,class (:background ,nord11))))
+
+    `(show-paren-match ((,class (:foreground ,nord0 :background ,nord8))))
+    `(show-paren-mismatch ((,class (:background ,nord11))))
+    `(success ((,class (:foreground ,nord14))))
+    `(term ((,class (:foreground ,nord4 :background ,nord0))))
+    `(term-color-black ((,class (:foreground ,nord1 :background ,nord1))))
+    `(term-color-white ((,class (:foreground ,nord5 :background ,nord5))))
+    `(term-color-cyan ((,class (:foreground ,nord7 :background ,nord7))))
+    `(term-color-blue ((,class (:foreground ,nord8 :background ,nord8))))
+    `(term-color-red ((,class (:foreground ,nord11 :background ,nord11))))
+    `(term-color-yellow ((,class (:foreground ,nord13 :background ,nord13))))
+    `(term-color-green ((,class (:foreground ,nord14 :background ,nord14))))
+    `(term-color-magenta ((,class (:foreground ,nord15 :background ,nord15))))
+    `(tool-bar ((,class (:foreground ,nord4 :background ,nord3))))
+    `(tooltip ((,class (:foreground ,nord0 :background ,nord4))))
+    `(trailing-whitespace ((,class (:foreground ,nord3))))
+    `(tty-menu-disabled-face ((,class (:foreground ,nord1))))
+    `(tty-menu-enabled-face ((,class (:background ,nord2 foreground ,nord4))))
+    `(tty-menu-selected-face ((,class (:foreground ,nord8 :underline t))))
+    `(undo-tree-visualizer-current-face ((,class (:foreground ,nord8))))
+    `(undo-tree-visualizer-default-face ((,class (:foreground ,nord4))))
+    `(undo-tree-visualizer-unmodified-face ((,class (:foreground ,nord4))))
+    `(undo-tree-visualizer-register-face ((,class (:foreground ,nord9))))
+    `(vc-conflict-state ((,class (:foreground ,nord12))))
+    `(vc-edited-state ((,class (:foreground ,nord13))))
+    `(vc-locally-added-state ((,class (:underline ,nord14))))
+    `(vc-locked-state ((,class (:foreground ,nord10))))
+    `(vc-missing-state ((,class (:foreground ,nord11))))
+    `(vc-needs-update-state ((,class (:foreground ,nord12))))
+    `(vc-removed-state ((,class (:foreground ,nord11))))
+    `(vc-state-base ((,class (:foreground ,nord4))))
+    `(vc-up-to-date-state ((,class (:foreground ,nord8))))
+    `(vertical-border ((,class (:foreground ,nord2))))
+    `(which-func ((,class (:foreground ,nord8))))
+    `(whitespace-big-indent ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-empty ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-hspace ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-indentation ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-line ((,class (:background ,nord0))))
+    `(whitespace-newline ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-space ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-space-after-tab ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-space-before-tab ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-tab ((,class (:foreground ,nord3 :background ,nord0))))
+    `(whitespace-trailing ((,class (:inherit trailing-whitespace))))
+    `(widget-button-pressed ((,class (:foreground ,nord9 :background ,nord1))))
+    `(widget-documentation ((,class (:foreground ,nord4))))
+    `(widget-field ((,class (:background ,nord2 :foreground ,nord4))))
+    `(widget-single-line-field ((,class (:background ,nord2 :foreground ,nord4))))
+    `(window-divider ((,class (:background ,nord3))))
+    `(window-divider-first-pixel ((,class (:background ,nord3))))
+    `(window-divider-last-pixel ((,class (:background ,nord3))))
+
+    ;;;; +-----------------+
+    ;;;; + Package Support +
+    ;;;; +-----------------+
+    ;; +--- Syntax ---+
+    ;; > Auctex
+    `(font-latex-bold-face ((,class (:inherit bold))))
+    `(font-latex-italic-face ((,class (:inherit italic))))
+    `(font-latex-math-face ((,class (:foreground ,nord8))))
+    `(font-latex-sectioning-0-face ((,class (:foreground ,nord8 :weight bold))))
+    `(font-latex-sectioning-1-face ((,class (:inherit font-latex-sectioning-0-face))))
+    `(font-latex-sectioning-2-face ((,class (:inherit font-latex-sectioning-0-face))))
+    `(font-latex-sectioning-3-face ((,class (:inherit font-latex-sectioning-0-face))))
+    `(font-latex-sectioning-4-face ((,class (:inherit font-latex-sectioning-0-face))))
+    `(font-latex-sectioning-5-face ((,class (:inherit font-latex-sectioning-0-face))))
+    `(font-latex-script-char-face ((,class (:inherit font-lock-warning-face))))
+    `(font-latex-string-face ((,class (:inherit font-lock-string-face))))
+    `(font-latex-warning-face ((,class (:inherit font-lock-warning-face))))
+
+    ;; > Elixir
+    `(elixir-attribute-face ((,class (:foreground ,nord-annotation))))
+    `(elixir-atom-face ((,class (:foreground ,nord4 :weight bold))))
+
+    ;; > Enhanced Ruby
+    `(enh-ruby-heredoc-delimiter-face ((,class (:foreground ,nord14))))
+    `(enh-ruby-op-face ((,class (:foreground ,nord9))))
+    `(enh-ruby-regexp-delimiter-face ((,class (:foreground ,nord13))))
+    `(enh-ruby-regexp-face ((,class (:foreground ,nord13))))
+    `(enh-ruby-string-delimiter-face ((,class (:foreground ,nord14))))
+    `(erm-syn-errline ((,class (:foreground ,nord11 :underline t))))
+    `(erm-syn-warnline ((,class (:foreground ,nord13 :underline t))))
+
+    ;; > Java Development Environment for Emacs
+    `(jdee-db-active-breakpoint-face ((,class (:background ,nord2 :weight bold))))
+    `(jdee-bug-breakpoint-cursor ((,class (:background ,nord2))))
+    `(jdee-db-requested-breakpoint-face ((,class (:foreground ,nord13 :background ,nord2 :weight bold))))
+    `(jdee-db-spec-breakpoint-face ((,class (:foreground ,nord14 :background ,nord2 :weight bold))))
+    `(jdee-font-lock-api-face ((,class (:foreground ,nord4))))
+    `(jdee-font-lock-code-face ((,class (:slant italic))))
+    `(jdee-font-lock-constant-face ((,class (:foreground ,nord-keyword))))
+    `(jdee-font-lock-constructor-face ((,class (:foreground ,nord-method))))
+    `(jdee-font-lock-doc-tag-face ((,class (:foreground ,nord7))))
+    `(jdee-font-lock-link-face ((,class (:underline t))))
+    `(jdee-font-lock-modifier-face ((,class (:foreground ,nord-keyword))))
+    `(jdee-font-lock-number-face ((,class (:foreground ,nord-numeric))))
+    `(jdee-font-lock-operator-fac ((,class (:foreground ,nord-operator))))
+    `(jdee-font-lock-package-face ((,class (:foreground ,nord-class))))
+    `(jdee-font-lock-pre-face ((,class (:foreground ,nord-comment :slant italic))))
+    `(jdee-font-lock-private-face ((,class (:foreground ,nord-keyword))))
+    `(jdee-font-lock-public-face ((,class (:foreground ,nord-keyword))))
+    `(jdee-font-lock-variable-face ((,class (:foreground ,nord-variable))))
+
+    ;; > JavaScript 2
+    `(js2-function-call ((,class (:foreground ,nord8))))
+    `(js2-private-function-call ((,class (:foreground ,nord8))))
+    `(js2-jsdoc-html-tag-delimiter ((,class (:foreground ,nord6))))
+    `(js2-jsdoc-html-tag-name ((,class (:foreground ,nord9))))
+    `(js2-external-variable ((,class (:foreground ,nord4))))
+    `(js2-function-param ((,class (:foreground ,nord4))))
+    `(js2-jsdoc-value ((,class (:foreground ,nord-comment))))
+    `(js2-jsdoc-tag ((,class (:foreground ,nord7))))
+    `(js2-jsdoc-type ((,class (:foreground ,nord7))))
+    `(js2-private-member ((,class (:foreground ,nord4))))
+    `(js2-object-property ((,class (:foreground ,nord4))))
+    `(js2-error ((,class (:foreground ,nord11))))
+    `(js2-warning ((,class (:foreground ,nord13))))
+    `(js2-instance-member ((,class (:foreground ,nord4))))
+
+    ;; > JavaScript 3
+    `(js3-error-face ((,class (:foreground ,nord11))))
+    `(js3-external-variable-face ((,class (:foreground ,nord4))))
+    `(js3-function-param-face ((,class (:foreground ,nord4))))
+    `(js3-instance-member-face ((,class (:foreground ,nord4))))
+    `(js3-jsdoc-html-tag-delimiter-face ((,class (:foreground ,nord6))))
+    `(js3-jsdoc-html-tag-name-face ((,class (:foreground ,nord9))))
+    `(js3-jsdoc-tag-face ((,class (:foreground ,nord9))))
+    `(js3-jsdoc-type-face ((,class (:foreground ,nord7))))
+    `(js3-jsdoc-value-face ((,class (:foreground ,nord4))))
+    `(js3-magic-paren-face ((,class (:inherit show-paren-match-face))))
+    `(js3-private-function-call-face ((,class (:foreground ,nord8))))
+    `(js3-private-member-face ((,class (:foreground ,nord4))))
+    `(js3-warning-face ((,class (:foreground ,nord13))))
+
+    ;; > Markdown
+    `(markdown-blockquote-face ((,class (:foreground ,nord-comment))))
+    `(markdown-bold-face ((,class (:inherit bold))))
+    `(markdown-header-face-1 ((,class (:foreground ,nord8))))
+    `(markdown-header-face-2 ((,class (:foreground ,nord8))))
+    `(markdown-header-face-3 ((,class (:foreground ,nord8))))
+    `(markdown-header-face-4 ((,class (:foreground ,nord8))))
+    `(markdown-header-face-5 ((,class (:foreground ,nord8))))
+    `(markdown-header-face-6 ((,class (:foreground ,nord8))))
+    `(markdown-inline-code-face ((,class (:foreground ,nord7))))
+    `(markdown-italic-face ((,class (:inherit italic))))
+    `(markdown-link-face ((,class (:foreground ,nord8))))
+    `(markdown-markup-face ((,class (:foreground ,nord9))))
+    `(markdown-reference-face ((,class (:inherit markdown-link-face))))
+    `(markdown-url-face ((,class (:foreground ,nord4 :underline t))))
+
+    ;; > Rainbow Delimeters
+    `(rainbow-delimiters-depth-1-face ((,class :foreground ,nord7)))
+    `(rainbow-delimiters-depth-2-face ((,class :foreground ,nord8)))
+    `(rainbow-delimiters-depth-3-face ((,class :foreground ,nord9)))
+    `(rainbow-delimiters-depth-4-face ((,class :foreground ,nord10)))
+    `(rainbow-delimiters-depth-5-face ((,class :foreground ,nord12)))
+    `(rainbow-delimiters-depth-6-face ((,class :foreground ,nord13)))
+    `(rainbow-delimiters-depth-7-face ((,class :foreground ,nord14)))
+    `(rainbow-delimiters-depth-8-face ((,class :foreground ,nord15)))
+    `(rainbow-delimiters-unmatched-face ((,class :foreground ,nord11)))
+
+    ;; > Web Mode
+    `(web-mode-attr-tag-custom-face ((,class (:foreground ,nord-attribute))))
+    `(web-mode-builtin-face ((,class (:foreground ,nord-keyword))))
+    `(web-mode-comment-face ((,class (:foreground ,nord-comment))))
+    `(web-mode-comment-keyword-face ((,class (:foreground ,nord-comment))))
+    `(web-mode-constant-face ((,class (:foreground ,nord-variable))))
+    `(web-mode-css-at-rule-face ((,class (:foreground ,nord-annotation))))
+    `(web-mode-css-function-face ((,class (:foreground ,nord-method))))
+    `(web-mode-css-property-name-face ((,class (:foreground ,nord-keyword))))
+    `(web-mode-css-pseudo-class-face ((,class (:foreground ,nord-class))))
+    `(web-mode-css-selector-face ((,class (:foreground ,nord-keyword))))
+    `(web-mode-css-string-face ((,class (:foreground ,nord-string))))
+    `(web-mode-doctype-face ((,class (:foreground ,nord-preprocessor))))
+    `(web-mode-function-call-face ((,class (:foreground ,nord-method))))
+    `(web-mode-function-name-face ((,class (:foreground ,nord-method))))
+    `(web-mode-html-attr-name-face ((,class (:foreground ,nord-attribute))))
+    `(web-mode-html-attr-equal-face ((,class (:foreground ,nord-punctuation))))
+    `(web-mode-html-attr-value-face ((,class (:foreground ,nord-string))))
+    `(web-mode-html-entity-face ((,class (:foreground ,nord-keyword))))
+    `(web-mode-html-tag-bracket-face ((,class (:foreground ,nord-punctuation))))
+    `(web-mode-html-tag-custom-face ((,class (:foreground ,nord-tag))))
+    `(web-mode-html-tag-face ((,class (:foreground ,nord-tag))))
+    `(web-mode-html-tag-namespaced-face ((,class (:foreground ,nord-keyword))))
+    `(web-mode-json-key-face ((,class (:foreground ,nord-class))))
+    `(web-mode-json-string-face ((,class (:foreground ,nord-string))))
+    `(web-mode-keyword-face ((,class (:foreground ,nord-keyword))))
+    `(web-mode-preprocessor-face ((,class (:foreground ,nord-preprocessor))))
+    `(web-mode-string-face ((,class (:foreground ,nord-string))))
+    `(web-mode-symbol-face ((,class (:foreground ,nord-variable))))
+    `(web-mode-type-face ((,class (:foreground ,nord-class))))
+    `(web-mode-warning-face ((,class (:inherit ,font-lock-warning-face))))
+    `(web-mode-variable-name-face ((,class (:foreground ,nord-variable))))
+
+    ;; +--- UI ---+
+    ;; > Anzu
+    `(anzu-mode-line ((,class (:foreground, nord8))))
+    `(anzu-mode-line-no-match ((,class (:foreground, nord11))))
+
+    ;; > Avy
+    `(avy-lead-face ((,class (:background ,nord11 :foreground ,nord5))))
+    `(avy-lead-face-0 ((,class (:background ,nord10 :foreground ,nord5))))
+    `(avy-lead-face-1 ((,class (:background ,nord3 :foreground ,nord5))))
+    `(avy-lead-face-2 ((,class (:background ,nord15 :foreground ,nord5))))
+
+    ;; > Company
+    `(company-echo-common ((,class (:foreground ,nord0 :background ,nord4))))
+    `(company-preview ((,class (:foreground ,nord4 :background ,nord10))))
+    `(company-preview-common ((,class (:foreground ,nord0 :background ,nord8))))
+    `(company-preview-search ((,class (:foreground ,nord0 :background ,nord8))))
+    `(company-scrollbar-bg ((,class (:foreground ,nord1 :background ,nord1))))
+    `(company-scrollbar-fg ((,class (:foreground ,nord2 :background ,nord2))))
+    `(company-template-field ((,class (:foreground ,nord0 :background ,nord7))))
+    `(company-tooltip ((,class (:foreground ,nord4 :background ,nord2))))
+    `(company-tooltip-annotation ((,class (:foreground ,nord12))))
+    `(company-tooltip-annotation-selection ((,class (:foreground ,nord12 :weight bold))))
+    `(company-tooltip-common ((,class (:foreground ,nord8))))
+    `(company-tooltip-common-selection ((,class (:foreground ,nord8 :background ,nord3))))
+    `(company-tooltip-mouse ((,class (:inherit highlight))))
+    `(company-tooltip-selection ((,class (:background ,nord3 :weight bold))))
+
+    ;; > diff-hl
+   `(diff-hl-change ((,class (:background ,nord13))))
+   `(diff-hl-insert ((,class (:background ,nord14))))
+   `(diff-hl-delete ((,class (:background ,nord11))))
+   
+    ;; > Evil
+    `(evil-ex-info ((,class (:foreground ,nord8))))
+    `(evil-ex-substitute-replacement ((,class (:foreground ,nord9))))
+    `(evil-ex-substitute-matches ((,class (:inherit isearch))))
+
+    ;; > Flycheck
+    `(flycheck-error ((,class (:underline (:style wave :color ,nord11)))))
+    `(flycheck-fringe-error ((,class (:foreground ,nord11 :weight bold))))
+    `(flycheck-fringe-info ((,class (:foreground ,nord8 :weight bold))))
+    `(flycheck-fringe-warning ((,class (:foreground ,nord13 :weight bold))))
+    `(flycheck-info ((,class (:underline (:style wave :color ,nord8)))))
+    `(flycheck-warning ((,class (:underline (:style wave :color ,nord13)))))
+
+    ;; > Git Gutter
+    `(git-gutter:modified ((,class (:foreground ,nord13))))
+    `(git-gutter:added ((,class (:foreground ,nord14))))
+    `(git-gutter:deleted ((,class (:foreground ,nord11))))
+
+    ;; > Git Gutter Plus
+    `(git-gutter+-modified ((,class (:foreground ,nord13))))
+    `(git-gutter+-added ((,class (:foreground ,nord14))))
+    `(git-gutter+-deleted ((,class (:foreground ,nord11))))
+
+    ;; > Helm
+    `(helm-bookmark-addressbook ((,class (:foreground ,nord7))))
+    `(helm-bookmark-directory ((,class (:foreground ,nord9))))
+    `(helm-bookmark-file ((,class (:foreground ,nord8))))
+    `(helm-bookmark-gnus ((,class (:foreground ,nord10))))
+    `(helm-bookmark-info ((,class (:foreground ,nord14))))
+    `(helm-bookmark-man ((,class (:foreground ,nord4))))
+    `(helm-bookmark-w3m ((,class (:foreground ,nord9))))
+    `(helm-buffer-directory ((,class (:foreground ,nord9))))
+    `(helm-buffer-file ((,class (:foreground ,nord8))))
+    `(helm-buffer-not-saved ((,class (:foreground ,nord13))))
+    `(helm-buffer-process ((,class (:foreground ,nord10))))
+    `(helm-candidate-number ((,class (:foreground ,nord4 :weight bold))))
+    `(helm-candidate-number-suspended ((,class (:foreground ,nord4))))
+    `(helm-ff-directory ((,class (:foreground ,nord9 :weight bold))))
+    `(helm-ff-dirs ((,class (:foreground ,nord9))))
+    `(helm-ff-dotted-director ((,class (:foreground ,nord9 :underline t))))
+    `(helm-ff-dotted-symlink-director ((,class (:foreground ,nord7 :weight bold))))
+    `(helm-ff-executable ((,class (:foreground ,nord8))))
+    `(helm-ff-file ((,class (:foreground ,nord4))))
+    `(helm-ff-invalid-symlink ((,class (:foreground ,nord11 :weight bold))))
+    `(helm-ff-prefix ((,class (:foreground ,nord0 :background ,nord9))))
+    `(helm-ff-symlink ((,class (:foreground ,nord7))))
+    `(helm-grep-cmd-line ((,class (:foreground ,nord4 :background ,nord0))))
+    `(helm-grep-file ((,class (:foreground ,nord8))))
+    `(helm-grep-finish ((,class (:foreground ,nord5))))
+    `(helm-grep-lineno ((,class (:foreground ,nord4))))
+    `(helm-grep-match ((,class (:inherit isearch))))
+    `(helm-grep-running ((,class (:foreground ,nord8))))
+    `(helm-header ((,class (:foreground ,nord9 :background ,nord2))))
+    `(helm-header-line-left-margin ((,class (:foreground ,nord9 :background ,nord2))))
+    `(helm-history-deleted ((,class (:foreground ,nord11))))
+    `(helm-history-remote ((,class (:foreground ,nord4))))
+    `(helm-lisp-completion-info ((,class (:foreground ,nord4 :weight bold))))
+    `(helm-lisp-show-completion ((,class (:inherit isearch))))
+    `(helm-locate-finish ((,class (:foreground ,nord14))))
+    `(helm-match ((,class (:foreground ,nord8))))
+    `(helm-match-item ((,class (:inherit isearch))))
+    `(helm-moccur-buffer ((,class (:foreground ,nord8))))
+    `(helm-resume-need-update ((,class (:foreground ,nord0 :background ,nord13))))
+    `(helm-selection ((,class (:inherit highlight))))
+    `(helm-selection-line ((,class (:background ,nord2))))
+    `(helm-source-header ((,class (:height 1.44 :foreground ,nord8 :background ,nord2))))
+    `(helm-swoop-line-number-face ((,class (:foreground ,nord4 :background ,nord0))))
+    `(helm-swoop-target-word-face ((,class (:foreground ,nord0 :background ,nord7))))
+    `(helm-swoop-target-line-face ((,class (:background ,nord13 :foreground ,nord3))))
+    `(helm-swoop-target-line-block-face ((,class (:background ,nord13 :foreground ,nord3))))
+    `(helm-separator ((,class (:background ,nord2))))
+    `(helm-visible-mark ((,class (:background ,nord2))))
+
+    ;; > Magit
+    `(magit-branch ((,class (:foreground ,nord7 :weight bold))))
+    `(magit-diff-context-highlight ((,class (:background ,nord2))))
+    `(magit-diff-file-header ((,class (:foreground ,nord8 :box (:color ,nord8)))))
+    `(magit-diffstat-added ((,class (:foreground ,nord14))))
+    `(magit-diffstat-removed ((,class (:foreground ,nord11))))
+    `(magit-hash ((,class (:foreground ,nord8))))
+    `(magit-hunk-heading ((,class (:foreground ,nord9))))
+    `(magit-hunk-heading-highlight ((,class (:foreground ,nord9 :background ,nord2))))
+    `(magit-item-highlight ((,class (:foreground ,nord8 :background ,nord2))))
+    `(magit-log-author ((,class (:foreground ,nord7))))
+    `(magit-process-ng ((,class (:foreground ,nord13 :weight bold))))
+    `(magit-process-ok ((,class (:foreground ,nord14 :weight bold))))
+    `(magit-section-heading ((,class (:foreground ,nord7 :weight bold))))
+    `(magit-section-highlight ((,class (:background ,nord2))))
+
+    ;; > MU4E
+    `(mu4e-header-marks-face ((,class (:foreground ,nord9))))
+    `(mu4e-title-face ((,class (:foreground ,nord8))))
+    `(mu4e-header-key-face ((,class (:foreground ,nord8))))
+    `(mu4e-highlight-face ((,class (:highlight))))
+    `(mu4e-flagged-face ((,class (:foreground ,nord13))))
+    `(mu4e-unread-face ((,class (:foreground ,nord13 :weight bold))))
+    `(mu4e-link-face ((,class (:underline t))))
+
+    ;; > Powerline
+    `(powerline-active1 ((,class (:foreground ,nord4 :background ,nord1))))
+    `(powerline-active2 ((,class (:foreground ,nord4 :background ,nord3))))
+    `(powerline-inactive1 ((,class (:background ,nord2))))
+    `(powerline-inactive2 ((,class (:background ,nord2))))
+
+    ;; > Powerline Evil
+    `(powerline-evil-base-face ((,class (:foreground ,nord4))))
+    `(powerline-evil-normal-face ((,class (:background ,nord8))))
+    `(powerline-evil-insert-face ((,class (:foreground ,nord0 :background ,nord4))))
+    `(powerline-evil-visual-face ((,class (:foreground ,nord0 :background ,nord7))))
+    `(powerline-evil-replace-face ((,class (:foreground ,nord0 :background ,nord9))))
+
+    ;; > NeoTree
+    `(neo-banner-face ((,class (:foreground ,nord10))))
+    `(neo-dir-link-face ((,class (:foreground ,nord9))))
+    `(neo-expand-btn-face ((,class (:foreground ,nord6 :bold t))))
+    `(neo-file-link-face ((,class (:foreground ,nord4))))
+    `(neo-root-dir-face ((,class (:foreground ,nord7 :weight bold))))
+    `(neo-vc-added-face ((,class (:foreground ,nord14))))
+    `(neo-vc-conflict-face ((,class (:foreground ,nord11))))
+    `(neo-vc-default-face ((,class (:foreground ,nord4))))
+    `(neo-vc-edited-face ((,class (:foreground ,nord13))))
+    `(neo-vc-ignored-face ((,class (:foreground ,nord3))))
+    `(neo-vc-missing-face ((,class (:foreground ,nord12))))
+    `(neo-vc-needs-merge-face ((,class (:background ,nord12 :foreground ,nord4))))
+    `(neo-vc-needs-update-face ((,class (:background ,nord10 :foreground ,nord4))))
+    `(neo-vc-removed-face ((,class (:foreground ,nord11 :strike-through nil))))
+    `(neo-vc-up-to-date-face ((,class (:foreground ,nord4))))
+    `(neo-vc-user-face ((,class (:foreground ,nord4))))
+
+    ;; > Cider
+    `(cider-result-overlay-face ((t (:background unspecified))))
+
+    ;; > Org
+    `(org-level-1 ((,class (:foreground ,nord7 :weight extra-bold))))
+    `(org-level-2 ((,class (:foreground ,nord8 :weight bold))))
+    `(org-level-3 ((,class (:foreground ,nord9 :weight semi-bold))))
+    `(org-level-4 ((,class (:foreground ,nord10 :weight normal))))
+    `(org-level-5 ((,class (:inherit org-level-4))))
+    `(org-level-6 ((,class (:inherit org-level-4))))
+    `(org-level-7 ((,class (:inherit org-level-4))))
+    `(org-level-8 ((,class (:inherit org-level-4))))
+    `(org-agenda-structure ((,class (:foreground ,nord9))))
+    `(org-agenda-date ((,class (:foreground ,nord8 :underline nil))))
+    `(org-agenda-done ((,class (:foreground ,nord14))))
+    `(org-agenda-dimmed-todo-face ((,class (:background ,nord13))))
+    `(org-block ((,class (:foreground ,nord4))))
+    `(org-block-background ((,class (:background ,nord0))))
+    `(org-block-begin-line ((,class (:foreground ,nord7))))
+    `(org-block-end-line ((,class (:foreground ,nord7))))
+    `(org-checkbox ((,class (:foreground ,nord9))))
+    `(org-checkbox-statistics-done ((,class (:foreground ,nord14))))
+    `(org-checkbox-statistics-todo ((,class (:foreground ,nord13))))
+    `(org-code ((,class (:foreground ,nord7))))
+    `(org-column ((,class (:background ,nord2))))
+    `(org-column-title ((,class (:inherit org-column :weight bold :underline t))))
+    `(org-date ((,class (:foreground ,nord8))))
+    `(org-document-info ((,class (:foreground ,nord4))))
+    `(org-document-info-keyword ((,class (:foreground ,nord3 :weight bold))))
+    `(org-document-title ((,class (:foreground ,nord8 :weight bold))))
+    `(org-done ((,class (:foreground ,nord14 :weight bold))))
+    `(org-ellipsis ((,class (:foreground ,nord3))))
+    `(org-footnote ((,class (:foreground ,nord8))))
+    `(org-formula ((,class (:foreground ,nord9))))
+    `(org-hide ((,class (:foreground ,nord0 :background ,nord0))))
+    `(org-link ((,class (:underline t))))
+    `(org-scheduled ((,class (:foreground ,nord14))))
+    `(org-scheduled-previously ((,class (:foreground ,nord13))))
+    `(org-scheduled-today ((,class (:foreground ,nord8))))
+    `(org-special-keyword ((,class (:foreground ,nord9))))
+    `(org-table ((,class (:foreground ,nord9))))
+    `(org-todo ((,class (:foreground ,nord13 :weight bold))))
+    `(org-upcoming-deadline ((,class (:foreground ,nord12))))
+    `(org-warning ((,class (:foreground ,nord13 :weight bold))))
+    `(font-latex-bold-face ((,class (:inherit bold))))
+    `(font-latex-italic-face ((,class (:slant italic))))
+    `(font-latex-string-face ((,class (:foreground ,nord14))))
+    `(font-latex-match-reference-keywords ((,class (:foreground ,nord9))))
+    `(font-latex-match-variable-keywords ((,class (:foreground ,nord4))))
+    `(ido-only-match ((,class (:foreground ,nord8))))
+    `(org-sexp-date ((,class (:foreground ,nord7))))
+    `(ido-first-match ((,class (:foreground ,nord8 :weight bold))))
+    `(ido-subdir ((,class (:foreground ,nord9))))
+    `(org-quote ((,class (:inherit org-block :slant italic))))
+    `(org-verse ((,class (:inherit org-block :slant italic))))
+    `(org-agenda-date-weekend ((,class (:foreground ,nord9))))
+    `(org-agenda-date-today ((,class (:foreground ,nord8 :weight bold))))
+    `(org-agenda-done ((,class (:foreground ,nord14))))
+    `(org-verbatim ((,class (:foreground ,nord7))))
+
+    ;; > ivy-mode
+    `(ivy-current-match ((,class (:inherit region))))
+    `(ivy-minibuffer-match-face-1 ((,class (:inherit default))))
+    `(ivy-minibuffer-match-face-2 ((,class (:background ,nord7 :foreground ,nord0))))
+    `(ivy-minibuffer-match-face-3 ((,class (:background ,nord8 :foreground ,nord0))))
+    `(ivy-minibuffer-match-face-4 ((,class (:background ,nord9 :foreground ,nord0))))
+    `(ivy-remote ((,class (:foreground ,nord14))))))
+
+;;;###autoload
+(when (and (boundp 'custom-theme-load-path) load-file-name)
+  (add-to-list 'custom-theme-load-path
+    (file-name-as-directory (file-name-directory load-file-name))))
+
+(provide-theme 'nord)
+
+;; Local Variables:
+;; no-byte-compile: t
+;; indent-tabs-mode: nil
+;; End:
+
+;;; nord-theme.el ends here
diff --git a/home/kurb42/.gitconfig b/home/kurb42/.gitconfig
new file mode 100644
index 0000000..97dd1be
--- /dev/null
+++ b/home/kurb42/.gitconfig
@@ -0,0 +1,3 @@
+[user]
+	email = kurb42@riseup.net
+	name = kurb42
diff --git a/home/kurb42/.mutt/account.net.riseup.kurb42 b/home/kurb42/.mutt/account.net.riseup.kurb42
new file mode 100644
index 0000000..ca585da
--- /dev/null
+++ b/home/kurb42/.mutt/account.net.riseup.kurb42
@@ -0,0 +1,14 @@
+set realname  = 'kurb42'
+set from      = kurb42@riseup.net
+set smtp_url  = smtps://kurb42@mail.riseup.net/
+set ssl_force_tls = yes
+set ssl_starttls  = yes
+set imap_user = kurb42@riseup.net
+set folder    = imaps://kurb42@mail.riseup.net/
+set imap_check_subscribed
+set spoolfile = +INBOX
+set postponed = +Drafts
+set record    = +Sent
+set header_cache = ~/.mutt/net.riseup.kurb42/cache/headers            
+set message_cachedir = ~/.mutt/net.riseup.kurb42/cache/bodies         
+set certificate_file = ~/.mutt/net.riseup.kurb42/certificates
\ No newline at end of file
diff --git a/home/kurb42/.mutt/muttrc b/home/kurb42/.mutt/muttrc
new file mode 100644
index 0000000..44edb0b
--- /dev/null
+++ b/home/kurb42/.mutt/muttrc
@@ -0,0 +1,11 @@
+# Folder hooks
+folder-hook 'account.net.riseup.kurb42' 'source ~/.mutt/account.net.riseup.kurb42'
+
+# Default account
+source ~/.mutt/account.net.riseup.kurb42         
+
+# Macros for switching accounts
+macro index <f2> '<sync-mailbox><enter-command>source ~/.mutt/account.net.riseup.kurb42<enter><change-folder>!<enter>'
+
+# Fetch mail shortcut
+bind index G imap-fetch-mail
diff --git a/home/kurb42/.vim/autoload/plug.vim b/home/kurb42/.vim/autoload/plug.vim
new file mode 100644
index 0000000..6a958cb
--- /dev/null
+++ b/home/kurb42/.vim/autoload/plug.vim
@@ -0,0 +1,2801 @@
+" vim-plug: Vim plugin manager
+" ============================
+"
+" Download plug.vim and put it in ~/.vim/autoload
+"
+"   curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
+"     https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
+"
+" Edit your .vimrc
+"
+"   call plug#begin('~/.vim/plugged')
+"
+"   " Make sure you use single quotes
+"
+"   " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align
+"   Plug 'junegunn/vim-easy-align'
+"
+"   " Any valid git URL is allowed
+"   Plug 'https://github.com/junegunn/vim-github-dashboard.git'
+"
+"   " Multiple Plug commands can be written in a single line using | separators
+"   Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
+"
+"   " On-demand loading
+"   Plug 'scrooloose/nerdtree', { 'on':  'NERDTreeToggle' }
+"   Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
+"
+"   " Using a non-default branch
+"   Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
+"
+"   " Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
+"   Plug 'fatih/vim-go', { 'tag': '*' }
+"
+"   " Plugin options
+"   Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' }
+"
+"   " Plugin outside ~/.vim/plugged with post-update hook
+"   Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
+"
+"   " Unmanaged plugin (manually installed and updated)
+"   Plug '~/my-prototype-plugin'
+"
+"   " Initialize plugin system
+"   call plug#end()
+"
+" Then reload .vimrc and :PlugInstall to install plugins.
+"
+" Plug options:
+"
+"| Option                  | Description                                      |
+"| ----------------------- | ------------------------------------------------ |
+"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use       |
+"| `rtp`                   | Subdirectory that contains Vim plugin            |
+"| `dir`                   | Custom directory for the plugin                  |
+"| `as`                    | Use different name for the plugin                |
+"| `do`                    | Post-update hook (string or funcref)             |
+"| `on`                    | On-demand loading: Commands or `<Plug>`-mappings |
+"| `for`                   | On-demand loading: File types                    |
+"| `frozen`                | Do not update unless explicitly specified        |
+"
+" More information: https://github.com/junegunn/vim-plug
+"
+"
+" Copyright (c) 2017 Junegunn Choi
+"
+" MIT License
+"
+" Permission is hereby granted, free of charge, to any person obtaining
+" a copy of this software and associated documentation files (the
+" "Software"), to deal in the Software without restriction, including
+" without limitation the rights to use, copy, modify, merge, publish,
+" distribute, sublicense, and/or sell copies of the Software, and to
+" permit persons to whom the Software is furnished to do so, subject to
+" the following conditions:
+"
+" The above copyright notice and this permission notice shall be
+" included in all copies or substantial portions of the Software.
+"
+" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+if exists('g:loaded_plug')
+  finish
+endif
+let g:loaded_plug = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+let s:plug_src = 'https://github.com/junegunn/vim-plug.git'
+let s:plug_tab = get(s:, 'plug_tab', -1)
+let s:plug_buf = get(s:, 'plug_buf', -1)
+let s:mac_gui = has('gui_macvim') && has('gui_running')
+let s:is_win = has('win32')
+let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win)
+let s:vim8 = has('patch-8.0.0039') && exists('*job_start')
+if s:is_win && &shellslash
+  set noshellslash
+  let s:me = resolve(expand('<sfile>:p'))
+  set shellslash
+else
+  let s:me = resolve(expand('<sfile>:p'))
+endif
+let s:base_spec = { 'branch': '', 'frozen': 0 }
+let s:TYPE = {
+\   'string':  type(''),
+\   'list':    type([]),
+\   'dict':    type({}),
+\   'funcref': type(function('call'))
+\ }
+let s:loaded = get(s:, 'loaded', {})
+let s:triggers = get(s:, 'triggers', {})
+
+function! s:is_powershell(shell)
+  return a:shell =~# 'powershell\(\.exe\)\?$' || a:shell =~# 'pwsh\(\.exe\)\?$'
+endfunction
+
+function! s:isabsolute(dir) abort
+  return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)')
+endfunction
+
+function! s:git_dir(dir) abort
+  let gitdir = s:trim(a:dir) . '/.git'
+  if isdirectory(gitdir)
+    return gitdir
+  endif
+  if !filereadable(gitdir)
+    return ''
+  endif
+  let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*')
+  if len(gitdir) && !s:isabsolute(gitdir)
+    let gitdir = a:dir . '/' . gitdir
+  endif
+  return isdirectory(gitdir) ? gitdir : ''
+endfunction
+
+function! s:git_origin_url(dir) abort
+  let gitdir = s:git_dir(a:dir)
+  let config = gitdir . '/config'
+  if empty(gitdir) || !filereadable(config)
+    return ''
+  endif
+  return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze')
+endfunction
+
+function! s:git_revision(dir) abort
+  let gitdir = s:git_dir(a:dir)
+  let head = gitdir . '/HEAD'
+  if empty(gitdir) || !filereadable(head)
+    return ''
+  endif
+
+  let line = get(readfile(head), 0, '')
+  let ref = matchstr(line, '^ref: \zs.*')
+  if empty(ref)
+    return line
+  endif
+
+  if filereadable(gitdir . '/' . ref)
+    return get(readfile(gitdir . '/' . ref), 0, '')
+  endif
+
+  if filereadable(gitdir . '/packed-refs')
+    for line in readfile(gitdir . '/packed-refs')
+      if line =~# ' ' . ref
+        return matchstr(line, '^[0-9a-f]*')
+      endif
+    endfor
+  endif
+
+  return ''
+endfunction
+
+function! s:git_local_branch(dir) abort
+  let gitdir = s:git_dir(a:dir)
+  let head = gitdir . '/HEAD'
+  if empty(gitdir) || !filereadable(head)
+    return ''
+  endif
+  let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*')
+  return len(branch) ? branch : 'HEAD'
+endfunction
+
+function! s:git_origin_branch(spec)
+  if len(a:spec.branch)
+    return a:spec.branch
+  endif
+
+  " The file may not be present if this is a local repository
+  let gitdir = s:git_dir(a:spec.dir)
+  let origin_head = gitdir.'/refs/remotes/origin/HEAD'
+  if len(gitdir) && filereadable(origin_head)
+    return matchstr(get(readfile(origin_head), 0, ''),
+                  \ '^ref: refs/remotes/origin/\zs.*')
+  endif
+
+  " The command may not return the name of a branch in detached HEAD state
+  let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir))
+  return v:shell_error ? '' : result[-1]
+endfunction
+
+if s:is_win
+  function! s:plug_call(fn, ...)
+    let shellslash = &shellslash
+    try
+      set noshellslash
+      return call(a:fn, a:000)
+    finally
+      let &shellslash = shellslash
+    endtry
+  endfunction
+else
+  function! s:plug_call(fn, ...)
+    return call(a:fn, a:000)
+  endfunction
+endif
+
+function! s:plug_getcwd()
+  return s:plug_call('getcwd')
+endfunction
+
+function! s:plug_fnamemodify(fname, mods)
+  return s:plug_call('fnamemodify', a:fname, a:mods)
+endfunction
+
+function! s:plug_expand(fmt)
+  return s:plug_call('expand', a:fmt, 1)
+endfunction
+
+function! s:plug_tempname()
+  return s:plug_call('tempname')
+endfunction
+
+function! plug#begin(...)
+  if a:0 > 0
+    let s:plug_home_org = a:1
+    let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p'))
+  elseif exists('g:plug_home')
+    let home = s:path(g:plug_home)
+  elseif !empty(&rtp)
+    let home = s:path(split(&rtp, ',')[0]) . '/plugged'
+  else
+    return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.')
+  endif
+  if s:plug_fnamemodify(home, ':t') ==# 'plugin' && s:plug_fnamemodify(home, ':h') ==# s:first_rtp
+    return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.')
+  endif
+
+  let g:plug_home = home
+  let g:plugs = {}
+  let g:plugs_order = []
+  let s:triggers = {}
+
+  call s:define_commands()
+  return 1
+endfunction
+
+function! s:define_commands()
+  command! -nargs=+ -bar Plug call plug#(<args>)
+  if !executable('git')
+    return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.')
+  endif
+  if has('win32')
+  \ && &shellslash
+  \ && (&shell =~# 'cmd\(\.exe\)\?$' || s:is_powershell(&shell))
+    return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.')
+  endif
+  if !has('nvim')
+    \ && (has('win32') || has('win32unix'))
+    \ && !has('multi_byte')
+    return s:err('Vim needs +multi_byte feature on Windows to run shell commands. Enable +iconv for best results.')
+  endif
+  command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(<bang>0, [<f-args>])
+  command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate  call s:update(<bang>0, [<f-args>])
+  command! -nargs=0 -bar -bang PlugClean call s:clean(<bang>0)
+  command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif
+  command! -nargs=0 -bar PlugStatus  call s:status()
+  command! -nargs=0 -bar PlugDiff    call s:diff()
+  command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(<bang>0, <f-args>)
+endfunction
+
+function! s:to_a(v)
+  return type(a:v) == s:TYPE.list ? a:v : [a:v]
+endfunction
+
+function! s:to_s(v)
+  return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n"
+endfunction
+
+function! s:glob(from, pattern)
+  return s:lines(globpath(a:from, a:pattern))
+endfunction
+
+function! s:source(from, ...)
+  let found = 0
+  for pattern in a:000
+    for vim in s:glob(a:from, pattern)
+      execute 'source' s:esc(vim)
+      let found = 1
+    endfor
+  endfor
+  return found
+endfunction
+
+function! s:assoc(dict, key, val)
+  let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
+endfunction
+
+function! s:ask(message, ...)
+  call inputsave()
+  echohl WarningMsg
+  let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
+  echohl None
+  call inputrestore()
+  echo "\r"
+  return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0
+endfunction
+
+function! s:ask_no_interrupt(...)
+  try
+    return call('s:ask', a:000)
+  catch
+    return 0
+  endtry
+endfunction
+
+function! s:lazy(plug, opt)
+  return has_key(a:plug, a:opt) &&
+        \ (empty(s:to_a(a:plug[a:opt]))         ||
+        \  !isdirectory(a:plug.dir)             ||
+        \  len(s:glob(s:rtp(a:plug), 'plugin')) ||
+        \  len(s:glob(s:rtp(a:plug), 'after/plugin')))
+endfunction
+
+function! plug#end()
+  if !exists('g:plugs')
+    return s:err('plug#end() called without calling plug#begin() first')
+  endif
+
+  if exists('#PlugLOD')
+    augroup PlugLOD
+      autocmd!
+    augroup END
+    augroup! PlugLOD
+  endif
+  let lod = { 'ft': {}, 'map': {}, 'cmd': {} }
+
+  if exists('g:did_load_filetypes')
+    filetype off
+  endif
+  for name in g:plugs_order
+    if !has_key(g:plugs, name)
+      continue
+    endif
+    let plug = g:plugs[name]
+    if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for')
+      let s:loaded[name] = 1
+      continue
+    endif
+
+    if has_key(plug, 'on')
+      let s:triggers[name] = { 'map': [], 'cmd': [] }
+      for cmd in s:to_a(plug.on)
+        if cmd =~? '^<Plug>.\+'
+          if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i'))
+            call s:assoc(lod.map, cmd, name)
+          endif
+          call add(s:triggers[name].map, cmd)
+        elseif cmd =~# '^[A-Z]'
+          let cmd = substitute(cmd, '!*$', '', '')
+          if exists(':'.cmd) != 2
+            call s:assoc(lod.cmd, cmd, name)
+          endif
+          call add(s:triggers[name].cmd, cmd)
+        else
+          call s:err('Invalid `on` option: '.cmd.
+          \ '. Should start with an uppercase letter or `<Plug>`.')
+        endif
+      endfor
+    endif
+
+    if has_key(plug, 'for')
+      let types = s:to_a(plug.for)
+      if !empty(types)
+        augroup filetypedetect
+        call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim')
+        augroup END
+      endif
+      for type in types
+        call s:assoc(lod.ft, type, name)
+      endfor
+    endif
+  endfor
+
+  for [cmd, names] in items(lod.cmd)
+    execute printf(
+    \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "<bang>", <line1>, <line2>, <q-args>, %s)',
+    \ cmd, string(cmd), string(names))
+  endfor
+
+  for [map, names] in items(lod.map)
+    for [mode, map_prefix, key_prefix] in
+          \ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
+      execute printf(
+      \ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>',
+      \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix)
+    endfor
+  endfor
+
+  for [ft, names] in items(lod.ft)
+    augroup PlugLOD
+      execute printf('autocmd FileType %s call <SID>lod_ft(%s, %s)',
+            \ ft, string(ft), string(names))
+    augroup END
+  endfor
+
+  call s:reorg_rtp()
+  filetype plugin indent on
+  if has('vim_starting')
+    if has('syntax') && !exists('g:syntax_on')
+      syntax enable
+    end
+  else
+    call s:reload_plugins()
+  endif
+endfunction
+
+function! s:loaded_names()
+  return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)')
+endfunction
+
+function! s:load_plugin(spec)
+  call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
+endfunction
+
+function! s:reload_plugins()
+  for name in s:loaded_names()
+    call s:load_plugin(g:plugs[name])
+  endfor
+endfunction
+
+function! s:trim(str)
+  return substitute(a:str, '[\/]\+$', '', '')
+endfunction
+
+function! s:version_requirement(val, min)
+  for idx in range(0, len(a:min) - 1)
+    let v = get(a:val, idx, 0)
+    if     v < a:min[idx] | return 0
+    elseif v > a:min[idx] | return 1
+    endif
+  endfor
+  return 1
+endfunction
+
+function! s:git_version_requirement(...)
+  if !exists('s:git_version')
+    let s:git_version = map(split(split(s:system(['git', '--version']))[2], '\.'), 'str2nr(v:val)')
+  endif
+  return s:version_requirement(s:git_version, a:000)
+endfunction
+
+function! s:progress_opt(base)
+  return a:base && !s:is_win &&
+        \ s:git_version_requirement(1, 7, 1) ? '--progress' : ''
+endfunction
+
+function! s:rtp(spec)
+  return s:path(a:spec.dir . get(a:spec, 'rtp', ''))
+endfunction
+
+if s:is_win
+  function! s:path(path)
+    return s:trim(substitute(a:path, '/', '\', 'g'))
+  endfunction
+
+  function! s:dirpath(path)
+    return s:path(a:path) . '\'
+  endfunction
+
+  function! s:is_local_plug(repo)
+    return a:repo =~? '^[a-z]:\|^[%~]'
+  endfunction
+
+  " Copied from fzf
+  function! s:wrap_cmds(cmds)
+    let cmds = [
+      \ '@echo off',
+      \ 'setlocal enabledelayedexpansion']
+    \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds])
+    \ + ['endlocal']
+    if has('iconv')
+      if !exists('s:codepage')
+        let s:codepage = libcallnr('kernel32.dll', 'GetACP', 0)
+      endif
+      return map(cmds, printf('iconv(v:val."\r", "%s", "cp%d")', &encoding, s:codepage))
+    endif
+    return map(cmds, 'v:val."\r"')
+  endfunction
+
+  function! s:batchfile(cmd)
+    let batchfile = s:plug_tempname().'.bat'
+    call writefile(s:wrap_cmds(a:cmd), batchfile)
+    let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0})
+    if s:is_powershell(&shell)
+      let cmd = '& ' . cmd
+    endif
+    return [batchfile, cmd]
+  endfunction
+else
+  function! s:path(path)
+    return s:trim(a:path)
+  endfunction
+
+  function! s:dirpath(path)
+    return substitute(a:path, '[/\\]*$', '/', '')
+  endfunction
+
+  function! s:is_local_plug(repo)
+    return a:repo[0] =~ '[/$~]'
+  endfunction
+endif
+
+function! s:err(msg)
+  echohl ErrorMsg
+  echom '[vim-plug] '.a:msg
+  echohl None
+endfunction
+
+function! s:warn(cmd, msg)
+  echohl WarningMsg
+  execute a:cmd 'a:msg'
+  echohl None
+endfunction
+
+function! s:esc(path)
+  return escape(a:path, ' ')
+endfunction
+
+function! s:escrtp(path)
+  return escape(a:path, ' ,')
+endfunction
+
+function! s:remove_rtp()
+  for name in s:loaded_names()
+    let rtp = s:rtp(g:plugs[name])
+    execute 'set rtp-='.s:escrtp(rtp)
+    let after = globpath(rtp, 'after')
+    if isdirectory(after)
+      execute 'set rtp-='.s:escrtp(after)
+    endif
+  endfor
+endfunction
+
+function! s:reorg_rtp()
+  if !empty(s:first_rtp)
+    execute 'set rtp-='.s:first_rtp
+    execute 'set rtp-='.s:last_rtp
+  endif
+
+  " &rtp is modified from outside
+  if exists('s:prtp') && s:prtp !=# &rtp
+    call s:remove_rtp()
+    unlet! s:middle
+  endif
+
+  let s:middle = get(s:, 'middle', &rtp)
+  let rtps     = map(s:loaded_names(), 's:rtp(g:plugs[v:val])')
+  let afters   = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)')
+  let rtp      = join(map(rtps, 'escape(v:val, ",")'), ',')
+                 \ . ','.s:middle.','
+                 \ . join(map(afters, 'escape(v:val, ",")'), ',')
+  let &rtp     = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g')
+  let s:prtp   = &rtp
+
+  if !empty(s:first_rtp)
+    execute 'set rtp^='.s:first_rtp
+    execute 'set rtp+='.s:last_rtp
+  endif
+endfunction
+
+function! s:doautocmd(...)
+  if exists('#'.join(a:000, '#'))
+    execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '<nomodeline>' : '') join(a:000)
+  endif
+endfunction
+
+function! s:dobufread(names)
+  for name in a:names
+    let path = s:rtp(g:plugs[name])
+    for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin']
+      if len(finddir(dir, path))
+        if exists('#BufRead')
+          doautocmd BufRead
+        endif
+        return
+      endif
+    endfor
+  endfor
+endfunction
+
+function! plug#load(...)
+  if a:0 == 0
+    return s:err('Argument missing: plugin name(s) required')
+  endif
+  if !exists('g:plugs')
+    return s:err('plug#begin was not called')
+  endif
+  let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000
+  let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)')
+  if !empty(unknowns)
+    let s = len(unknowns) > 1 ? 's' : ''
+    return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', ')))
+  end
+  let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)')
+  if !empty(unloaded)
+    for name in unloaded
+      call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
+    endfor
+    call s:dobufread(unloaded)
+    return 1
+  end
+  return 0
+endfunction
+
+function! s:remove_triggers(name)
+  if !has_key(s:triggers, a:name)
+    return
+  endif
+  for cmd in s:triggers[a:name].cmd
+    execute 'silent! delc' cmd
+  endfor
+  for map in s:triggers[a:name].map
+    execute 'silent! unmap' map
+    execute 'silent! iunmap' map
+  endfor
+  call remove(s:triggers, a:name)
+endfunction
+
+function! s:lod(names, types, ...)
+  for name in a:names
+    call s:remove_triggers(name)
+    let s:loaded[name] = 1
+  endfor
+  call s:reorg_rtp()
+
+  for name in a:names
+    let rtp = s:rtp(g:plugs[name])
+    for dir in a:types
+      call s:source(rtp, dir.'/**/*.vim')
+    endfor
+    if a:0
+      if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2))
+        execute 'runtime' a:1
+      endif
+      call s:source(rtp, a:2)
+    endif
+    call s:doautocmd('User', name)
+  endfor
+endfunction
+
+function! s:lod_ft(pat, names)
+  let syn = 'syntax/'.a:pat.'.vim'
+  call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn)
+  execute 'autocmd! PlugLOD FileType' a:pat
+  call s:doautocmd('filetypeplugin', 'FileType')
+  call s:doautocmd('filetypeindent', 'FileType')
+endfunction
+
+function! s:lod_cmd(cmd, bang, l1, l2, args, names)
+  call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
+  call s:dobufread(a:names)
+  execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args)
+endfunction
+
+function! s:lod_map(map, names, with_prefix, prefix)
+  call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
+  call s:dobufread(a:names)
+  let extra = ''
+  while 1
+    let c = getchar(0)
+    if c == 0
+      break
+    endif
+    let extra .= nr2char(c)
+  endwhile
+
+  if a:with_prefix
+    let prefix = v:count ? v:count : ''
+    let prefix .= '"'.v:register.a:prefix
+    if mode(1) == 'no'
+      if v:operator == 'c'
+        let prefix = "\<esc>" . prefix
+      endif
+      let prefix .= v:operator
+    endif
+    call feedkeys(prefix, 'n')
+  endif
+  call feedkeys(substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
+endfunction
+
+function! plug#(repo, ...)
+  if a:0 > 1
+    return s:err('Invalid number of arguments (1..2)')
+  endif
+
+  try
+    let repo = s:trim(a:repo)
+    let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec
+    let name = get(opts, 'as', s:plug_fnamemodify(repo, ':t:s?\.git$??'))
+    let spec = extend(s:infer_properties(name, repo), opts)
+    if !has_key(g:plugs, name)
+      call add(g:plugs_order, name)
+    endif
+    let g:plugs[name] = spec
+    let s:loaded[name] = get(s:loaded, name, 0)
+  catch
+    return s:err(repo . ' ' . v:exception)
+  endtry
+endfunction
+
+function! s:parse_options(arg)
+  let opts = copy(s:base_spec)
+  let type = type(a:arg)
+  let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)'
+  if type == s:TYPE.string
+    if empty(a:arg)
+      throw printf(opt_errfmt, 'tag', 'string')
+    endif
+    let opts.tag = a:arg
+  elseif type == s:TYPE.dict
+    for opt in ['branch', 'tag', 'commit', 'rtp', 'dir', 'as']
+      if has_key(a:arg, opt)
+      \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt]))
+        throw printf(opt_errfmt, opt, 'string')
+      endif
+    endfor
+    for opt in ['on', 'for']
+      if has_key(a:arg, opt)
+      \ && type(a:arg[opt]) != s:TYPE.list
+      \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt]))
+        throw printf(opt_errfmt, opt, 'string or list')
+      endif
+    endfor
+    if has_key(a:arg, 'do')
+      \ && type(a:arg.do) != s:TYPE.funcref
+      \ && (type(a:arg.do) != s:TYPE.string || empty(a:arg.do))
+        throw printf(opt_errfmt, 'do', 'string or funcref')
+    endif
+    call extend(opts, a:arg)
+    if has_key(opts, 'dir')
+      let opts.dir = s:dirpath(s:plug_expand(opts.dir))
+    endif
+  else
+    throw 'Invalid argument type (expected: string or dictionary)'
+  endif
+  return opts
+endfunction
+
+function! s:infer_properties(name, repo)
+  let repo = a:repo
+  if s:is_local_plug(repo)
+    return { 'dir': s:dirpath(s:plug_expand(repo)) }
+  else
+    if repo =~ ':'
+      let uri = repo
+    else
+      if repo !~ '/'
+        throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo)
+      endif
+      let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git')
+      let uri = printf(fmt, repo)
+    endif
+    return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri }
+  endif
+endfunction
+
+function! s:install(force, names)
+  call s:update_impl(0, a:force, a:names)
+endfunction
+
+function! s:update(force, names)
+  call s:update_impl(1, a:force, a:names)
+endfunction
+
+function! plug#helptags()
+  if !exists('g:plugs')
+    return s:err('plug#begin was not called')
+  endif
+  for spec in values(g:plugs)
+    let docd = join([s:rtp(spec), 'doc'], '/')
+    if isdirectory(docd)
+      silent! execute 'helptags' s:esc(docd)
+    endif
+  endfor
+  return 1
+endfunction
+
+function! s:syntax()
+  syntax clear
+  syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber
+  syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX
+  syn match plugNumber /[0-9]\+[0-9.]*/ contained
+  syn match plugBracket /[[\]]/ contained
+  syn match plugX /x/ contained
+  syn match plugDash /^-\{1}\ /
+  syn match plugPlus /^+/
+  syn match plugStar /^*/
+  syn match plugMessage /\(^- \)\@<=.*/
+  syn match plugName /\(^- \)\@<=[^ ]*:/
+  syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/
+  syn match plugTag /(tag: [^)]\+)/
+  syn match plugInstall /\(^+ \)\@<=[^:]*/
+  syn match plugUpdate /\(^* \)\@<=[^:]*/
+  syn match plugCommit /^  \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag
+  syn match plugEdge /^  \X\+$/
+  syn match plugEdge /^  \X*/ contained nextgroup=plugSha
+  syn match plugSha /[0-9a-f]\{7,9}/ contained
+  syn match plugRelDate /([^)]*)$/ contained
+  syn match plugNotLoaded /(not loaded)$/
+  syn match plugError /^x.*/
+  syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
+  syn match plugH2 /^.*:\n-\+$/
+  syn match plugH2 /^-\{2,}/
+  syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
+  hi def link plug1       Title
+  hi def link plug2       Repeat
+  hi def link plugH2      Type
+  hi def link plugX       Exception
+  hi def link plugBracket Structure
+  hi def link plugNumber  Number
+
+  hi def link plugDash    Special
+  hi def link plugPlus    Constant
+  hi def link plugStar    Boolean
+
+  hi def link plugMessage Function
+  hi def link plugName    Label
+  hi def link plugInstall Function
+  hi def link plugUpdate  Type
+
+  hi def link plugError   Error
+  hi def link plugDeleted Ignore
+  hi def link plugRelDate Comment
+  hi def link plugEdge    PreProc
+  hi def link plugSha     Identifier
+  hi def link plugTag     Constant
+
+  hi def link plugNotLoaded Comment
+endfunction
+
+function! s:lpad(str, len)
+  return a:str . repeat(' ', a:len - len(a:str))
+endfunction
+
+function! s:lines(msg)
+  return split(a:msg, "[\r\n]")
+endfunction
+
+function! s:lastline(msg)
+  return get(s:lines(a:msg), -1, '')
+endfunction
+
+function! s:new_window()
+  execute get(g:, 'plug_window', 'vertical topleft new')
+endfunction
+
+function! s:plug_window_exists()
+  let buflist = tabpagebuflist(s:plug_tab)
+  return !empty(buflist) && index(buflist, s:plug_buf) >= 0
+endfunction
+
+function! s:switch_in()
+  if !s:plug_window_exists()
+    return 0
+  endif
+
+  if winbufnr(0) != s:plug_buf
+    let s:pos = [tabpagenr(), winnr(), winsaveview()]
+    execute 'normal!' s:plug_tab.'gt'
+    let winnr = bufwinnr(s:plug_buf)
+    execute winnr.'wincmd w'
+    call add(s:pos, winsaveview())
+  else
+    let s:pos = [winsaveview()]
+  endif
+
+  setlocal modifiable
+  return 1
+endfunction
+
+function! s:switch_out(...)
+  call winrestview(s:pos[-1])
+  setlocal nomodifiable
+  if a:0 > 0
+    execute a:1
+  endif
+
+  if len(s:pos) > 1
+    execute 'normal!' s:pos[0].'gt'
+    execute s:pos[1] 'wincmd w'
+    call winrestview(s:pos[2])
+  endif
+endfunction
+
+function! s:finish_bindings()
+  nnoremap <silent> <buffer> R  :call <SID>retry()<cr>
+  nnoremap <silent> <buffer> D  :PlugDiff<cr>
+  nnoremap <silent> <buffer> S  :PlugStatus<cr>
+  nnoremap <silent> <buffer> U  :call <SID>status_update()<cr>
+  xnoremap <silent> <buffer> U  :call <SID>status_update()<cr>
+  nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr>
+  nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr>
+endfunction
+
+function! s:prepare(...)
+  if empty(s:plug_getcwd())
+    throw 'Invalid current working directory. Cannot proceed.'
+  endif
+
+  for evar in ['$GIT_DIR', '$GIT_WORK_TREE']
+    if exists(evar)
+      throw evar.' detected. Cannot proceed.'
+    endif
+  endfor
+
+  call s:job_abort()
+  if s:switch_in()
+    if b:plug_preview == 1
+      pc
+    endif
+    enew
+  else
+    call s:new_window()
+  endif
+
+  nnoremap <silent> <buffer> q :call <SID>close_pane()<cr>
+  if a:0 == 0
+    call s:finish_bindings()
+  endif
+  let b:plug_preview = -1
+  let s:plug_tab = tabpagenr()
+  let s:plug_buf = winbufnr(0)
+  call s:assign_name()
+
+  for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
+    execute 'silent! unmap <buffer>' k
+  endfor
+  setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell
+  if exists('+colorcolumn')
+    setlocal colorcolumn=
+  endif
+  setf vim-plug
+  if exists('g:syntax_on')
+    call s:syntax()
+  endif
+endfunction
+
+function! s:close_pane()
+  if b:plug_preview == 1
+    pc
+    let b:plug_preview = -1
+  else
+    bd
+  endif
+endfunction
+
+function! s:assign_name()
+  " Assign buffer name
+  let prefix = '[Plugins]'
+  let name   = prefix
+  let idx    = 2
+  while bufexists(name)
+    let name = printf('%s (%s)', prefix, idx)
+    let idx = idx + 1
+  endwhile
+  silent! execute 'f' fnameescape(name)
+endfunction
+
+function! s:chsh(swap)
+  let prev = [&shell, &shellcmdflag, &shellredir]
+  if !s:is_win
+    set shell=sh
+  endif
+  if a:swap
+    if s:is_powershell(&shell)
+      let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s'
+    elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$'
+      set shellredir=>%s\ 2>&1
+    endif
+  endif
+  return prev
+endfunction
+
+function! s:bang(cmd, ...)
+  let batchfile = ''
+  try
+    let [sh, shellcmdflag, shrd] = s:chsh(a:0)
+    " FIXME: Escaping is incomplete. We could use shellescape with eval,
+    "        but it won't work on Windows.
+    let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
+    if s:is_win
+      let [batchfile, cmd] = s:batchfile(cmd)
+    endif
+    let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%')
+    execute "normal! :execute g:_plug_bang\<cr>\<cr>"
+  finally
+    unlet g:_plug_bang
+    let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
+    if s:is_win && filereadable(batchfile)
+      call delete(batchfile)
+    endif
+  endtry
+  return v:shell_error ? 'Exit status: ' . v:shell_error : ''
+endfunction
+
+function! s:regress_bar()
+  let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '')
+  call s:progress_bar(2, bar, len(bar))
+endfunction
+
+function! s:is_updated(dir)
+  return !empty(s:system_chomp(['git', 'log', '--pretty=format:%h', 'HEAD...HEAD@{1}'], a:dir))
+endfunction
+
+function! s:do(pull, force, todo)
+  for [name, spec] in items(a:todo)
+    if !isdirectory(spec.dir)
+      continue
+    endif
+    let installed = has_key(s:update.new, name)
+    let updated = installed ? 0 :
+      \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir))
+    if a:force || installed || updated
+      execute 'cd' s:esc(spec.dir)
+      call append(3, '- Post-update hook for '. name .' ... ')
+      let error = ''
+      let type = type(spec.do)
+      if type == s:TYPE.string
+        if spec.do[0] == ':'
+          if !get(s:loaded, name, 0)
+            let s:loaded[name] = 1
+            call s:reorg_rtp()
+          endif
+          call s:load_plugin(spec)
+          try
+            execute spec.do[1:]
+          catch
+            let error = v:exception
+          endtry
+          if !s:plug_window_exists()
+            cd -
+            throw 'Warning: vim-plug was terminated by the post-update hook of '.name
+          endif
+        else
+          let error = s:bang(spec.do)
+        endif
+      elseif type == s:TYPE.funcref
+        try
+          call s:load_plugin(spec)
+          let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged')
+          call spec.do({ 'name': name, 'status': status, 'force': a:force })
+        catch
+          let error = v:exception
+        endtry
+      else
+        let error = 'Invalid hook type'
+      endif
+      call s:switch_in()
+      call setline(4, empty(error) ? (getline(4) . 'OK')
+                                 \ : ('x' . getline(4)[1:] . error))
+      if !empty(error)
+        call add(s:update.errors, name)
+        call s:regress_bar()
+      endif
+      cd -
+    endif
+  endfor
+endfunction
+
+function! s:hash_match(a, b)
+  return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0
+endfunction
+
+function! s:checkout(spec)
+  let sha = a:spec.commit
+  let output = s:git_revision(a:spec.dir)
+  if !empty(output) && !s:hash_match(sha, s:lines(output)[0])
+    let credential_helper = s:git_version_requirement(2) ? '-c credential.helper= ' : ''
+    let output = s:system(
+          \ 'git '.credential_helper.'fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir)
+  endif
+  return output
+endfunction
+
+function! s:finish(pull)
+  let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen'))
+  if new_frozen
+    let s = new_frozen > 1 ? 's' : ''
+    call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s))
+  endif
+  call append(3, '- Finishing ... ') | 4
+  redraw
+  call plug#helptags()
+  call plug#end()
+  call setline(4, getline(4) . 'Done!')
+  redraw
+  let msgs = []
+  if !empty(s:update.errors)
+    call add(msgs, "Press 'R' to retry.")
+  endif
+  if a:pull && len(s:update.new) < len(filter(getline(5, '$'),
+                \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'"))
+    call add(msgs, "Press 'D' to see the updated changes.")
+  endif
+  echo join(msgs, ' ')
+  call s:finish_bindings()
+endfunction
+
+function! s:retry()
+  if empty(s:update.errors)
+    return
+  endif
+  echo
+  call s:update_impl(s:update.pull, s:update.force,
+        \ extend(copy(s:update.errors), [s:update.threads]))
+endfunction
+
+function! s:is_managed(name)
+  return has_key(g:plugs[a:name], 'uri')
+endfunction
+
+function! s:names(...)
+  return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)'))
+endfunction
+
+function! s:check_ruby()
+  silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'")
+  if !exists('g:plug_ruby')
+    redraw!
+    return s:warn('echom', 'Warning: Ruby interface is broken')
+  endif
+  let ruby_version = split(g:plug_ruby, '\.')
+  unlet g:plug_ruby
+  return s:version_requirement(ruby_version, [1, 8, 7])
+endfunction
+
+function! s:update_impl(pull, force, args) abort
+  let sync = index(a:args, '--sync') >= 0 || has('vim_starting')
+  let args = filter(copy(a:args), 'v:val != "--sync"')
+  let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ?
+                  \ remove(args, -1) : get(g:, 'plug_threads', 16)
+
+  let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
+  let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') :
+                         \ filter(managed, 'index(args, v:key) >= 0')
+
+  if empty(todo)
+    return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install'))
+  endif
+
+  if !s:is_win && s:git_version_requirement(2, 3)
+    let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : ''
+    let $GIT_TERMINAL_PROMPT = 0
+    for plug in values(todo)
+      let plug.uri = substitute(plug.uri,
+            \ '^https://git::@github\.com', 'https://github.com', '')
+    endfor
+  endif
+
+  if !isdirectory(g:plug_home)
+    try
+      call mkdir(g:plug_home, 'p')
+    catch
+      return s:err(printf('Invalid plug directory: %s. '.
+              \ 'Try to call plug#begin with a valid directory', g:plug_home))
+    endtry
+  endif
+
+  if has('nvim') && !exists('*jobwait') && threads > 1
+    call s:warn('echom', '[vim-plug] Update Neovim for parallel installer')
+  endif
+
+  let use_job = s:nvim || s:vim8
+  let python = (has('python') || has('python3')) && !use_job
+  let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby()
+
+  let s:update = {
+    \ 'start':   reltime(),
+    \ 'all':     todo,
+    \ 'todo':    copy(todo),
+    \ 'errors':  [],
+    \ 'pull':    a:pull,
+    \ 'force':   a:force,
+    \ 'new':     {},
+    \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1,
+    \ 'bar':     '',
+    \ 'fin':     0
+  \ }
+
+  call s:prepare(1)
+  call append(0, ['', ''])
+  normal! 2G
+  silent! redraw
+
+  let s:clone_opt = []
+  if get(g:, 'plug_shallow', 1)
+    call extend(s:clone_opt, ['--depth', '1'])
+    if s:git_version_requirement(1, 7, 10)
+      call add(s:clone_opt, '--no-single-branch')
+    endif
+  endif
+
+  if has('win32unix') || has('wsl')
+    call extend(s:clone_opt, ['-c', 'core.eol=lf', '-c', 'core.autocrlf=input'])
+  endif
+
+  let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : ''
+
+  " Python version requirement (>= 2.7)
+  if python && !has('python3') && !ruby && !use_job && s:update.threads > 1
+    redir => pyv
+    silent python import platform; print platform.python_version()
+    redir END
+    let python = s:version_requirement(
+          \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6])
+  endif
+
+  if (python || ruby) && s:update.threads > 1
+    try
+      let imd = &imd
+      if s:mac_gui
+        set noimd
+      endif
+      if ruby
+        call s:update_ruby()
+      else
+        call s:update_python()
+      endif
+    catch
+      let lines = getline(4, '$')
+      let printed = {}
+      silent! 4,$d _
+      for line in lines
+        let name = s:extract_name(line, '.', '')
+        if empty(name) || !has_key(printed, name)
+          call append('$', line)
+          if !empty(name)
+            let printed[name] = 1
+            if line[0] == 'x' && index(s:update.errors, name) < 0
+              call add(s:update.errors, name)
+            end
+          endif
+        endif
+      endfor
+    finally
+      let &imd = imd
+      call s:update_finish()
+    endtry
+  else
+    call s:update_vim()
+    while use_job && sync
+      sleep 100m
+      if s:update.fin
+        break
+      endif
+    endwhile
+  endif
+endfunction
+
+function! s:log4(name, msg)
+  call setline(4, printf('- %s (%s)', a:msg, a:name))
+  redraw
+endfunction
+
+function! s:update_finish()
+  if exists('s:git_terminal_prompt')
+    let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt
+  endif
+  if s:switch_in()
+    call append(3, '- Updating ...') | 4
+    for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))'))
+      let [pos, _] = s:logpos(name)
+      if !pos
+        continue
+      endif
+      if has_key(spec, 'commit')
+        call s:log4(name, 'Checking out '.spec.commit)
+        let out = s:checkout(spec)
+      elseif has_key(spec, 'tag')
+        let tag = spec.tag
+        if tag =~ '\*'
+          let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir))
+          if !v:shell_error && !empty(tags)
+            let tag = tags[0]
+            call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
+            call append(3, '')
+          endif
+        endif
+        call s:log4(name, 'Checking out '.tag)
+        let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir)
+      else
+        let branch = s:git_origin_branch(spec)
+        call s:log4(name, 'Merging origin/'.s:esc(branch))
+        let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1'
+              \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir)
+      endif
+      if !v:shell_error && filereadable(spec.dir.'/.gitmodules') &&
+            \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir))
+        call s:log4(name, 'Updating submodules. This may take a while.')
+        let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir)
+      endif
+      let msg = s:format_message(v:shell_error ? 'x': '-', name, out)
+      if v:shell_error
+        call add(s:update.errors, name)
+        call s:regress_bar()
+        silent execute pos 'd _'
+        call append(4, msg) | 4
+      elseif !empty(out)
+        call setline(pos, msg[0])
+      endif
+      redraw
+    endfor
+    silent 4 d _
+    try
+      call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")'))
+    catch
+      call s:warn('echom', v:exception)
+      call s:warn('echo', '')
+      return
+    endtry
+    call s:finish(s:update.pull)
+    call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.')
+    call s:switch_out('normal! gg')
+  endif
+endfunction
+
+function! s:job_abort()
+  if (!s:nvim && !s:vim8) || !exists('s:jobs')
+    return
+  endif
+
+  for [name, j] in items(s:jobs)
+    if s:nvim
+      silent! call jobstop(j.jobid)
+    elseif s:vim8
+      silent! call job_stop(j.jobid)
+    endif
+    if j.new
+      call s:rm_rf(g:plugs[name].dir)
+    endif
+  endfor
+  let s:jobs = {}
+endfunction
+
+function! s:last_non_empty_line(lines)
+  let len = len(a:lines)
+  for idx in range(len)
+    let line = a:lines[len-idx-1]
+    if !empty(line)
+      return line
+    endif
+  endfor
+  return ''
+endfunction
+
+function! s:job_out_cb(self, data) abort
+  let self = a:self
+  let data = remove(self.lines, -1) . a:data
+  let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]')
+  call extend(self.lines, lines)
+  " To reduce the number of buffer updates
+  let self.tick = get(self, 'tick', -1) + 1
+  if !self.running || self.tick % len(s:jobs) == 0
+    let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-')
+    let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines)
+    call s:log(bullet, self.name, result)
+  endif
+endfunction
+
+function! s:job_exit_cb(self, data) abort
+  let a:self.running = 0
+  let a:self.error = a:data != 0
+  call s:reap(a:self.name)
+  call s:tick()
+endfunction
+
+function! s:job_cb(fn, job, ch, data)
+  if !s:plug_window_exists() " plug window closed
+    return s:job_abort()
+  endif
+  call call(a:fn, [a:job, a:data])
+endfunction
+
+function! s:nvim_cb(job_id, data, event) dict abort
+  return (a:event == 'stdout' || a:event == 'stderr') ?
+    \ s:job_cb('s:job_out_cb',  self, 0, join(a:data, "\n")) :
+    \ s:job_cb('s:job_exit_cb', self, 0, a:data)
+endfunction
+
+function! s:spawn(name, cmd, opts)
+  let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
+            \ 'new': get(a:opts, 'new', 0) }
+  let s:jobs[a:name] = job
+
+  if s:nvim
+    if has_key(a:opts, 'dir')
+      let job.cwd = a:opts.dir
+    endif
+    let argv = a:cmd
+    call extend(job, {
+    \ 'on_stdout': function('s:nvim_cb'),
+    \ 'on_stderr': function('s:nvim_cb'),
+    \ 'on_exit':   function('s:nvim_cb'),
+    \ })
+    let jid = s:plug_call('jobstart', argv, job)
+    if jid > 0
+      let job.jobid = jid
+    else
+      let job.running = 0
+      let job.error   = 1
+      let job.lines   = [jid < 0 ? argv[0].' is not executable' :
+            \ 'Invalid arguments (or job table is full)']
+    endif
+  elseif s:vim8
+    let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"script": 0})'))
+    if has_key(a:opts, 'dir')
+      let cmd = s:with_cd(cmd, a:opts.dir, 0)
+    endif
+    let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd]
+    let jid = job_start(s:is_win ? join(argv, ' ') : argv, {
+    \ 'out_cb':   function('s:job_cb', ['s:job_out_cb',  job]),
+    \ 'err_cb':   function('s:job_cb', ['s:job_out_cb',  job]),
+    \ 'exit_cb':  function('s:job_cb', ['s:job_exit_cb', job]),
+    \ 'err_mode': 'raw',
+    \ 'out_mode': 'raw'
+    \})
+    if job_status(jid) == 'run'
+      let job.jobid = jid
+    else
+      let job.running = 0
+      let job.error   = 1
+      let job.lines   = ['Failed to start job']
+    endif
+  else
+    let job.lines = s:lines(call('s:system', has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]))
+    let job.error = v:shell_error != 0
+    let job.running = 0
+  endif
+endfunction
+
+function! s:reap(name)
+  let job = s:jobs[a:name]
+  if job.error
+    call add(s:update.errors, a:name)
+  elseif get(job, 'new', 0)
+    let s:update.new[a:name] = 1
+  endif
+  let s:update.bar .= job.error ? 'x' : '='
+
+  let bullet = job.error ? 'x' : '-'
+  let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines)
+  call s:log(bullet, a:name, empty(result) ? 'OK' : result)
+  call s:bar()
+
+  call remove(s:jobs, a:name)
+endfunction
+
+function! s:bar()
+  if s:switch_in()
+    let total = len(s:update.all)
+    call setline(1, (s:update.pull ? 'Updating' : 'Installing').
+          \ ' plugins ('.len(s:update.bar).'/'.total.')')
+    call s:progress_bar(2, s:update.bar, total)
+    call s:switch_out()
+  endif
+endfunction
+
+function! s:logpos(name)
+  let max = line('$')
+  for i in range(4, max > 4 ? max : 4)
+    if getline(i) =~# '^[-+x*] '.a:name.':'
+      for j in range(i + 1, max > 5 ? max : 5)
+        if getline(j) !~ '^ '
+          return [i, j - 1]
+        endif
+      endfor
+      return [i, i]
+    endif
+  endfor
+  return [0, 0]
+endfunction
+
+function! s:log(bullet, name, lines)
+  if s:switch_in()
+    let [b, e] = s:logpos(a:name)
+    if b > 0
+      silent execute printf('%d,%d d _', b, e)
+      if b > winheight('.')
+        let b = 4
+      endif
+    else
+      let b = 4
+    endif
+    " FIXME For some reason, nomodifiable is set after :d in vim8
+    setlocal modifiable
+    call append(b - 1, s:format_message(a:bullet, a:name, a:lines))
+    call s:switch_out()
+  endif
+endfunction
+
+function! s:update_vim()
+  let s:jobs = {}
+
+  call s:bar()
+  call s:tick()
+endfunction
+
+function! s:tick()
+  let pull = s:update.pull
+  let prog = s:progress_opt(s:nvim || s:vim8)
+while 1 " Without TCO, Vim stack is bound to explode
+  if empty(s:update.todo)
+    if empty(s:jobs) && !s:update.fin
+      call s:update_finish()
+      let s:update.fin = 1
+    endif
+    return
+  endif
+
+  let name = keys(s:update.todo)[0]
+  let spec = remove(s:update.todo, name)
+  let new  = empty(globpath(spec.dir, '.git', 1))
+
+  call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
+  redraw
+
+  let has_tag = has_key(spec, 'tag')
+  if !new
+    let [error, _] = s:git_validate(spec, 0)
+    if empty(error)
+      if pull
+        let cmd = s:git_version_requirement(2) ? ['git', '-c', 'credential.helper=', 'fetch'] : ['git', 'fetch']
+        if has_tag && !empty(globpath(spec.dir, '.git/shallow'))
+          call extend(cmd, ['--depth', '99999999'])
+        endif
+        if !empty(prog)
+          call add(cmd, prog)
+        endif
+        call s:spawn(name, cmd, { 'dir': spec.dir })
+      else
+        let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 }
+      endif
+    else
+      let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 }
+    endif
+  else
+    let cmd = ['git', 'clone']
+    if !has_tag
+      call extend(cmd, s:clone_opt)
+    endif
+    if !empty(prog)
+      call add(cmd, prog)
+    endif
+    call s:spawn(name, extend(cmd, [spec.uri, s:trim(spec.dir)]), { 'new': 1 })
+  endif
+
+  if !s:jobs[name].running
+    call s:reap(name)
+  endif
+  if len(s:jobs) >= s:update.threads
+    break
+  endif
+endwhile
+endfunction
+
+function! s:update_python()
+let py_exe = has('python') ? 'python' : 'python3'
+execute py_exe "<< EOF"
+import datetime
+import functools
+import os
+try:
+  import queue
+except ImportError:
+  import Queue as queue
+import random
+import re
+import shutil
+import signal
+import subprocess
+import tempfile
+import threading as thr
+import time
+import traceback
+import vim
+
+G_NVIM = vim.eval("has('nvim')") == '1'
+G_PULL = vim.eval('s:update.pull') == '1'
+G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1
+G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)'))
+G_CLONE_OPT = ' '.join(vim.eval('s:clone_opt'))
+G_PROGRESS = vim.eval('s:progress_opt(1)')
+G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads'))
+G_STOP = thr.Event()
+G_IS_WIN = vim.eval('s:is_win') == '1'
+
+class PlugError(Exception):
+  def __init__(self, msg):
+    self.msg = msg
+class CmdTimedOut(PlugError):
+  pass
+class CmdFailed(PlugError):
+  pass
+class InvalidURI(PlugError):
+  pass
+class Action(object):
+  INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-']
+
+class Buffer(object):
+  def __init__(self, lock, num_plugs, is_pull):
+    self.bar = ''
+    self.event = 'Updating' if is_pull else 'Installing'
+    self.lock = lock
+    self.maxy = int(vim.eval('winheight(".")'))
+    self.num_plugs = num_plugs
+
+  def __where(self, name):
+    """ Find first line with name in current buffer. Return line num. """
+    found, lnum = False, 0
+    matcher = re.compile('^[-+x*] {0}:'.format(name))
+    for line in vim.current.buffer:
+      if matcher.search(line) is not None:
+        found = True
+        break
+      lnum += 1
+
+    if not found:
+      lnum = -1
+    return lnum
+
+  def header(self):
+    curbuf = vim.current.buffer
+    curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs)
+
+    num_spaces = self.num_plugs - len(self.bar)
+    curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ')
+
+    with self.lock:
+      vim.command('normal! 2G')
+      vim.command('redraw')
+
+  def write(self, action, name, lines):
+    first, rest = lines[0], lines[1:]
+    msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)]
+    msg.extend(['    ' + line for line in rest])
+
+    try:
+      if action == Action.ERROR:
+        self.bar += 'x'
+        vim.command("call add(s:update.errors, '{0}')".format(name))
+      elif action == Action.DONE:
+        self.bar += '='
+
+      curbuf = vim.current.buffer
+      lnum = self.__where(name)
+      if lnum != -1: # Found matching line num
+        del curbuf[lnum]
+        if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]):
+          lnum = 3
+      else:
+        lnum = 3
+      curbuf.append(msg, lnum)
+
+      self.header()
+    except vim.error:
+      pass
+
+class Command(object):
+  CD = 'cd /d' if G_IS_WIN else 'cd'
+
+  def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None):
+    self.cmd = cmd
+    if cmd_dir:
+      self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd)
+    self.timeout = timeout
+    self.callback = cb if cb else (lambda msg: None)
+    self.clean = clean if clean else (lambda: None)
+    self.proc = None
+
+  @property
+  def alive(self):
+    """ Returns true only if command still running. """
+    return self.proc and self.proc.poll() is None
+
+  def execute(self, ntries=3):
+    """ Execute the command with ntries if CmdTimedOut.
+        Returns the output of the command if no Exception.
+    """
+    attempt, finished, limit = 0, False, self.timeout
+
+    while not finished:
+      try:
+        attempt += 1
+        result = self.try_command()
+        finished = True
+        return result
+      except CmdTimedOut:
+        if attempt != ntries:
+          self.notify_retry()
+          self.timeout += limit
+        else:
+          raise
+
+  def notify_retry(self):
+    """ Retry required for command, notify user. """
+    for count in range(3, 0, -1):
+      if G_STOP.is_set():
+        raise KeyboardInterrupt
+      msg = 'Timeout. Will retry in {0} second{1} ...'.format(
+            count, 's' if count != 1 else '')
+      self.callback([msg])
+      time.sleep(1)
+    self.callback(['Retrying ...'])
+
+  def try_command(self):
+    """ Execute a cmd & poll for callback. Returns list of output.
+        Raises CmdFailed   -> return code for Popen isn't 0
+        Raises CmdTimedOut -> command exceeded timeout without new output
+    """
+    first_line = True
+
+    try:
+      tfile = tempfile.NamedTemporaryFile(mode='w+b')
+      preexec_fn = not G_IS_WIN and os.setsid or None
+      self.proc = subprocess.Popen(self.cmd, stdout=tfile,
+                                   stderr=subprocess.STDOUT,
+                                   stdin=subprocess.PIPE, shell=True,
+                                   preexec_fn=preexec_fn)
+      thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,))
+      thrd.start()
+
+      thread_not_started = True
+      while thread_not_started:
+        try:
+          thrd.join(0.1)
+          thread_not_started = False
+        except RuntimeError:
+          pass
+
+      while self.alive:
+        if G_STOP.is_set():
+          raise KeyboardInterrupt
+
+        if first_line or random.random() < G_LOG_PROB:
+          first_line = False
+          line = '' if G_IS_WIN else nonblock_read(tfile.name)
+          if line:
+            self.callback([line])
+
+        time_diff = time.time() - os.path.getmtime(tfile.name)
+        if time_diff > self.timeout:
+          raise CmdTimedOut(['Timeout!'])
+
+        thrd.join(0.5)
+
+      tfile.seek(0)
+      result = [line.decode('utf-8', 'replace').rstrip() for line in tfile]
+
+      if self.proc.returncode != 0:
+        raise CmdFailed([''] + result)
+
+      return result
+    except:
+      self.terminate()
+      raise
+
+  def terminate(self):
+    """ Terminate process and cleanup. """
+    if self.alive:
+      if G_IS_WIN:
+        os.kill(self.proc.pid, signal.SIGINT)
+      else:
+        os.killpg(self.proc.pid, signal.SIGTERM)
+    self.clean()
+
+class Plugin(object):
+  def __init__(self, name, args, buf_q, lock):
+    self.name = name
+    self.args = args
+    self.buf_q = buf_q
+    self.lock = lock
+    self.tag = args.get('tag', 0)
+
+  def manage(self):
+    try:
+      if os.path.exists(self.args['dir']):
+        self.update()
+      else:
+        self.install()
+        with self.lock:
+          thread_vim_command("let s:update.new['{0}'] = 1".format(self.name))
+    except PlugError as exc:
+      self.write(Action.ERROR, self.name, exc.msg)
+    except KeyboardInterrupt:
+      G_STOP.set()
+      self.write(Action.ERROR, self.name, ['Interrupted!'])
+    except:
+      # Any exception except those above print stack trace
+      msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip())
+      self.write(Action.ERROR, self.name, msg.split('\n'))
+      raise
+
+  def install(self):
+    target = self.args['dir']
+    if target[-1] == '\\':
+      target = target[0:-1]
+
+    def clean(target):
+      def _clean():
+        try:
+          shutil.rmtree(target)
+        except OSError:
+          pass
+      return _clean
+
+    self.write(Action.INSTALL, self.name, ['Installing ...'])
+    callback = functools.partial(self.write, Action.INSTALL, self.name)
+    cmd = 'git clone {0} {1} {2} {3} 2>&1'.format(
+          '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'],
+          esc(target))
+    com = Command(cmd, None, G_TIMEOUT, callback, clean(target))
+    result = com.execute(G_RETRIES)
+    self.write(Action.DONE, self.name, result[-1:])
+
+  def repo_uri(self):
+    cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url'
+    command = Command(cmd, self.args['dir'], G_TIMEOUT,)
+    result = command.execute(G_RETRIES)
+    return result[-1]
+
+  def update(self):
+    actual_uri = self.repo_uri()
+    expect_uri = self.args['uri']
+    regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$')
+    ma = regex.match(actual_uri)
+    mb = regex.match(expect_uri)
+    if ma is None or mb is None or ma.groups() != mb.groups():
+      msg = ['',
+             'Invalid URI: {0}'.format(actual_uri),
+             'Expected     {0}'.format(expect_uri),
+             'PlugClean required.']
+      raise InvalidURI(msg)
+
+    if G_PULL:
+      self.write(Action.UPDATE, self.name, ['Updating ...'])
+      callback = functools.partial(self.write, Action.UPDATE, self.name)
+      fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else ''
+      cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS)
+      com = Command(cmd, self.args['dir'], G_TIMEOUT, callback)
+      result = com.execute(G_RETRIES)
+      self.write(Action.DONE, self.name, result[-1:])
+    else:
+      self.write(Action.DONE, self.name, ['Already installed'])
+
+  def write(self, action, name, msg):
+    self.buf_q.put((action, name, msg))
+
+class PlugThread(thr.Thread):
+  def __init__(self, tname, args):
+    super(PlugThread, self).__init__()
+    self.tname = tname
+    self.args = args
+
+  def run(self):
+    thr.current_thread().name = self.tname
+    buf_q, work_q, lock = self.args
+
+    try:
+      while not G_STOP.is_set():
+        name, args = work_q.get_nowait()
+        plug = Plugin(name, args, buf_q, lock)
+        plug.manage()
+        work_q.task_done()
+    except queue.Empty:
+      pass
+
+class RefreshThread(thr.Thread):
+  def __init__(self, lock):
+    super(RefreshThread, self).__init__()
+    self.lock = lock
+    self.running = True
+
+  def run(self):
+    while self.running:
+      with self.lock:
+        thread_vim_command('noautocmd normal! a')
+      time.sleep(0.33)
+
+  def stop(self):
+    self.running = False
+
+if G_NVIM:
+  def thread_vim_command(cmd):
+    vim.session.threadsafe_call(lambda: vim.command(cmd))
+else:
+  def thread_vim_command(cmd):
+    vim.command(cmd)
+
+def esc(name):
+  return '"' + name.replace('"', '\"') + '"'
+
+def nonblock_read(fname):
+  """ Read a file with nonblock flag. Return the last line. """
+  fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK)
+  buf = os.read(fread, 100000).decode('utf-8', 'replace')
+  os.close(fread)
+
+  line = buf.rstrip('\r\n')
+  left = max(line.rfind('\r'), line.rfind('\n'))
+  if left != -1:
+    left += 1
+    line = line[left:]
+
+  return line
+
+def main():
+  thr.current_thread().name = 'main'
+  nthreads = int(vim.eval('s:update.threads'))
+  plugs = vim.eval('s:update.todo')
+  mac_gui = vim.eval('s:mac_gui') == '1'
+
+  lock = thr.Lock()
+  buf = Buffer(lock, len(plugs), G_PULL)
+  buf_q, work_q = queue.Queue(), queue.Queue()
+  for work in plugs.items():
+    work_q.put(work)
+
+  start_cnt = thr.active_count()
+  for num in range(nthreads):
+    tname = 'PlugT-{0:02}'.format(num)
+    thread = PlugThread(tname, (buf_q, work_q, lock))
+    thread.start()
+  if mac_gui:
+    rthread = RefreshThread(lock)
+    rthread.start()
+
+  while not buf_q.empty() or thr.active_count() != start_cnt:
+    try:
+      action, name, msg = buf_q.get(True, 0.25)
+      buf.write(action, name, ['OK'] if not msg else msg)
+      buf_q.task_done()
+    except queue.Empty:
+      pass
+    except KeyboardInterrupt:
+      G_STOP.set()
+
+  if mac_gui:
+    rthread.stop()
+    rthread.join()
+
+main()
+EOF
+endfunction
+
+function! s:update_ruby()
+  ruby << EOF
+  module PlugStream
+    SEP = ["\r", "\n", nil]
+    def get_line
+      buffer = ''
+      loop do
+        char = readchar rescue return
+        if SEP.include? char.chr
+          buffer << $/
+          break
+        else
+          buffer << char
+        end
+      end
+      buffer
+    end
+  end unless defined?(PlugStream)
+
+  def esc arg
+    %["#{arg.gsub('"', '\"')}"]
+  end
+
+  def killall pid
+    pids = [pid]
+    if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
+      pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil }
+    else
+      unless `which pgrep 2> /dev/null`.empty?
+        children = pids
+        until children.empty?
+          children = children.map { |pid|
+            `pgrep -P #{pid}`.lines.map { |l| l.chomp }
+          }.flatten
+          pids += children
+        end
+      end
+      pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil }
+    end
+  end
+
+  def compare_git_uri a, b
+    regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$}
+    regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1)
+  end
+
+  require 'thread'
+  require 'fileutils'
+  require 'timeout'
+  running = true
+  iswin = VIM::evaluate('s:is_win').to_i == 1
+  pull  = VIM::evaluate('s:update.pull').to_i == 1
+  base  = VIM::evaluate('g:plug_home')
+  all   = VIM::evaluate('s:update.todo')
+  limit = VIM::evaluate('get(g:, "plug_timeout", 60)')
+  tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1
+  nthr  = VIM::evaluate('s:update.threads').to_i
+  maxy  = VIM::evaluate('winheight(".")').to_i
+  vim7  = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/
+  cd    = iswin ? 'cd /d' : 'cd'
+  tot   = VIM::evaluate('len(s:update.todo)') || 0
+  bar   = ''
+  skip  = 'Already installed'
+  mtx   = Mutex.new
+  take1 = proc { mtx.synchronize { running && all.shift } }
+  logh  = proc {
+    cnt = bar.length
+    $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})"
+    $curbuf[2] = '[' + bar.ljust(tot) + ']'
+    VIM::command('normal! 2G')
+    VIM::command('redraw')
+  }
+  where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } }
+  log   = proc { |name, result, type|
+    mtx.synchronize do
+      ing  = ![true, false].include?(type)
+      bar += type ? '=' : 'x' unless ing
+      b = case type
+          when :install  then '+' when :update then '*'
+          when true, nil then '-' else
+            VIM::command("call add(s:update.errors, '#{name}')")
+            'x'
+          end
+      result =
+        if type || type.nil?
+          ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"]
+        elsif result =~ /^Interrupted|^Timeout/
+          ["#{b} #{name}: #{result}"]
+        else
+          ["#{b} #{name}"] + result.lines.map { |l| "    " << l }
+        end
+      if lnum = where.call(name)
+        $curbuf.delete lnum
+        lnum = 4 if ing && lnum > maxy
+      end
+      result.each_with_index do |line, offset|
+        $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp)
+      end
+      logh.call
+    end
+  }
+  bt = proc { |cmd, name, type, cleanup|
+    tried = timeout = 0
+    begin
+      tried += 1
+      timeout += limit
+      fd = nil
+      data = ''
+      if iswin
+        Timeout::timeout(timeout) do
+          tmp = VIM::evaluate('tempname()')
+          system("(#{cmd}) > #{tmp}")
+          data = File.read(tmp).chomp
+          File.unlink tmp rescue nil
+        end
+      else
+        fd = IO.popen(cmd).extend(PlugStream)
+        first_line = true
+        log_prob = 1.0 / nthr
+        while line = Timeout::timeout(timeout) { fd.get_line }
+          data << line
+          log.call name, line.chomp, type if name && (first_line || rand < log_prob)
+          first_line = false
+        end
+        fd.close
+      end
+      [$? == 0, data.chomp]
+    rescue Timeout::Error, Interrupt => e
+      if fd && !fd.closed?
+        killall fd.pid
+        fd.close
+      end
+      cleanup.call if cleanup
+      if e.is_a?(Timeout::Error) && tried < tries
+        3.downto(1) do |countdown|
+          s = countdown > 1 ? 's' : ''
+          log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type
+          sleep 1
+        end
+        log.call name, 'Retrying ...', type
+        retry
+      end
+      [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"]
+    end
+  }
+  main = Thread.current
+  threads = []
+  watcher = Thread.new {
+    if vim7
+      while VIM::evaluate('getchar(1)')
+        sleep 0.1
+      end
+    else
+      require 'io/console' # >= Ruby 1.9
+      nil until IO.console.getch == 3.chr
+    end
+    mtx.synchronize do
+      running = false
+      threads.each { |t| t.raise Interrupt } unless vim7
+    end
+    threads.each { |t| t.join rescue nil }
+    main.kill
+  }
+  refresh = Thread.new {
+    while true
+      mtx.synchronize do
+        break unless running
+        VIM::command('noautocmd normal! a')
+      end
+      sleep 0.2
+    end
+  } if VIM::evaluate('s:mac_gui') == 1
+
+  clone_opt = VIM::evaluate('s:clone_opt').join(' ')
+  progress = VIM::evaluate('s:progress_opt(1)')
+  nthr.times do
+    mtx.synchronize do
+      threads << Thread.new {
+        while pair = take1.call
+          name = pair.first
+          dir, uri, tag = pair.last.values_at *%w[dir uri tag]
+          exists = File.directory? dir
+          ok, result =
+            if exists
+              chdir = "#{cd} #{iswin ? dir : esc(dir)}"
+              ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil
+              current_uri = data.lines.to_a.last
+              if !ret
+                if data =~ /^Interrupted|^Timeout/
+                  [false, data]
+                else
+                  [false, [data.chomp, "PlugClean required."].join($/)]
+                end
+              elsif !compare_git_uri(current_uri, uri)
+                [false, ["Invalid URI: #{current_uri}",
+                         "Expected:    #{uri}",
+                         "PlugClean required."].join($/)]
+              else
+                if pull
+                  log.call name, 'Updating ...', :update
+                  fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : ''
+                  bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil
+                else
+                  [true, skip]
+                end
+              end
+            else
+              d = esc dir.sub(%r{[\\/]+$}, '')
+              log.call name, 'Installing ...', :install
+              bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc {
+                FileUtils.rm_rf dir
+              }
+            end
+          mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok
+          log.call name, result, ok
+        end
+      } if running
+    end
+  end
+  threads.each { |t| t.join rescue nil }
+  logh.call
+  refresh.kill if refresh
+  watcher.kill
+EOF
+endfunction
+
+function! s:shellesc_cmd(arg, script)
+  let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g')
+  return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g')
+endfunction
+
+function! s:shellesc_ps1(arg)
+  return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'"
+endfunction
+
+function! s:shellesc_sh(arg)
+  return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'"
+endfunction
+
+" Escape the shell argument based on the shell.
+" Vim and Neovim's shellescape() are insufficient.
+" 1. shellslash determines whether to use single/double quotes.
+"    Double-quote escaping is fragile for cmd.exe.
+" 2. It does not work for powershell.
+" 3. It does not work for *sh shells if the command is executed
+"    via cmd.exe (ie. cmd.exe /c sh -c command command_args)
+" 4. It does not support batchfile syntax.
+"
+" Accepts an optional dictionary with the following keys:
+" - shell: same as Vim/Neovim 'shell' option.
+"          If unset, fallback to 'cmd.exe' on Windows or 'sh'.
+" - script: If truthy and shell is cmd.exe, escape for batchfile syntax.
+function! plug#shellescape(arg, ...)
+  if a:arg =~# '^[A-Za-z0-9_/:.-]\+$'
+    return a:arg
+  endif
+  let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {}
+  let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
+  let script = get(opts, 'script', 1)
+  if shell =~# 'cmd\(\.exe\)\?$'
+    return s:shellesc_cmd(a:arg, script)
+  elseif s:is_powershell(shell)
+    return s:shellesc_ps1(a:arg)
+  endif
+  return s:shellesc_sh(a:arg)
+endfunction
+
+function! s:glob_dir(path)
+  return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)')
+endfunction
+
+function! s:progress_bar(line, bar, total)
+  call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']')
+endfunction
+
+function! s:compare_git_uri(a, b)
+  " See `git help clone'
+  " https:// [user@] github.com[:port] / junegunn/vim-plug [.git]
+  "          [git@]  github.com[:port] : junegunn/vim-plug [.git]
+  " file://                            / junegunn/vim-plug        [/]
+  "                                    / junegunn/vim-plug        [/]
+  let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$'
+  let ma = matchlist(a:a, pat)
+  let mb = matchlist(a:b, pat)
+  return ma[1:2] ==# mb[1:2]
+endfunction
+
+function! s:format_message(bullet, name, message)
+  if a:bullet != 'x'
+    return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))]
+  else
+    let lines = map(s:lines(a:message), '"    ".v:val')
+    return extend([printf('x %s:', a:name)], lines)
+  endif
+endfunction
+
+function! s:with_cd(cmd, dir, ...)
+  let script = a:0 > 0 ? a:1 : 1
+  return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd)
+endfunction
+
+function! s:system(cmd, ...)
+  let batchfile = ''
+  try
+    let [sh, shellcmdflag, shrd] = s:chsh(1)
+    if type(a:cmd) == s:TYPE.list
+      " Neovim's system() supports list argument to bypass the shell
+      " but it cannot set the working directory for the command.
+      " Assume that the command does not rely on the shell.
+      if has('nvim') && a:0 == 0
+        return system(a:cmd)
+      endif
+      let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})'))
+      if s:is_powershell(&shell)
+        let cmd = '& ' . cmd
+      endif
+    else
+      let cmd = a:cmd
+    endif
+    if a:0 > 0
+      let cmd = s:with_cd(cmd, a:1, type(a:cmd) != s:TYPE.list)
+    endif
+    if s:is_win && type(a:cmd) != s:TYPE.list
+      let [batchfile, cmd] = s:batchfile(cmd)
+    endif
+    return system(cmd)
+  finally
+    let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
+    if s:is_win && filereadable(batchfile)
+      call delete(batchfile)
+    endif
+  endtry
+endfunction
+
+function! s:system_chomp(...)
+  let ret = call('s:system', a:000)
+  return v:shell_error ? '' : substitute(ret, '\n$', '', '')
+endfunction
+
+function! s:git_validate(spec, check_branch)
+  let err = ''
+  if isdirectory(a:spec.dir)
+    let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)]
+    let remote = result[-1]
+    if empty(remote)
+      let err = join([remote, 'PlugClean required.'], "\n")
+    elseif !s:compare_git_uri(remote, a:spec.uri)
+      let err = join(['Invalid URI: '.remote,
+                    \ 'Expected:    '.a:spec.uri,
+                    \ 'PlugClean required.'], "\n")
+    elseif a:check_branch && has_key(a:spec, 'commit')
+      let sha = s:git_revision(a:spec.dir)
+      if empty(sha)
+        let err = join(add(result, 'PlugClean required.'), "\n")
+      elseif !s:hash_match(sha, a:spec.commit)
+        let err = join([printf('Invalid HEAD (expected: %s, actual: %s)',
+                              \ a:spec.commit[:6], sha[:6]),
+                      \ 'PlugUpdate required.'], "\n")
+      endif
+    elseif a:check_branch
+      let current_branch = result[0]
+      " Check tag
+      let origin_branch = s:git_origin_branch(a:spec)
+      if has_key(a:spec, 'tag')
+        let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
+        if a:spec.tag !=# tag && a:spec.tag !~ '\*'
+          let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.',
+                \ (empty(tag) ? 'N/A' : tag), a:spec.tag)
+        endif
+      " Check branch
+      elseif origin_branch !=# current_branch
+        let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.',
+              \ current_branch, origin_branch)
+      endif
+      if empty(err)
+        let [ahead, behind] = split(s:lastline(s:system([
+        \ 'git', 'rev-list', '--count', '--left-right',
+        \ printf('HEAD...origin/%s', origin_branch)
+        \ ], a:spec.dir)), '\t')
+        if !v:shell_error && ahead
+          if behind
+            " Only mention PlugClean if diverged, otherwise it's likely to be
+            " pushable (and probably not that messed up).
+            let err = printf(
+                  \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n"
+                  \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', origin_branch, ahead, behind)
+          else
+            let err = printf("Ahead of origin/%s by %d commit(s).\n"
+                  \ .'Cannot update until local changes are pushed.',
+                  \ origin_branch, ahead)
+          endif
+        endif
+      endif
+    endif
+  else
+    let err = 'Not found'
+  endif
+  return [err, err =~# 'PlugClean']
+endfunction
+
+function! s:rm_rf(dir)
+  if isdirectory(a:dir)
+    return s:system(s:is_win
+    \ ? 'rmdir /S /Q '.plug#shellescape(a:dir)
+    \ : ['rm', '-rf', a:dir])
+  endif
+endfunction
+
+function! s:clean(force)
+  call s:prepare()
+  call append(0, 'Searching for invalid plugins in '.g:plug_home)
+  call append(1, '')
+
+  " List of valid directories
+  let dirs = []
+  let errs = {}
+  let [cnt, total] = [0, len(g:plugs)]
+  for [name, spec] in items(g:plugs)
+    if !s:is_managed(name)
+      call add(dirs, spec.dir)
+    else
+      let [err, clean] = s:git_validate(spec, 1)
+      if clean
+        let errs[spec.dir] = s:lines(err)[0]
+      else
+        call add(dirs, spec.dir)
+      endif
+    endif
+    let cnt += 1
+    call s:progress_bar(2, repeat('=', cnt), total)
+    normal! 2G
+    redraw
+  endfor
+
+  let allowed = {}
+  for dir in dirs
+    let allowed[s:dirpath(s:plug_fnamemodify(dir, ':h:h'))] = 1
+    let allowed[dir] = 1
+    for child in s:glob_dir(dir)
+      let allowed[child] = 1
+    endfor
+  endfor
+
+  let todo = []
+  let found = sort(s:glob_dir(g:plug_home))
+  while !empty(found)
+    let f = remove(found, 0)
+    if !has_key(allowed, f) && isdirectory(f)
+      call add(todo, f)
+      call append(line('$'), '- ' . f)
+      if has_key(errs, f)
+        call append(line('$'), '    ' . errs[f])
+      endif
+      let found = filter(found, 'stridx(v:val, f) != 0')
+    end
+  endwhile
+
+  4
+  redraw
+  if empty(todo)
+    call append(line('$'), 'Already clean.')
+  else
+    let s:clean_count = 0
+    call append(3, ['Directories to delete:', ''])
+    redraw!
+    if a:force || s:ask_no_interrupt('Delete all directories?')
+      call s:delete([6, line('$')], 1)
+    else
+      call setline(4, 'Cancelled.')
+      nnoremap <silent> <buffer> d :set opfunc=<sid>delete_op<cr>g@
+      nmap     <silent> <buffer> dd d_
+      xnoremap <silent> <buffer> d :<c-u>call <sid>delete_op(visualmode(), 1)<cr>
+      echo 'Delete the lines (d{motion}) to delete the corresponding directories'
+    endif
+  endif
+  4
+  setlocal nomodifiable
+endfunction
+
+function! s:delete_op(type, ...)
+  call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0)
+endfunction
+
+function! s:delete(range, force)
+  let [l1, l2] = a:range
+  let force = a:force
+  let err_count = 0
+  while l1 <= l2
+    let line = getline(l1)
+    if line =~ '^- ' && isdirectory(line[2:])
+      execute l1
+      redraw!
+      let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1)
+      let force = force || answer > 1
+      if answer
+        let err = s:rm_rf(line[2:])
+        setlocal modifiable
+        if empty(err)
+          call setline(l1, '~'.line[1:])
+          let s:clean_count += 1
+        else
+          delete _
+          call append(l1 - 1, s:format_message('x', line[1:], err))
+          let l2 += len(s:lines(err))
+          let err_count += 1
+        endif
+        let msg = printf('Removed %d directories.', s:clean_count)
+        if err_count > 0
+          let msg .= printf(' Failed to remove %d directories.', err_count)
+        endif
+        call setline(4, msg)
+        setlocal nomodifiable
+      endif
+    endif
+    let l1 += 1
+  endwhile
+endfunction
+
+function! s:upgrade()
+  echo 'Downloading the latest version of vim-plug'
+  redraw
+  let tmp = s:plug_tempname()
+  let new = tmp . '/plug.vim'
+
+  try
+    let out = s:system(['git', 'clone', '--depth', '1', s:plug_src, tmp])
+    if v:shell_error
+      return s:err('Error upgrading vim-plug: '. out)
+    endif
+
+    if readfile(s:me) ==# readfile(new)
+      echo 'vim-plug is already up-to-date'
+      return 0
+    else
+      call rename(s:me, s:me . '.old')
+      call rename(new, s:me)
+      unlet g:loaded_plug
+      echo 'vim-plug has been upgraded'
+      return 1
+    endif
+  finally
+    silent! call s:rm_rf(tmp)
+  endtry
+endfunction
+
+function! s:upgrade_specs()
+  for spec in values(g:plugs)
+    let spec.frozen = get(spec, 'frozen', 0)
+  endfor
+endfunction
+
+function! s:status()
+  call s:prepare()
+  call append(0, 'Checking plugins')
+  call append(1, '')
+
+  let ecnt = 0
+  let unloaded = 0
+  let [cnt, total] = [0, len(g:plugs)]
+  for [name, spec] in items(g:plugs)
+    let is_dir = isdirectory(spec.dir)
+    if has_key(spec, 'uri')
+      if is_dir
+        let [err, _] = s:git_validate(spec, 1)
+        let [valid, msg] = [empty(err), empty(err) ? 'OK' : err]
+      else
+        let [valid, msg] = [0, 'Not found. Try PlugInstall.']
+      endif
+    else
+      if is_dir
+        let [valid, msg] = [1, 'OK']
+      else
+        let [valid, msg] = [0, 'Not found.']
+      endif
+    endif
+    let cnt += 1
+    let ecnt += !valid
+    " `s:loaded` entry can be missing if PlugUpgraded
+    if is_dir && get(s:loaded, name, -1) == 0
+      let unloaded = 1
+      let msg .= ' (not loaded)'
+    endif
+    call s:progress_bar(2, repeat('=', cnt), total)
+    call append(3, s:format_message(valid ? '-' : 'x', name, msg))
+    normal! 2G
+    redraw
+  endfor
+  call setline(1, 'Finished. '.ecnt.' error(s).')
+  normal! gg
+  setlocal nomodifiable
+  if unloaded
+    echo "Press 'L' on each line to load plugin, or 'U' to update"
+    nnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr>
+    xnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr>
+  end
+endfunction
+
+function! s:extract_name(str, prefix, suffix)
+  return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$')
+endfunction
+
+function! s:status_load(lnum)
+  let line = getline(a:lnum)
+  let name = s:extract_name(line, '-', '(not loaded)')
+  if !empty(name)
+    call plug#load(name)
+    setlocal modifiable
+    call setline(a:lnum, substitute(line, ' (not loaded)$', '', ''))
+    setlocal nomodifiable
+  endif
+endfunction
+
+function! s:status_update() range
+  let lines = getline(a:firstline, a:lastline)
+  let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)')
+  if !empty(names)
+    echo
+    execute 'PlugUpdate' join(names)
+  endif
+endfunction
+
+function! s:is_preview_window_open()
+  silent! wincmd P
+  if &previewwindow
+    wincmd p
+    return 1
+  endif
+endfunction
+
+function! s:find_name(lnum)
+  for lnum in reverse(range(1, a:lnum))
+    let line = getline(lnum)
+    if empty(line)
+      return ''
+    endif
+    let name = s:extract_name(line, '-', '')
+    if !empty(name)
+      return name
+    endif
+  endfor
+  return ''
+endfunction
+
+function! s:preview_commit()
+  if b:plug_preview < 0
+    let b:plug_preview = !s:is_preview_window_open()
+  endif
+
+  let sha = matchstr(getline('.'), '^  \X*\zs[0-9a-f]\{7,9}')
+  if empty(sha)
+    return
+  endif
+
+  let name = s:find_name(line('.'))
+  if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir)
+    return
+  endif
+
+  if exists('g:plug_pwindow') && !s:is_preview_window_open()
+    execute g:plug_pwindow
+    execute 'e' sha
+  else
+    execute 'pedit' sha
+    wincmd P
+  endif
+  setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
+  let batchfile = ''
+  try
+    let [sh, shellcmdflag, shrd] = s:chsh(1)
+    let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha
+    if s:is_win
+      let [batchfile, cmd] = s:batchfile(cmd)
+    endif
+    execute 'silent %!' cmd
+  finally
+    let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
+    if s:is_win && filereadable(batchfile)
+      call delete(batchfile)
+    endif
+  endtry
+  setlocal nomodifiable
+  nnoremap <silent> <buffer> q :q<cr>
+  wincmd p
+endfunction
+
+function! s:section(flags)
+  call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
+endfunction
+
+function! s:format_git_log(line)
+  let indent = '  '
+  let tokens = split(a:line, nr2char(1))
+  if len(tokens) != 5
+    return indent.substitute(a:line, '\s*$', '', '')
+  endif
+  let [graph, sha, refs, subject, date] = tokens
+  let tag = matchstr(refs, 'tag: [^,)]\+')
+  let tag = empty(tag) ? ' ' : ' ('.tag.') '
+  return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date)
+endfunction
+
+function! s:append_ul(lnum, text)
+  call append(a:lnum, ['', a:text, repeat('-', len(a:text))])
+endfunction
+
+function! s:diff()
+  call s:prepare()
+  call append(0, ['Collecting changes ...', ''])
+  let cnts = [0, 0]
+  let bar = ''
+  let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)')
+  call s:progress_bar(2, bar, len(total))
+  for origin in [1, 0]
+    let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))'))))
+    if empty(plugs)
+      continue
+    endif
+    call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
+    for [k, v] in plugs
+      let branch = s:git_origin_branch(v)
+      if len(branch)
+        let range = origin ? '..origin/'.branch : 'HEAD@{1}..'
+        let cmd = ['git', 'log', '--graph', '--color=never']
+        if s:git_version_requirement(2, 10, 0)
+          call add(cmd, '--no-show-signature')
+        endif
+        call extend(cmd, ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range])
+        if has_key(v, 'rtp')
+          call extend(cmd, ['--', v.rtp])
+        endif
+        let diff = s:system_chomp(cmd, v.dir)
+        if !empty(diff)
+          let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : ''
+          call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)')))
+          let cnts[origin] += 1
+        endif
+      endif
+      let bar .= '='
+      call s:progress_bar(2, bar, len(total))
+      normal! 2G
+      redraw
+    endfor
+    if !cnts[origin]
+      call append(5, ['', 'N/A'])
+    endif
+  endfor
+  call setline(1, printf('%d plugin(s) updated.', cnts[0])
+        \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : ''))
+
+  if cnts[0] || cnts[1]
+    nnoremap <silent> <buffer> <plug>(plug-preview) :silent! call <SID>preview_commit()<cr>
+    if empty(maparg("\<cr>", 'n'))
+      nmap <buffer> <cr> <plug>(plug-preview)
+    endif
+    if empty(maparg('o', 'n'))
+      nmap <buffer> o <plug>(plug-preview)
+    endif
+  endif
+  if cnts[0]
+    nnoremap <silent> <buffer> X :call <SID>revert()<cr>
+    echo "Press 'X' on each block to revert the update"
+  endif
+  normal! gg
+  setlocal nomodifiable
+endfunction
+
+function! s:revert()
+  if search('^Pending updates', 'bnW')
+    return
+  endif
+
+  let name = s:find_name(line('.'))
+  if empty(name) || !has_key(g:plugs, name) ||
+    \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y'
+    return
+  endif
+
+  call s:system('git reset --hard HEAD@{1} && git checkout '.plug#shellescape(g:plugs[name].branch).' --', g:plugs[name].dir)
+  setlocal modifiable
+  normal! "_dap
+  setlocal nomodifiable
+  echo 'Reverted'
+endfunction
+
+function! s:snapshot(force, ...) abort
+  call s:prepare()
+  setf vim
+  call append(0, ['" Generated by vim-plug',
+                \ '" '.strftime("%c"),
+                \ '" :source this file in vim to restore the snapshot',
+                \ '" or execute: vim -S snapshot.vim',
+                \ '', '', 'PlugUpdate!'])
+  1
+  let anchor = line('$') - 3
+  let names = sort(keys(filter(copy(g:plugs),
+        \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)')))
+  for name in reverse(names)
+    let sha = s:git_revision(g:plugs[name].dir)
+    if !empty(sha)
+      call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha))
+      redraw
+    endif
+  endfor
+
+  if a:0 > 0
+    let fn = s:plug_expand(a:1)
+    if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?'))
+      return
+    endif
+    call writefile(getline(1, '$'), fn)
+    echo 'Saved as '.a:1
+    silent execute 'e' s:esc(fn)
+    setf vim
+  endif
+endfunction
+
+function! s:split_rtp()
+  return split(&rtp, '\\\@<!,')
+endfunction
+
+let s:first_rtp = s:escrtp(get(s:split_rtp(), 0, ''))
+let s:last_rtp  = s:escrtp(get(s:split_rtp(), -1, ''))
+
+if exists('g:plugs')
+  let g:plugs_order = get(g:, 'plugs_order', keys(g:plugs))
+  call s:upgrade_specs()
+  call s:define_commands()
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/home/kurb42/.vimrc b/home/kurb42/.vimrc
new file mode 100644
index 0000000..20e6508
--- /dev/null
+++ b/home/kurb42/.vimrc
@@ -0,0 +1,48 @@
+" Encoding
+set encoding=UTF-8
+
+" Plug
+call plug#begin('~/.vim/plugged')
+Plug 'preservim/nerdtree'
+Plug 'tiagofumo/vim-nerdtree-syntax-highlight'
+Plug 'arcticicestudio/nord-vim'
+Plug 'luochen1990/rainbow'
+Plug 'sheerun/vim-polyglot'
+call plug#end()
+
+" Text Rendering
+syntax enable
+
+" Interface
+set wildmenu
+colorscheme nord
+set cursorline
+set number
+set title
+set background=dark
+set confirm
+
+" Rainbow Brackets
+let g:rainbow_active = 1
+
+" Indent
+set smartindent
+set autoindent
+
+" Search
+set hlsearch
+set ignorecase
+set incsearch
+set smartcase
+
+" NERDTree
+let g:NERDTreeDisableFileExtensionHighlight = 1
+let g:NERDTreeDisableExactMatchHighlight = 1
+let g:NERDTreeDisablePatternMatchHighlight = 1
+let g:NERDTreeShowHidden = 1
+autocmd vimenter * NERDTree | wincmd p
+autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
+nnoremap <C-b> :NERDTreeToggle<CR>
+let g:NERDTreeDirArrowExpandable = ''
+let g:NERDTreeDirArrowCollapsible = ''
+
diff --git a/home/kurb42/.xinitrc b/home/kurb42/.xinitrc
new file mode 100644
index 0000000..88b739f
--- /dev/null
+++ b/home/kurb42/.xinitrc
@@ -0,0 +1,3 @@
+xsetroot -solid "#202020"
+setxkbmap br
+exec dwm
diff --git a/usr/share/fonts/UbuntuMono/UbuntuMono Bold Italic Nerd Font Complete.ttf b/usr/share/fonts/UbuntuMono/UbuntuMono Bold Italic Nerd Font Complete.ttf
new file mode 100644
index 0000000..88672f1
--- /dev/null
+++ b/usr/share/fonts/UbuntuMono/UbuntuMono Bold Italic Nerd Font Complete.ttf
Binary files differdiff --git a/usr/share/fonts/UbuntuMono/UbuntuMono Bold Nerd Font Complete.ttf b/usr/share/fonts/UbuntuMono/UbuntuMono Bold Nerd Font Complete.ttf
new file mode 100644
index 0000000..7639e69
--- /dev/null
+++ b/usr/share/fonts/UbuntuMono/UbuntuMono Bold Nerd Font Complete.ttf
Binary files differdiff --git a/usr/share/fonts/UbuntuMono/UbuntuMono Italic Nerd Font Complete.ttf b/usr/share/fonts/UbuntuMono/UbuntuMono Italic Nerd Font Complete.ttf
new file mode 100644
index 0000000..95104b6
--- /dev/null
+++ b/usr/share/fonts/UbuntuMono/UbuntuMono Italic Nerd Font Complete.ttf
Binary files differdiff --git a/usr/share/fonts/UbuntuMono/UbuntuMono Nerd Font Complete.ttf b/usr/share/fonts/UbuntuMono/UbuntuMono Nerd Font Complete.ttf
new file mode 100644
index 0000000..d7a2fed
--- /dev/null
+++ b/usr/share/fonts/UbuntuMono/UbuntuMono Nerd Font Complete.ttf
Binary files differ