diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c9c23ff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+sh/WIP
+ssh/*
+!ssh/known_hosts
+!ssh/crawl
+vim/backup/*
+vim/.*
+*.swp
+*.swo
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b3c139c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+## obligatory personal dotfiles repository.
+
+_(plus some little shell scripts)_
+
+there's probably a lot of little things in here gone uncredited,
+but who cares.
diff --git a/bashrc b/bashrc
new file mode 100644
index 0000000..b0d38b6
--- /dev/null
+++ b/bashrc
@@ -0,0 +1,33 @@
+[ -z "$PS1" ] && return
+
+if [[ "$TERM" == "rxvt-unicode-256color" ]]; then
+ export TERM=xterm-256color
+fi
+
+HISTCONTROL=erasedups
+HISTSIZE=1000
+HISTFILESIZE=2000
+
+shopt -s histappend
+shopt -s checkwinsize
+#shopt -s physical # chaselinks (doesn't exist?)
+
+if [[ "$TERM" = xterm* ]]; then
+ _title="\[\033]2;\w\a\]"
+else
+ _title=""
+fi
+
+Csucc=$'\\[\e[42m\\]'
+Cfail=$'\\[\e[41m\\]'
+_line1=$' \\[\e[0m\\]'
+_line2=$'\\[\e[1;37m\\]\\$\\[\e[0m\\] '
+ret_succ="$_title${Csucc}$_line1\n${Csucc}$_line2"
+ret_fail="$_title${Cfail}$_line1\n${Cfail}$_line2"
+
+PROMPT_COMMAND='[ $? = 0 ] && PS1=${ret_succ} || PS1=${ret_fail}'
+
+. ~/shrc.zsh
+
+# this doesn't work for all scripts at the moment, but
+PATH="$PATH:$HOME/sh"
diff --git a/config/menus/xfce-applications.menu b/config/menus/xfce-applications.menu
new file mode 100644
index 0000000..b90d62f
--- /dev/null
+++ b/config/menus/xfce-applications.menu
@@ -0,0 +1,37 @@
+
+
+
diff --git a/conkyrc b/conkyrc
new file mode 100644
index 0000000..0843b81
--- /dev/null
+++ b/conkyrc
@@ -0,0 +1,20 @@
+background yes
+own_window yes
+own_window_type desktop
+own_window_transparent yes
+own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
+double_buffer yes
+use_xft yes
+xftfont DejaVu Sans Mono:size=12
+gap_x 18
+gap_y 18
+alignment bottom_left
+
+TEXT
+${color grey} RAM:$color $mem / $memmax $alignr($memperc%)
+${color grey}Swap:$color $swap / $swapmax $alignr($swapperc%)
+${color grey} CPU:$color ${cpugraph 24,210}
+${color grey}Proc:$color $processes $color($running_processes)\
+ ${color grey}Up:$color ${upspeed eth0} ${color grey}Down:$color ${downspeed eth0}
+${color lightgrey}${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}
+${color lightgrey}${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}
diff --git a/init.sh b/init.sh
new file mode 100755
index 0000000..6f23164
--- /dev/null
+++ b/init.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+note() {
+ echo -E "$@"
+}
+
+crap() {
+ echo -E "$@">&2
+ exit 1
+}
+
+dotless() {
+ [[ "${1:0:1}" == "." ]] && echo -E "${1:1}" || echo -E "$1"
+}
+
+hardlink() {
+ [ -e "$1" ] && {
+ [ "$1" -ef "$2" ] && return
+ [ -h "$1" ] && note "removing symbolic link $1" && echo rm "$1"
+ [ -s "$1" ] && crap "$1 already exists" || echo rm "$1"
+ }
+
+ ln "$2" "$1" || crap "couldn't hardlink $1"
+}
+
+softlink() {
+ [ -e "$1" ] && {
+ [ -h "$1" ] && {
+ [ "$(readlink "$1")" == "$2" ] && return
+ note "removing symbolic link $1"
+ echo rm "$1"
+ } || crap "$1 already exists and is not a symbolic link"
+ }
+
+ ln -s "$2" "$1" || crap "couldn't symlink $1"
+}
+
+rc="$(readlink -f "$(dirname "$0")" )"
+cd $HOME
+PATH="$PATH:$rc/sh"
+
+umask 027
+
+for f in .bashrc .zshrc shrc.zsh .conkyrc .inputrc .screenrc .xinitrc; do
+ r="$rc/$(dotless "$f")"
+ hardlink "$f" "$r"
+done
+
+for d in sh .vim .mpv; do
+ r="$rc/$(dotless "$d")"
+ softlink "$d" "$r"
+done
+
+# FIXME: this loop is pretty inefficient
+for r in $rc/ssh/* $rc/config/menus/*; do
+ f=".${r#"$rc/"}"
+ mkdir -p "$(dirname "$f")"
+ hardlink "$f" "$r"
+done
+
+grep .bashrc .bash_profile >/dev/null 2>&1 || \
+ echo -e '\n[[ -f ~/.bashrc ]] && . ~/.bashrc' >> .bash_profile
+
+for d in Desktop Documents Downloads Music Pictures Public Templates Video; do
+ [ -d "$d" ] || continue
+ is_empty "$d" && echo rm -r "$d" || note "skipping unempty $d"
+done
+
+mkdir -p opt/local/bin src work play
diff --git a/inputrc b/inputrc
new file mode 100644
index 0000000..ae904f6
--- /dev/null
+++ b/inputrc
@@ -0,0 +1,4 @@
+"\e[A": history-search-backward
+"\e[B": history-search-forward
+set show-all-if-ambiguous on
+set completion-ignore-case on
diff --git a/screenrc b/screenrc
new file mode 100644
index 0000000..c6ade12
--- /dev/null
+++ b/screenrc
@@ -0,0 +1 @@
+altscreen on
diff --git a/sh/4graze.sh/4graze.sh b/sh/4graze.sh/4graze.sh
new file mode 100755
index 0000000..79eb809
--- /dev/null
+++ b/sh/4graze.sh/4graze.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+url="${1:-}"
+[[ "$url" =~ ^https?://boards.4chan.org/([A-Za-z]+)/res/([0-9]+) ]] || exit 1
+board="${BASH_REMATCH[1]}"
+threadnum="${BASH_REMATCH[2]}"
+
+# TODO: curl version
+
+wgetflags="-erobots=off --no-verbose"
+wgetflags+=" --no-clobber --recursive --level=1 --span-hosts"
+wgetflags+=" --no-directories --directory-prefix=-$board-$threadnum"
+wgetflags+=" --accept=jpg,gif,png --domains=images.4chan.org"
+wget $wgetflags $url
diff --git a/sh/_lsarchive b/sh/_lsarchive
new file mode 100755
index 0000000..f5c1351
--- /dev/null
+++ b/sh/_lsarchive
@@ -0,0 +1,15 @@
+#!/bin/zsh
+#compdef lsarchive
+#autoload
+
+#
+# Completes lsarchive.
+#
+# Authors:
+# Sorin Ionescu
+#
+
+_arguments \
+ '(-v --verbose)'{-v,--remove}'[verbose archive listing]' \
+ "*::archive file:_files -g '(#i)*.(tar|tgz|tbz|tbz2|txz|tlz|gz|bz2|xz|lzma|Z|zip|rar|7z)(-.)'" && return 0
+
diff --git a/sh/_unarchive b/sh/_unarchive
new file mode 100755
index 0000000..2c4caf7
--- /dev/null
+++ b/sh/_unarchive
@@ -0,0 +1,15 @@
+#!/bin/zsh
+#compdef unarchive
+#autoload
+
+#
+# Completes unarchive.
+#
+# Authors:
+# Sorin Ionescu
+#
+
+_arguments \
+ '(-r --remove)'{-r,--remove}'[remove archive]' \
+ "*::archive file:_files -g '(#i)*.(tar|tgz|tbz|tbz2|txz|tlz|gz|bz2|xz|lzma|Z|zip|rar|7z|deb)(-.)'" && return 0
+
diff --git a/sh/arith b/sh/arith
new file mode 100755
index 0000000..eef4450
--- /dev/null
+++ b/sh/arith
@@ -0,0 +1,2 @@
+#!/bin/zsh
+<<<"$(($@))"
diff --git a/sh/cdbusiest b/sh/cdbusiest
new file mode 100644
index 0000000..a925cc6
--- /dev/null
+++ b/sh/cdbusiest
@@ -0,0 +1,4 @@
+#!/bin/zsh
+dbusiest | read -r c d
+<<<"$c $d"
+cd $d
diff --git a/sh/colors b/sh/colors
new file mode 100755
index 0000000..4fe1e2b
--- /dev/null
+++ b/sh/colors
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+printf "\e[%dm$(printf " \e[%dm mV \e[40m" {4,10}{0..7})\e[0m\n" {3,9}{0..7}
diff --git a/sh/confirm b/sh/confirm
new file mode 100755
index 0000000..5e62a9b
--- /dev/null
+++ b/sh/confirm
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+if [ -n "${ZSH_VERSION:-}" ]; then
+ confirm() {
+ read -q '?Continue? [Y/n] '
+ ret=$?
+ echo
+ return $ret
+ }
+else
+ confirm() {
+ # manually specify stdin (1) to avoid taking input from pipes
+ read -n1 -u 1 -p "Continue? [Y/n] " c
+ echo
+ [ "$c" != 'y' ] && [ "$c" != 'Y' ] && return 1
+ return 0
+ }
+fi
+confirm
diff --git a/danny.sh b/sh/danny.sh/danny.sh
similarity index 100%
rename from danny.sh
rename to sh/danny.sh/danny.sh
diff --git a/sh/days b/sh/days
new file mode 100755
index 0000000..0ac67e1
--- /dev/null
+++ b/sh/days
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+echo $(( ($(date +%s) - $(date -d "$1" +%s)) / 60 / 60 / 24 ))
diff --git a/sh/dbusiest b/sh/dbusiest
new file mode 100644
index 0000000..2b38e80
--- /dev/null
+++ b/sh/dbusiest
@@ -0,0 +1,7 @@
+#!/bin/zsh
+local c d
+for d in *(FD); do
+ print $(find $d 2>/dev/null | wc -l) $d
+done | sort -nr | while read c d; do
+ echo -E $c $d
+done
diff --git a/sh/dfu b/sh/dfu
new file mode 100755
index 0000000..8da3bda
--- /dev/null
+++ b/sh/dfu
@@ -0,0 +1,4 @@
+#!/bin/sh
+df -xtmpfs | awk '
+NR==1{printf"%-20s %7s %7s %7s\n","Filesystem","Used","Max","Misc"}
+NR>1{printf"%-20s %7.2f %7.2f %7.2f\n",$6,$3/2^20,($3+$4)/2^20,($2-$4-$3)/2^20}'
diff --git a/sh/e b/sh/e
new file mode 100755
index 0000000..97a6efb
--- /dev/null
+++ b/sh/e
@@ -0,0 +1,17 @@
+#!/bin/zsh
+# http://unix.stackexchange.com/a/37887
+#[ -n "${ZSH_VERSION:-}" ] && local -A EDITOR ${=EDITOR}
+# TODO: find actually working way of portably splitting word cmds, zsh/bash
+
+if [ $# -eq 0 ]; then
+ $=EDITOR
+ return
+fi
+
+local needroot=0
+for f in $@; do
+ [ -e "$f" ] && { [ -w "$f" ] || needroot=1; }
+# TODO: check directory permissions too
+done
+
+if [ $needroot -eq 0 ]; then $=EDITOR $@; else sudo -e $@; fi
diff --git a/sh/empty/butt b/sh/empty/butt
new file mode 100644
index 0000000..377279e
Binary files /dev/null and b/sh/empty/butt differ
diff --git a/sh/gitall b/sh/gitall
new file mode 100755
index 0000000..b699412
--- /dev/null
+++ b/sh/gitall
@@ -0,0 +1,8 @@
+#!/bin/zsh
+find ~ -name .git -type d \
+| grep -v '/src/\|/work/' \
+| while read -r fp; do
+ cd "${fp%/.git}"
+ pwd
+ confirm && git pull
+done
diff --git a/sh/is_empty b/sh/is_empty
new file mode 100755
index 0000000..b9612b4
--- /dev/null
+++ b/sh/is_empty
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+is_empty() {
+ while read -r; do
+ [ ! -d "$REPLY" ] && [ -s "$REPLY" ] && return 1
+ done < <(find ${1:-.})
+ return 0
+}
+is_empty "$@"
diff --git a/sh/logs b/sh/logs
new file mode 100755
index 0000000..e157730
--- /dev/null
+++ b/sh/logs
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+if [ -n "${ZSH_VERSION:-}" ]; then
+ logs() {
+ local last="${@: -1}"
+ [ -n "$last" ] && [ ${last[1]} != '-' ] && last="-u $last"
+ journalctl ${@:1:-1} $last
+ }
+else
+ logs() {
+ local last="${@: -1}"
+ [ -n "$last" ] && [ ${last:0:1} != '-' ] && last="-u $last"
+ journalctl ${@:1:$(($#-1))} $last
+ }
+fi
+logs "$@"
diff --git a/sh/lsarchive b/sh/lsarchive
new file mode 100755
index 0000000..b9ff15b
--- /dev/null
+++ b/sh/lsarchive
@@ -0,0 +1,57 @@
+#!/bin/zsh
+#
+# Lists the contents of archives.
+#
+# Authors:
+# Sorin Ionescu
+#
+
+local verbose
+
+if (( $# == 0 )); then
+ cat >&2 <.
+EOF
+fi
+
+if [[ "$1" == "-v" || "$1" == "--verbose" ]]; then
+ verbose=0
+ shift
+fi
+
+while (( $# > 0 )); do
+ if [[ ! -s "$1" ]]; then
+ print "$0: file not valid: $1" >&2
+ shift
+ continue
+ fi
+
+ case "$1" in
+ (*.tar.gz|*.tgz) tar t${verbose:+v}vzf "$1" ;;
+ (*.tar.bz2|*.tbz|*.tbz2) tar t${verbose:+v}jf "$1" ;;
+ (*.tar.xz|*.txz) tar --xz --help &> /dev/null \
+ && tar --xz -t${verbose:+v}f "$1" \
+ || xzcat "$1" | tar t${verbose:+v}f - ;;
+ (*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \
+ && tar --lzma -t${verbose:+v}f "$1" \
+ || lzcat "$1" | tar x${verbose:+v}f - ;;
+ (*.tar) tar t${verbose:+v}f "$1" ;;
+ (*.zip) unzip -l${verbose:+v} "$1" ;;
+ (*.rar) unrar &> /dev/null \
+ && unrar ${${verbose:+v}:-l} "$1" \
+ || rar ${${verbose:+v}:-l} "$1" ;;
+ (*.7z) 7za l "$1" ;;
+ (*)
+ print "$0: cannot list: $1" >&2
+ success=1
+ ;;
+ esac
+
+ shift
+done
+
diff --git a/sh/lsf.sh/lsf.sh b/sh/lsf.sh/lsf.sh
new file mode 100755
index 0000000..21d4804
--- /dev/null
+++ b/sh/lsf.sh/lsf.sh
@@ -0,0 +1,172 @@
+#!/bin/bash
+# ultra-fancy ultra-pointless `ls -l` alternative
+# to be sourced by bash or zsh
+# similar project: https://github.com/trapd00r/ls--
+
+# to maintain zsh compatibility:
+# $() is surrounded in double quotes
+# echo -E is used to avoid \033 expanding
+# bare asterisks are escaped to prevent globbing
+# arrays are used instead of relying on word expansion
+# for loops over "${array[@]}" as it works the same in both
+
+# TODO: set better defaults for quick glances at filesize
+# TODO: include sorting somehow
+# TODO: handle symlinks nicely
+# TODO: append WHI / clr to dir names
+
+_lsf_begin(){
+ local begin='
+me='$UID'
+'"$(
+awk -F: '{print "unames["$3"]=\""$1"\""}' < /etc/passwd
+awk -F: '{print "gnames["$3"]=\""$1"\""}' < /etc/group
+for x in $(groups); do echo "us[\"$x\"]=1"; done
+i=0;for x in bla red gre yel blu pur cya whi; do
+ echo -E $x'="\033[3'${i}'m"'
+ echo -n "$x" | tr a-z A-Z
+ echo -E '="\033[1;3'${i}'m"'
+ let i++
+done
+)"'
+clr="\033[0m"
+BLD="\033[1m"
+s=1
+m=60*s
+h=60*m
+d=24*h
+y=365*d
+B=1
+K=1024*B
+M=1024*K
+G=1024*M
+T=1024*G
+ff["time"]="%3d%s " clr
+ff["size"]="%4d" clr "%s "
+'"$(
+for x in s m h d y;do echo "u[\"time,$x\"]=$x";done
+for x in B K M G T;do echo "u[\"size,$x\"]=$x";done
+ft=(-1 m m\*10 h h\*12 d d\*7 30\*d y y\*2 y\*10)
+fut=(s s s m m h h d d d y y)
+fct=(RED PUR pur YEL yel GRE gre CYA cya BLU blu BLA)
+fs=( 0 K K\*8 M M\*8 G G\*8 T T\*8)
+fus=(B B B K K M M G G T)
+fcs=(BLA cya CYA CYA yel yel pur pur red red)
+pc=(BLA WHI yel YEL blu BLU gre GRE)
+i=0;for x in "${ft[@]}"; do echo "f[\"time,$i\"]=$x"; let i++;done
+echo "f[\"times\"]=$i"
+i=0;for x in "${fs[@]}"; do echo "f[\"size,$i\"]=$x"; let i++;done
+echo "f[\"sizes\"]=$i"
+i=0;for x in "${fut[@]}";do echo "fu[\"time,$i\"]=\"$x\"";let i++;done
+i=0;for x in "${fus[@]}";do echo "fu[\"size,$i\"]=\"$x\"";let i++;done
+i=0;for x in "${fct[@]}";do echo "fc[\"time,$i\"]=$x"; let i++;done
+i=0;for x in "${fcs[@]}";do echo "fc[\"size,$i\"]=$x"; let i++;done
+i=0;for x in "${pc[@]}"; do echo "pc[$i]=$x"; let i++;done
+)"
+ echo -E "$begin"
+}
+
+_lsf_cached=
+_lsf_program='
+function printff(id, n) {
+ len=f[id "s"]
+ for(i=0;i<=len;i++) {
+ idi=id "," i
+ if(i!=len && n>f[idi]) continue
+ unit=fu[idi]
+ printf(fc[idi] ff[id], n/u[id "," unit], unit)
+ break
+ }
+}
+
+function trunc(str, len) {
+ e=length(str)>len?"…":""
+ return substr(str,0,len-(e?1:0)) e
+}
+function fixlen(str, len) {
+ return trunc(sprintf("%" len "s", str), len)
+}
+{
+ printff("size", $(NF-14))
+
+ uid=$(NF-11)
+ gid=$(NF-10)
+ is_me=(uid==me)
+ is_us=(gnames[gid] in us)
+
+ bits=("0x" $(NF-12))+0
+ # note: we ignore the set and sticky bits... for now
+ type=rshift(and(bits, 0170000), 12)
+ operm=and(bits, 07)
+ gperm=rshift(and(bits, 070), 3)
+ uperm=rshift(and(bits, 0700), 6)
+ our_perm=or(or((is_me)?uperm:0, (is_us)?gperm:0), operm)
+
+ printf(pc[our_perm] "%o " clr, our_perm)
+ if(OSP) {
+ printf(pc[uperm] "%o" clr, uperm)
+ printf(pc[gperm] "%o" clr, gperm)
+ printf(pc[operm] "%o " clr, operm)
+ }
+
+ if(OSU) {
+ name=fixlen((uid in unames)?unames[uid]:uid, 6)
+ if(is_me) name=WHI name clr
+ printf("%s ", name)
+ }
+
+ if(OSG) {
+ name=fixlen((gid in gnames)?gnames[gid]:gid, 6)
+ if(is_us) name=WHI name clr
+ printf("%s ", name)
+ }
+
+ da=$(NF-4)
+ dc=$(NF-3)
+ dm=$(NF-2)
+ if(OMR) {
+ max=(da>dm)?da:dm
+ max=(max>dc)?max:dc
+ printff("time", now-max)
+ } else {
+ printff("time", now-da)
+ printff("time", now-dm)
+ printff("time", now-dc)
+ }
+
+ # acquire filename by killing all fields not part of it
+ NF-=15
+ fn=$0
+
+ if (!OSPA) {
+ if (NR!=1) fn=substr(fn,firstlen)
+ else firstlen=length(fn)+2-(fn ~ /\/$/)
+ }
+
+ print fn
+}'
+
+lsf(){
+ local o_showallperm=1 o_showuser=1 o_showgroup=1
+ local o_mostrecent=0 o_showpath=1 opts=mgupfs opt
+ while getopts $opts'h' opt; do
+ case $opt in
+ f) _lsf_cached=;;
+ p) o_showallperm=0;;
+ u) o_showuser=0;;
+ g) o_showgroup=0;;
+ m) o_mostrecent=1;;
+ s) o_showpath=0;;
+ ?) echo "usage: $0 [-$opts] [dir]"
+ return 1;;
+ esac
+ done
+
+ [ "$_lsf_cached" ] || _lsf_cached="$(_lsf_begin)"
+
+ shift $((OPTIND-1))
+ find "${1:-.}" -maxdepth 1 -exec stat -t {} + | awk --non-decimal-data \
+-v"now=$(date +%s)" -v"OMR=$o_mostrecent" -v"OSU=$o_showuser" \
+-v"OSG=$o_showgroup" -v"OSP=$o_showallperm" -v"OSPA=$o_showpath" \
+"BEGIN{$_lsf_cached}$_lsf_program"
+}
diff --git a/sh/lsz b/sh/lsz
new file mode 100755
index 0000000..d972b1c
--- /dev/null
+++ b/sh/lsz
@@ -0,0 +1,126 @@
+#!/bin/zsh
+# TODO: safe-ify echos and prints
+local din=${1:-$(pwd)}
+din=${din%/} # TODO: hackish
+
+local -A unames gnames us
+while IFS=: read -rA A; do unames[${A[3]}]=${A[1]} done < /etc/passwd
+while IFS=: read -rA A; do gnames[${A[3]}]=${A[1]} done < /etc/group
+for x in $(groups); do us[$x]=1 done
+
+local -a colors
+colors=(bla red gre yel blu pur cya whi)
+local i= $=colors ${(U)=colors} clr=$'\e[0m'
+for i in {0..7}; do
+ local x=${colors[$((i+1))]}
+ eval "$x=$'\\e[3${i}m'" "${(U)x}=$'\\e[9${i}m'"
+done
+
+local s=1 m h d y B=1 K M G T
+noglob let m=60*s h=60*m d=24*h y=365*d K=1024*B M=1024*K G=1024*M T=1024*G
+
+local -a ft fut fct fs fus fcs
+
+local s_ft='
+y*10 y BLA
+y*2 y blu
+y d BLU
+d*30 d cya
+d*7 d CYA
+d h gre
+h*12 h GRE
+h m yel
+m*10 m YEL
+m s pur
+0 s PUR
+'
+local s_fs='
+T*8 T red
+T G red
+G*8 G pur
+G M pur
+M M yel
+M K yel
+K B CYA
+1 B cya
+0 B BLA
+'
+
+local permcolors="$BLA $WHI $yel $YEL $blu $BLU $gre $GRE"
+permcolors=($=permcolors)
+
+# TODO: functionize for better locals
+local min unit color
+for min unit color in $=s_ft; do
+ # TODO: consider dereferencing color, [no]and coloring unit itself[/no]
+ ft+=($(($min)) $unit $color)
+done
+for min unit color in $=s_fs; do
+ fs+=($(($min)) $unit $color)
+done
+
+trunc() { # deprecate me for speed...
+ local len=${1:-$COLUMNS} c='…' L
+ local end=$((len-1))
+ while read -r L; do
+ [ ${#L} -gt $len ] && echo ${L[1,$end]}$c || echo $L
+ done
+}
+
+prettify() {
+ local min unit color
+ for min unit color in ${(P)2}; do
+ [ $1 -lt $min ] && continue
+ local unitified=$(($1/$unit))
+ echo -n "${(P)color}${(l:4:)unitified}$clr$unit "
+ break
+ done
+}
+
+min() {
+ local min=99999999999 x
+ for x; do [ $x -lt $min ] && min=$x; done
+ echo $min
+}
+
+permprint() {
+ echo -n ${permcolors[$(($1+1))]}$1
+}
+
+local now=$(date +%s)
+local f="$din/*(D)"
+stat -t -- ${~f} | while read -rA A; do
+ prettify ${A[-15]} fs
+
+ local uid=${A[-12]} gid=${A[-11]} is_me=0 is_us=0
+ local uname=${unames[$uid]} gname=${gnames[$gid]}
+ [ $uid -eq $UID ] && is_me=1
+ [ -n "$gname" ] && [[ ${us[$gname]} -eq 1 ]] && is_us=1
+
+ local bits=$((16#${A[-13]})) type= uperm= gperm= operm= our_perm=
+ let 'type=(bits & 8#170000) >> 12'
+ let 'uperm=(bits & 8#700) >> 6'
+ let 'gperm=(bits & 8#70) >> 3'
+ let 'operm=bits & 8#7'
+ let 'our_perm=(is_me?uperm:0) | (is_us?gperm:0) | operm'
+
+ permprint $our_perm
+
+ true && {
+ echo -n ' '
+ permprint $uperm
+ permprint $gperm
+ permprint $operm
+ }
+
+ echo -n "$clr"
+
+ local da=${A[-5]} dc=${A[-4]} dm=${A[-3]}
+ let da=now-da dc=now-dc dm=now-dm
+ prettify $(min $da $dc $dm) ft
+ #prettify $da ft
+ #prettify $dm ft
+ #prettify $dc ft
+
+ echo ${A[1,-16]}
+done
diff --git a/sh/meow.sh/README.md b/sh/meow.sh/README.md
new file mode 100644
index 0000000..10d1005
--- /dev/null
+++ b/sh/meow.sh/README.md
@@ -0,0 +1,20 @@
+# meow.sh
+
+Prints out the title, torrent link, and timestamp
+for every new release matching your regular expressions
+and reminds you that your taste in anime is shit.
+
+## Usage
+
+Just take a peek at `run` and `config.sh` for now.
+If you can't figure it out, you're too sane to use this.
+
+## License
+
+These scripts are hardly unique so
+I'm not signing my name on them and
+I'm not applying any license.
+Just pretend they're under the [WTFPL][0]
+if you really want to.
+
+[0]: http://www.wtfpl.net/txt/copying/
diff --git a/sh/meow.sh/config.sh b/sh/meow.sh/config.sh
new file mode 100644
index 0000000..59dcb88
--- /dev/null
+++ b/sh/meow.sh/config.sh
@@ -0,0 +1,3 @@
+watch Commie 'Yuyushiki - \d\d' 'Aiura - \d\d'
+watch rori 'Hentai Ouji to Warawanai Neko - '
+watch FFF 'DATE A LIVE - \d\d(?!v0)'
diff --git a/sh/meow.sh/meow.sh b/sh/meow.sh/meow.sh
new file mode 100644
index 0000000..6c6c4e4
--- /dev/null
+++ b/sh/meow.sh/meow.sh
@@ -0,0 +1,89 @@
+#!/usr/bin/env bash
+SEP=$'\1'
+
+die() {
+ echo -E "$@" 1>&2
+ exit 1
+}
+
+nullcheck() {
+ [[ -n "$1" ]] || die "Null group name";
+}
+
+sanitize() {
+ sed -e 's/[^0-9a-zA-Z_]/_/g'
+}
+
+splittags() {
+ awk -v tag="$1" -f "$SRCDIR/splittags.awk"
+}
+
+scrape() {
+ TZ=UTC0 awk -v g="$1" -v timestamp="${2:-0}" -v sep="$SEP" -f "$SRCDIR/scrape.awk"
+}
+
+declare -A groupinsane # unsanitized group names
+declare -A groupshows # regexes
+watch() { # {group name} [regex...]
+ nullcheck "$1"
+ local gs="$(sanitize<<<"$1")"
+ groupinsane[$gs]="$1"
+ shift
+ while (( "$#" )); do
+ groupshows[$gs]+="|($1)"
+ shift
+ done
+}
+
+declare -A grouptimes # last times timestamp
+touchgroup() { # {group name} {unix time}
+ nullcheck "$1"
+ local gs="$(sanitize<<<"$1")"
+ grouptimes[$gs]="$2"
+}
+
+groupreleases() { # groupname [timestamp]
+ nullcheck "$1"
+ # TODO: escapeurl $1
+ local URL="http://www.nyaa.eu/?page=search&term=%5B$1%5D&page=rss"
+ curl -LsS "$URL" > "$1.xml" || die "Failed to retrieve releases for $1"
+ tr -d '\r\n'"$SEP" < "$1.xml" | splittags item | scrape "$1" "${2:-}"
+}
+
+groupfilter() { # groupname regex [timestamp]
+ groupreleases "$1" "${3:-}" | while IFS=$SEP read -r title etc; do
+ grep -P "$2" <<< "$title" 1>/dev/null && echo -E "$title$SEP$etc"
+ done
+ [ ${PIPESTATUS[0]} = 0 ] || exit 1
+}
+
+cleanup() {
+ for gs in "${!grouptimes[@]}"; do
+ local v="${grouptimes[$gs]}"
+ echo -E "touchgroup $gs $v" >> times.sh
+ [ -e "$gs.xml" ] && rm "$gs.xml"
+ done
+ exit ${1:-1}
+}
+
+rungroup() {
+ local insane regex timestamp res recent
+ insane="${groupinsane[$1]}"
+ regex="${groupshows[$1]:1}"
+ timestamp="${grouptimes[$1]}"
+ res="$(groupfilter "$insane" "$regex" "$timestamp")"
+ [ $? = 0 ] || return $?
+ IFS=$SEP read -r _ _ recent <<< "$res"
+ [ -n "$recent" ] && {
+ grouptimes[$1]="$recent"
+ echo -E "$res"
+ }
+ return 0
+}
+
+runall() {
+ trap cleanup INT
+ ret=0
+ for gs in "${!groupshows[@]}"; do rungroup "$gs" || ret=1; done
+ cleanup $ret
+}
diff --git a/sh/meow.sh/run b/sh/meow.sh/run
new file mode 100755
index 0000000..0cb8a20
--- /dev/null
+++ b/sh/meow.sh/run
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+SRCDIR="$(readlink -f "$(dirname "$0")" )"
+
+# TODO: a way to pass opts to transmission-remote
+
+declare -a actions
+while getopts 'aph' opt; do
+ case $opt in
+ a) actions+=(addtorrent);;
+ p) actions+=(prettify);;
+ ?) echo -E "usage: $0 [-ap]" 1>&2;;
+ esac
+done
+
+prettify() {
+ echo -E "$1"$'\n'"dl:"$'\t'"$2"$'\n'"at:"$'\t'"$(date -d @"$3")"
+}
+
+declare -a torrents
+addtorrent() {
+ torrents+=("$2")
+}
+
+runactions() {
+ [ ${#actions} = 0 ] && {
+ cat
+ return
+ }
+ while IFS=$SEP read -r title torrent time; do
+ for a in "${actions[@]}"; do
+ "$a" "$title" "$torrent" "$time"
+ done
+ done
+ [ ${#torrents} = 0 ] || transmission-remote -a "${torrents[@]}"
+}
+
+. "$SRCDIR/meow.sh"
+. config.sh
+[ -e times.sh ] && { . times.sh; mv times.sh times.sh.old; }
+runall | runactions
+exit ${PIPESTATUS[0]}
diff --git a/sh/meow.sh/scrape.awk b/sh/meow.sh/scrape.awk
new file mode 100644
index 0000000..bc4c0f1
--- /dev/null
+++ b/sh/meow.sh/scrape.awk
@@ -0,0 +1,39 @@
+function opentag(str, tag) {
+ topen="<"tag">"
+ tclose=""tag">"
+ len=length(tag)
+ begin=index(str, topen)
+ end=index(str, tclose)
+ return (begin && end) ? substr(str, begin+len+2, end-begin-len-2) : ""
+}
+
+function unescape(str) {
+ while (match(str, /([0-9]+);/, b))
+ str=substr(str, 1, RSTART-1) sprintf("%c",b[1]) substr(str, RSTART+RLENGTH)
+ return str
+}
+
+function hotdate(str) {
+ split(str, d, "[ :]")
+ return mktime(d[4]" "months[d[3]]" "d[2]" "d[5]" "d[6]" "d[7])
+}
+
+BEGIN{
+ # http://stackoverflow.com/a/2123002
+ m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
+ for(o=1;o<=m;o++) months[d[o]]=sprintf("%02d",o)
+ glen=length(g)
+}
+
+function run(str) {
+ title=unescape(opentag(str, "title"))
+ if (substr(title,1,glen+2) != "["g"]") return
+ pub=unescape(opentag($0, "pubDate"))
+# "date -d \""pub "\" +%s" | getline pubunix
+ pubunix=hotdate(pub)
+ if (pubunix <= timestamp) return
+ torrent=unescape(opentag(str, "link"))
+ print title sep torrent sep pubunix
+}
+
+{run($0)}
diff --git a/sh/meow.sh/splittags.awk b/sh/meow.sh/splittags.awk
new file mode 100644
index 0000000..689f54a
--- /dev/null
+++ b/sh/meow.sh/splittags.awk
@@ -0,0 +1,13 @@
+{
+ str=$0
+ topen="<"tag">"
+ tclose=""tag">"
+ len=length(tag)
+ for (;;) {
+ begin=index(str, topen)
+ end=index(str,tclose)
+ if (!(begin || end)) break
+ print substr(str, begin+len+2, end-begin-len-2)
+ str=substr(str, end+len+3)
+ }
+}
diff --git a/sh/pacman-list-disowned b/sh/pacman-list-disowned
new file mode 100755
index 0000000..3ff1e3f
--- /dev/null
+++ b/sh/pacman-list-disowned
@@ -0,0 +1,24 @@
+#
+# Lists Pacman disowned files.
+#
+# Authors:
+# Benjamin Boudreau
+# Sorin Ionescu
+#
+
+TMPDIR=/tmp
+local tmp="$TMPDIR/pacman-disowned-$UID-$$"
+local db="$tmp/db"
+local fs="$tmp/fs"
+
+mkdir "$tmp"
+trap 'rm -rf "$tmp"' EXIT
+
+pacman --quiet --query --list | sort --unique > "$db"
+
+find /bin /etc /lib /sbin /usr \
+ ! -name lost+found \
+ \( -type d -printf '%p/\n' -o -print \) | sort > "$fs"
+
+comm -23 "$fs" "$db"
+
diff --git a/sh/pause b/sh/pause
new file mode 100755
index 0000000..a753371
--- /dev/null
+++ b/sh/pause
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+[ -n "${ZSH_VERSION:-}" ] \
+&& read -sk '?Press any key to continue
+' || read -n1 -u 1 -sp 'Press any key to continue
+'
diff --git a/sh/psbm b/sh/psbm
new file mode 100755
index 0000000..feb5ee2
--- /dev/null
+++ b/sh/psbm
@@ -0,0 +1,5 @@
+#!/bin/sh
+ps axco rss,pid,command | awk '
+NR>1&&$1>0{t+=$1;printf("%8.2fM %7d %s\n",$1/1024,$2,$3)}
+END{printf("%8.2fM\n",t/1024)}
+' | sort -n
diff --git a/sh/randir b/sh/randir
new file mode 100755
index 0000000..3184183
--- /dev/null
+++ b/sh/randir
@@ -0,0 +1,2 @@
+#!/bin/sh
+find -maxdepth 1 -type d \( -path '/root' -prune -o -print \) | shuf | head -1
diff --git a/sh/scropt b/sh/scropt
new file mode 100755
index 0000000..d8fc09f
--- /dev/null
+++ b/sh/scropt
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+local now=$(date +%F_%H-%M-%S)
+scrot ~/$now.png -e "optipng -quiet \$f" \
+&& mv ~/$now.png ~/Dropbox/Public/screenshots/
diff --git a/sh/similar b/sh/similar
new file mode 100755
index 0000000..d22f9fa
--- /dev/null
+++ b/sh/similar
@@ -0,0 +1,12 @@
+#!/bin/sh
+awk '
+{
+ i=0
+ split($0,a,"")
+ split(L,b,"")
+ for (c in a)
+ if (a[c]==b[c]) i++
+ else break
+ print substr($0,1,i) "\033[7m" substr($0,i+1) "\033[0m"
+ L=$0
+}'
diff --git a/sh/slit b/sh/slit
new file mode 100755
index 0000000..1dfef11
--- /dev/null
+++ b/sh/slit
@@ -0,0 +1,3 @@
+#!/bin/zsh
+# from https://github.com/sorin-ionescu/prezto/
+awk "{ print ${(j:,:):-\$${^@}} }"
diff --git a/sh/trunc b/sh/trunc
new file mode 100755
index 0000000..3c6c312
--- /dev/null
+++ b/sh/trunc
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+COLUMNS=${COLUMNS:-$(tput cols)}
+awk -vL=${1:-$COLUMNS} '{e=length>L?"…":"";print substr($0,0,L-(e?1:0)) e}'
diff --git a/sh/unarchive b/sh/unarchive
new file mode 100755
index 0000000..cc99156
--- /dev/null
+++ b/sh/unarchive
@@ -0,0 +1,80 @@
+#!/bin/zsh
+#
+# Extracts the contents of archives.
+#
+# Authors:
+# Sorin Ionescu
+#
+
+local remove_archive
+local success
+local file_name
+local extract_dir
+
+if (( $# == 0 )); then
+ cat >&2 <.
+EOF
+fi
+
+remove_archive=1
+if [[ "$1" == "-r" || "$1" == "--remove" ]]; then
+ remove_archive=0
+ shift
+fi
+
+while (( $# > 0 )); do
+ if [[ ! -s "$1" ]]; then
+ print "$0: file not valid: $1" >&2
+ shift
+ continue
+ fi
+
+ success=0
+ file_name="${1:t}"
+ extract_dir="${file_name:r}"
+ case "$1" in
+ (*.tar.gz|*.tgz) tar xvzf "$1" ;;
+ (*.tar.bz2|*.tbz|*.tbz2) tar xvjf "$1" ;;
+ (*.tar.xz|*.txz) tar --xz --help &> /dev/null \
+ && tar --xz -xvf "$1" \
+ || xzcat "$1" | tar xvf - ;;
+ (*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \
+ && tar --lzma -xvf "$1" \
+ || lzcat "$1" | tar xvf - ;;
+ (*.tar) tar xvf "$1" ;;
+ (*.gz) gunzip "$1" ;;
+ (*.bz2) bunzip2 "$1" ;;
+ (*.xz) unxz "$1" ;;
+ (*.lzma) unlzma "$1" ;;
+ (*.Z) uncompress "$1" ;;
+ (*.zip) unzip "$1" -d $extract_dir ;;
+ (*.rar) unrar &> /dev/null \
+ && unrar e -ad "$1" \
+ || rar e -ad "$1" ;;
+ (*.7z) 7za x "$1" ;;
+ (*.deb)
+ mkdir -p "$extract_dir/control"
+ mkdir -p "$extract_dir/data"
+ cd "$extract_dir"; ar vx "../${1}" > /dev/null
+ cd control; tar xzvf ../control.tar.gz
+ cd ../data; tar xzvf ../data.tar.gz
+ cd ..; rm *.tar.gz debian-binary
+ cd ..
+ ;;
+ (*)
+ print "$0: cannot extract: $1" >&2
+ success=1
+ ;;
+ esac
+
+ (( success = $success > 0 ? $success : $? ))
+ (( $success == 0 )) && (( $remove_archive == 0 )) && rm "$1"
+ shift
+done
+
diff --git a/sh/z/Makefile b/sh/z/Makefile
new file mode 100644
index 0000000..dcf433d
--- /dev/null
+++ b/sh/z/Makefile
@@ -0,0 +1,4 @@
+readme:
+ @groff -man -Tascii z.1 | col -bx
+
+.PHONY: readme
diff --git a/sh/z/README b/sh/z/README
new file mode 100644
index 0000000..4257001
--- /dev/null
+++ b/sh/z/README
@@ -0,0 +1,137 @@
+Z(1) User Commands Z(1)
+
+
+
+NAME
+ z - jump around
+
+SYNOPSIS
+ z [-chlrtx] [regex1 regex2 ... regexn]
+
+AVAILABILITY
+ bash, zsh
+
+DESCRIPTION
+ Tracks your most used directories, based on 'frecency'.
+
+ After a short learning phase, z will take you to the most 'frecent'
+ directory that matches ALL of the regexes given on the command line.
+
+OPTIONS
+ -c restrict matches to subdirectories of the current directory
+
+ -h show a brief help message
+
+ -l list only
+
+ -r match by rank only
+
+ -t match by recent access only
+
+ -x remove the current directory from the datafile
+
+EXAMPLES
+ z foo cd to most frecent dir matching foo
+
+ z foo bar cd to most frecent dir matching foo and bar
+
+ z -r foo cd to highest ranked dir matching foo
+
+ z -t foo cd to most recently accessed dir matching foo
+
+ z -l foo list all dirs matching foo (by frecency)
+
+NOTES
+ Installation:
+ Put something like this in your $HOME/.bashrc or $HOME/.zshrc:
+
+ . /path/to/z.sh
+
+ cd around for a while to build up the db.
+
+ PROFIT!!
+
+ Optionally:
+ Set $_Z_CMD to change the command name (default z).
+ Set $_Z_DATA to change the datafile (default $HOME/.z).
+ Set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution.
+ Set $_Z_NO_PROMPT_COMMAND to handle PROMPT_COMMAND/precmd your-
+ self.
+ Set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
+ (These settings should go in .bashrc/.zshrc before the lines
+ added above.)
+ Install the provided man page z.1 somewhere like
+ /usr/local/man/man1.
+
+ Aging:
+ The rank of directories maintained by z undergoes aging based on a sim-
+ ple formula. The rank of each entry is incremented every time it is
+ accessed. When the sum of ranks is greater than 6000, all ranks are
+ multiplied by 0.99. Entries with a rank lower than 1 are forgotten.
+
+ Frecency:
+ Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted
+ rank that depends on how often and how recently something occurred. As
+ far as I know, Mozilla came up with the term.
+
+ To z, a directory that has low ranking but has been accessed recently
+ will quickly have higher rank than a directory accessed frequently a
+ long time ago.
+
+ Frecency is determined at runtime.
+
+ Common:
+ When multiple directories match all queries, and they all have a common
+ prefix, z will cd to the shortest matching directory, without regard to
+ priority. This has been in effect, if undocumented, for quite some
+ time, but should probably be configurable or reconsidered.
+
+ Tab Completion:
+ z supports tab completion. After any number of arguments, press TAB to
+ complete on directories that match each argument. Due to limitations of
+ the completion implementations, only the last argument will be com-
+ pleted in the shell.
+
+ Internally, z decides you've requested a completion if the last argu-
+ ment passed is an absolute path to an existing directory. This may
+ cause unexpected behavior if the last argument to z begins with /.
+
+ENVIRONMENT
+ A function _z() is defined.
+
+ The contents of the variable $_Z_CMD is aliased to _z 2>&1. If not set,
+ $_Z_CMD defaults to z.
+
+ The environment variable $_Z_DATA can be used to control the datafile
+ location. If it is not defined, the location defaults to $HOME/.z.
+
+ The environment variable $_Z_NO_RESOLVE_SYMLINKS can be set to prevent
+ resolving of symlinks. If it is not set, symbolic links will be
+ resolved when added to the datafile.
+
+ In bash, z appends a command to the PROMPT_COMMAND environment variable
+ to maintain its database. In zsh, z appends a function _z_precmd to the
+ precmd_functions array.
+
+ The environment variable $_Z_NO_PROMPT_COMMAND can be set if you want
+ to handle PROMPT_COMMAND or precmd yourself.
+
+ The environment variable $_Z_EXCLUDE_DIRS can be set to an array of
+ directories to exclude from tracking. $HOME is always excluded. Direc-
+ tories must be full paths without trailing slashes.
+
+FILES
+ Data is stored in $HOME/.z. This can be overridden by setting the
+ $_Z_DATA environment variable. When initialized, z will raise an error
+ if this path is a directory, and not function correctly.
+
+ A man page (z.1) is provided.
+
+SEE ALSO
+ regex(7), pushd, popd, autojump, cdargs
+
+ Please file bugs at https://github.com/rupa/z/
+
+
+
+z January 2013 Z(1)
diff --git a/sh/z/z.1 b/sh/z/z.1
new file mode 100644
index 0000000..4d2a607
--- /dev/null
+++ b/sh/z/z.1
@@ -0,0 +1,158 @@
+.TH "Z" "1" "January 2013" "z" "User Commands"
+.SH
+NAME
+z \- jump around
+.SH
+SYNOPSIS
+z [\-chlrtx] [regex1 regex2 ... regexn]
+.SH
+AVAILABILITY
+bash, zsh
+.SH
+DESCRIPTION
+Tracks your most used directories, based on 'frecency'.
+.P
+After a short learning phase, \fBz\fR will take you to the most 'frecent'
+directory that matches ALL of the regexes given on the command line.
+.SH
+OPTIONS
+.TP
+\fB\-c\fR
+restrict matches to subdirectories of the current directory
+.TP
+\fB\-h\fR
+show a brief help message
+.TP
+\fB\-l\fR
+list only
+.TP
+\fB\-r\fR
+match by rank only
+.TP
+\fB\-t\fR
+match by recent access only
+.TP
+\fB\-x\fR
+remove the current directory from the datafile
+.SH EXAMPLES
+.TP 14
+\fBz foo\fR
+cd to most frecent dir matching foo
+.TP 14
+\fBz foo bar\fR
+cd to most frecent dir matching foo and bar
+.TP 14
+\fBz -r foo\fR
+cd to highest ranked dir matching foo
+.TP 14
+\fBz -t foo\fR
+cd to most recently accessed dir matching foo
+.TP 14
+\fBz -l foo\fR
+list all dirs matching foo (by frecency)
+.SH
+NOTES
+.SS
+Installation:
+.P
+Put something like this in your \fB$HOME/.bashrc\fR or \fB$HOME/.zshrc\fR:
+.RS
+.P
+\fB. /path/to/z.sh\fR
+.RE
+.P
+\fBcd\fR around for a while to build up the db.
+.P
+PROFIT!!
+.P
+Optionally:
+.RS
+Set \fB$_Z_CMD\fR to change the command name (default \fBz\fR).
+.RE
+.RS
+Set \fB$_Z_DATA\fR to change the datafile (default \fB$HOME/.z\fR).
+.RE
+.RS
+Set \fB$_Z_NO_RESOLVE_SYMLINKS\fR to prevent symlink resolution.
+.RE
+.RS
+Set \fB$_Z_NO_PROMPT_COMMAND\fR to handle \fBPROMPT_COMMAND/precmd\fR yourself.
+.RE
+.RS
+Set \fB$_Z_EXCLUDE_DIRS\fR to an array of directories to exclude.
+.RE
+.RS
+(These settings should go in .bashrc/.zshrc before the lines added above.)
+.RE
+.RS
+Install the provided man page \fBz.1\fR somewhere like \fB/usr/local/man/man1\fR.
+.RE
+.SS
+Aging:
+The rank of directories maintained by \fBz\fR undergoes aging based on a simple
+formula. The rank of each entry is incremented every time it is accessed. When
+the sum of ranks is greater than 6000, all ranks are multiplied by 0.99. Entries
+with a rank lower than 1 are forgotten.
+.SS
+Frecency:
+Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted rank
+that depends on how often and how recently something occurred. As far as I
+know, Mozilla came up with the term.
+.P
+To \fBz\fR, a directory that has low ranking but has been accessed recently
+will quickly have higher rank than a directory accessed frequently a long time
+ago.
+.P
+Frecency is determined at runtime.
+.SS
+Common:
+When multiple directories match all queries, and they all have a common prefix,
+\fBz\fR will cd to the shortest matching directory, without regard to priority.
+This has been in effect, if undocumented, for quite some time, but should
+probably be configurable or reconsidered.
+.SS
+Tab Completion:
+\fBz\fR supports tab completion. After any number of arguments, press TAB to
+complete on directories that match each argument. Due to limitations of the
+completion implementations, only the last argument will be completed in the
+shell.
+.P
+Internally, \fBz\fR decides you've requested a completion if the last argument
+passed is an absolute path to an existing directory. This may cause unexpected
+behavior if the last argument to \fBz\fR begins with \fB/\fR.
+.SH
+ENVIRONMENT
+A function \fB_z()\fR is defined.
+.P
+The contents of the variable \fB$_Z_CMD\fR is aliased to \fB_z 2>&1\fR. If not
+set, \fB$_Z_CMD\fR defaults to \fBz\fR.
+.P
+The environment variable \fB$_Z_DATA\fR can be used to control the datafile
+location. If it is not defined, the location defaults to \fB$HOME/.z\fR.
+.P
+The environment variable \fB$_Z_NO_RESOLVE_SYMLINKS\fR can be set to prevent
+resolving of symlinks. If it is not set, symbolic links will be resolved when
+added to the datafile.
+.P
+In bash, \fBz\fR appends a command to the \fBPROMPT_COMMAND\fR environment
+variable to maintain its database. In zsh, \fBz\fR appends a function
+\fB_z_precmd\fR to the \fBprecmd_functions\fR array.
+.P
+The environment variable \fB$_Z_NO_PROMPT_COMMAND\fR can be set if you want to
+handle \fBPROMPT_COMMAND\fR or \fBprecmd\fR yourself.
+.P
+The environment variable \fB$_Z_EXCLUDE_DIRS\fR can be set to an array of
+directories to exclude from tracking. \fB$HOME\fR is always excluded.
+Directories must be full paths without trailing slashes.
+.SH
+FILES
+Data is stored in \fB$HOME/.z\fR. This can be overridden by setting the
+\fB$_Z_DATA\fR environment variable. When initialized, \fBz\fR will raise an
+error if this path is a directory, and not function correctly.
+.P
+A man page (\fBz.1\fR) is provided.
+.SH
+SEE ALSO
+regex(7), pushd, popd, autojump, cdargs
+.P
+Please file bugs at https://github.com/rupa/z/
diff --git a/sh/z/z.sh b/sh/z/z.sh
new file mode 100644
index 0000000..6dc70f9
--- /dev/null
+++ b/sh/z/z.sh
@@ -0,0 +1,236 @@
+# Copyright (c) 2009 rupa deadwyler under the WTFPL license
+
+# maintains a jump-list of the directories you actually use
+#
+# INSTALL:
+# * put something like this in your .bashrc/.zshrc:
+# . /path/to/z.sh
+# * cd around for a while to build up the db
+# * PROFIT!!
+# * optionally:
+# set $_Z_CMD in .bashrc/.zshrc to change the command (default z).
+# set $_Z_DATA in .bashrc/.zshrc to change the datafile (default ~/.z).
+# set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution.
+# set $_Z_NO_PROMPT_COMMAND if you're handling PROMPT_COMMAND yourself.
+# set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
+#
+# USE:
+# * z foo # cd to most frecent dir matching foo
+# * z foo bar # cd to most frecent dir matching foo and bar
+# * z -r foo # cd to highest ranked dir matching foo
+# * z -t foo # cd to most recently accessed dir matching foo
+# * z -l foo # list matches instead of cd
+# * z -c foo # restrict matches to subdirs of $PWD
+
+[ -d "${_Z_DATA:-$HOME/.z}" ] && {
+ echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory."
+}
+
+_z() {
+
+ local datafile="${_Z_DATA:-$HOME/.z}"
+
+ # bail if we don't own ~/.z (we're another user but our ENV is still set)
+ [ -f "$datafile" -a ! -O "$datafile" ] && return
+
+ # add entries
+ if [ "$1" = "--add" ]; then
+ shift
+
+ # $HOME isn't worth matching
+ [ "$*" = "$HOME" ] && return
+
+ # don't track excluded dirs
+ local exclude
+ for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do
+ [ "$*" = "$exclude" ] && return
+ done
+
+ # maintain the file
+ local tempfile
+ tempfile="$datafile.$RANDOM"
+ while read line; do
+ # only count directories
+ [ -d "${line%%\|*}" ] && echo $line
+ done < "$datafile" | awk -v path="$*" -v now="$(date +%s)" -F"|" '
+ BEGIN {
+ rank[path] = 1
+ time[path] = now
+ }
+ $2 >= 1 {
+ if( $1 == path ) {
+ rank[$1] = $2 + 1
+ time[$1] = now
+ } else {
+ rank[$1] = $2
+ time[$1] = $3
+ }
+ count += $2
+ }
+ END {
+ if( count > 6000 ) {
+ # aging
+ for( i in rank ) print i "|" 0.99*rank[i] "|" time[i]
+ } else for( i in rank ) print i "|" rank[i] "|" time[i]
+ }
+ ' 2>/dev/null >| "$tempfile"
+ if [ $? -ne 0 -a -f "$datafile" ]; then
+ env rm -f "$tempfile"
+ else
+ env mv -f "$tempfile" "$datafile" || env rm -f "$tmpfile"
+ fi
+
+ # tab completion
+ elif [ "$1" = "--complete" ]; then
+ while read line; do
+ [ -d "${line%%\|*}" ] && echo $line
+ done < "$datafile" | awk -v q="$2" -F"|" '
+ BEGIN {
+ if( q == tolower(q) ) nocase = 1
+ split(substr(q,3),fnd," ")
+ }
+ {
+ if( nocase ) {
+ for( i in fnd ) tolower($1) !~ tolower(fnd[i]) && $1 = ""
+ } else {
+ for( i in fnd ) $1 !~ fnd[i] && $1 = ""
+ }
+ if( $1 ) print $1
+ }
+ ' 2>/dev/null
+
+ else
+ # list/go
+ while [ "$1" ]; do case "$1" in
+ --) while [ "$1" ]; do shift; local fnd="$fnd $1";done;;
+ -*) local opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in
+ c) local fnd="^$PWD $fnd";;
+ h) echo "${_Z_CMD:-z} [-chlrtx] args" >&2; return;;
+ x) sed -i "\:^${PWD}|.*:d" "$datafile";;
+ l) local list=1;;
+ r) local typ="rank";;
+ t) local typ="recent";;
+ esac; opt=${opt:1}; done;;
+ *) local fnd="$fnd $1";;
+ esac; local last=$1; shift; done
+ [ "$fnd" -a "$fnd" != "^$PWD " ] || local list=1
+
+ # if we hit enter on a completion just go there
+ case "$last" in
+ # completions will always start with /
+ /*) [ -z "$list" -a -d "$last" ] && cd "$last" && return;;
+ esac
+
+ # no file yet
+ [ -f "$datafile" ] || return
+
+ local cd
+ cd="$(while read line; do
+ [ -d "${line%%\|*}" ] && echo $line
+ done < "$datafile" | awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" '
+ function frecent(rank, time) {
+ # relate frequency and time
+ dx = t-time
+ if( dx < 3600 ) return rank*4
+ if( dx < 86400 ) return rank*2
+ if( dx < 604800 ) return rank/2
+ return rank/4
+ }
+ function output(files, toopen, common) {
+ # list or return the desired directory
+ if( list ) {
+ cmd = "sort -n >&2"
+ for( i in files ) {
+ if( files[i] ) printf "%-10s %s\n", files[i], i | cmd
+ }
+ if( common ) {
+ printf "%-10s %s\n", "common:", common > "/dev/stderr"
+ }
+ } else {
+ if( common ) toopen = common
+ print toopen
+ }
+ }
+ function common(matches) {
+ # find the common root of a list of dirs, if it exists
+ for( i in matches ) {
+ if( matches[i] && (!short || length(i) < length(short)) ) {
+ short = i
+ }
+ }
+ if( short == "/" ) return
+ # use a copy to escape special characters, as we want to return
+ # the original.
+ clean_short = short
+ gsub(/[\(\)\[\]\|]/, "\\\\&", clean_short)
+ for( i in matches ) if( matches[i] && i !~ clean_short ) return
+ return short
+ }
+ BEGIN { split(q, a, " "); oldf = noldf = -9999999999 }
+ {
+ if( typ == "rank" ) {
+ f = $2
+ } else if( typ == "recent" ) {
+ f = $3-t
+ } else f = frecent($2, $3)
+ wcase[$1] = nocase[$1] = f
+ for( i in a ) {
+ if( $1 !~ a[i] ) delete wcase[$1]
+ if( tolower($1) !~ tolower(a[i]) ) delete nocase[$1]
+ }
+ if( wcase[$1] && wcase[$1] > oldf ) {
+ cx = $1
+ oldf = wcase[$1]
+ } else if( nocase[$1] && nocase[$1] > noldf ) {
+ ncx = $1
+ noldf = nocase[$1]
+ }
+ }
+ END {
+ if( cx ) {
+ output(wcase, cx, common(wcase))
+ } else if( ncx ) output(nocase, ncx, common(nocase))
+ }
+ ')"
+ [ $? -gt 0 ] && return
+ [ "$cd" ] && cd "$cd"
+ fi
+}
+
+alias ${_Z_CMD:-z}='_z 2>&1'
+
+[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P"
+
+if compctl &> /dev/null; then
+ # zsh
+ [ "$_Z_NO_PROMPT_COMMAND" ] || {
+ # populate directory list, avoid clobbering any other precmds
+ if [ "$_Z_NO_RESOLVE_SYMLINKS" ]; then
+ _z_precmd() {
+ _z --add "${PWD:a}"
+ }
+ else
+ _z_precmd() {
+ _z --add "${PWD:A}"
+ }
+ fi
+ precmd_functions+=(_z_precmd)
+ }
+ _z_zsh_tab_completion() {
+ # tab completion
+ local compl
+ read -l compl
+ reply=(${(f)"$(_z --complete "$compl")"})
+ }
+ compctl -U -K _z_zsh_tab_completion _z
+elif complete &> /dev/null; then
+ # bash
+ # tab completion
+ complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z}
+ [ "$_Z_NO_PROMPT_COMMAND" ] || {
+ # bash populate directory list. avoid clobbering other PROMPT_COMMANDs.
+ grep -q "_z --add" <<< "$PROMPT_COMMAND" || {
+ PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''_z --add "$(pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null;'
+ }
+ }
+fi
diff --git a/shrc.zsh b/shrc.zsh
new file mode 100644
index 0000000..9026940
--- /dev/null
+++ b/shrc.zsh
@@ -0,0 +1,53 @@
+# for both zsh and bash
+
+umask 027 # screw others
+
+export PATH="$PATH:$HOME/opt/local/bin"
+export PATH="$PATH:$HOME/opt/mingw-w64/bin"
+
+export PREFIX="$HOME/opt/local"
+export CC=clang
+export CFLAGS='-march=native -O2'
+export LDFLAGS='-Wl,-O1,--sort-common,-z,relro'
+export CFLAGS="$CFLAGS -I'$HOME/opt/local/include'"
+export LDFLAGS="$LDFLAGS -L'$HOME/opt/local/lib'"
+export LD_LIBRARY_PATH= # -n isn't an option in zsh's export
+
+export EDITOR='vim -p'
+export GOPATH="$HOME/go"
+
+# colors
+for x in ls dir vdir grep fgrep egrep; do
+ alias $x="$x --color=auto"
+done
+alias make="colormake"
+
+# just flags
+export LESS='-SR'
+alias fils="du -bad1"
+alias lsfm="lsf -ugpms"
+alias lsa="ls -A --group-directories-first"
+alias logs="logs -o cat -b -e"
+alias logsf="logs -f"
+alias diff="git --no-pager diff --color=auto --no-ext-diff --no-index"
+
+# being specific
+alias erc="e ~/.zshrc ~/shrc.zsh ~/.bashrc"
+alias irc="screen -dR irc irssi"
+alias crawl='screen -dR crawl ssh crawl@crawl.develz.org -i ~/.ssh/crawl'
+alias crawla='screen -dR crawl ssh crawl@crawl.akrasiac.org -l joshua -i ~/.ssh/crawl'
+alias cmakem="cmake -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=~/mingw.cmake"
+
+# providing extra functionality
+# TODO: dotfiles first, like `LC_ALL=C ls -A` which doesnt work with -X flag
+alias ll="ls -ACX --group-directories-first --color=force | less"
+alias counts='find . | wc -l'
+alias exts='print -l *(:e:l) | sort | uniq -c | sort -n'
+alias meow='( cd ~/play/meow; ~/sh/meow.sh/run -pa )'
+alias nocom='grep -oP --line-buffered --color=never "^[^#]+"'
+alias unwrap='awk '"'"'BEGIN{RS="\n\n";FS="\n"}{for(i=1;i<=NF;i++)printf "%s ",$i;print "\n"}'"'"
+alias picky='{ pacman -Qgq base base-devel; pacman -Qtq; } | sort | uniq -u'
+alias unused='{ pacman -Qt; pacman -Qe | tee -; } | sort | uniq -u'
+
+. ~/sh/lsf.sh/lsf.sh
+. ~/sh/z/z.sh
diff --git a/ssh/crawl b/ssh/crawl
new file mode 100644
index 0000000..59af0f8
--- /dev/null
+++ b/ssh/crawl
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEoQIBAAKCAQEA2ztCchPiQL6kRFtk1Rqk/sk1ygnc0PbD6GP1CLOqu/+pD1Dg
+slIo+TXXxJmX76ChKtk2RanvoSjQQM+igD5cctTXZhWvQrvpOxEucVN9WaE/tl4y
+8SYYQjov3X3Kr06AASkscSP9mcJp10lxGN+EyFASg7RyCaXOioDAFHZnLy6nkHKl
+NnWfY1ZEB0V2ujG19v9VVoGNJCmrut8lvThjewo7YG2utX6sqz5GaiUBrjvhWGV0
+er882ykekCrclMAKxjQcP1+1GZOoSgTuiK8kTtPj5mVQoshqas+R6xbp78p4Os9R
+B6cWvtp8AdkIJ1b8tGkPtasfRDUdcJ/v1CmZiQIBIwKCAQBwv2QAJ3usRMmCPaGS
+KvXE3IIQIlRONcPWmc55gPi4dNqaKZghMZFqOPKfn3K1wFLi1hvpUBTWigSznfvM
+7N8WfBcBTPsMYKPVPAlBmKbdo2KYTbPMef3Y6rmH2kr7Em23dEK91/7EGtdYxq8x
+XQJ1pYXdVXx5/YAp+RJTqpt3WN6rq377Zjv1wWKb9vzaSlRD6USf7tSx0cvY4RW5
+NXVHKBZmtqsWb54QO0cHUxjJZ4CGdYc7D99CX/vYRjeJirrwzB4SDbzZGAb2W8hp
+xOVxIlrKAScPFhLjKvFfbnuk9uB5h/tdC22hnCkvM5KiPwo7EGRKmseBWPcRuH9u
+pZQjAoGBAPYUr9rm9atYChfCOodtIrOkWVFhbq0Hd44G4SuVdFaTrSR2JaaMnUhJ
+Iemmt2dnesshFkzq03OA5M4OBtuOrY/1PenXbnx13D8llSPsBRTUeFENSzvqSfL9
+O6O+Hrl8R7c3OE+KeNiR/BjnXyt9I2Xal8B9s8X2ywMRV47vabHbAoGBAOQRg4xK
+OSofN7OkAAOkmuyyJ4y+F9DC74McgTN4hsVOyAfNOi1EXbEJqRnDaHhNW2Nqv/Xy
+aV5ZNFiWfwbP9oEZMGm2nZ7Es1uavVMkVd+QJv7CF9b+txnQTqcP2kAIFH5QKwqB
+Jj5WLr2weSMZY62f3BpuA0cnPR2D79ri77lrAoGBAKG10qXK+TYVSHYDSwiJi9Ui
+25vg8PVcraZ5jKecuipDyYz9Lq9GdfxNUMy+A353M2+KxYMAttbfrEzkpWu1h/+D
+5tt+8NVyBcMYsnaxCqdJy2h2c0ShRom8WmRJvGtDCo5XfMaOMifq534UYxyUD/J5
+tC4JdiMBQ5RNOYnQh0j9AoGAe87+RNfV46qL884OouRUGheR0A9sA50FrZMhkPhJ
+KUgGMB7zsixtYBsv6WoUJAy8lQ4Qb5I5Mze9VKl4KEUCKNMo6O4bDQux0qR1Z6YC
+uzD/OdcUQYL1ru1shpOTvFwoYdO/l/z3gOz0zV/Mu0hMDcvPQYwtqkiAQzj+jMRW
+QBUCgYBofwHY0pcG8XLp4hoKXf8yA6LQxJ9z+mofRIHOVMpOwPBmTOqwDrr15ovd
+eOo8P8O22rZYrNpOSV800L9fH6LmDHYZp8ChdK3fHuqcyVGplctXEZ3XMIQhcv4p
+cPeYhJwUMebhn5QFk8hlhdNQDYZSomXFjonWBpJsrYxcrmfO9Q==
+-----END RSA PRIVATE KEY-----
diff --git a/ssh/known_hosts b/ssh/known_hosts
new file mode 100644
index 0000000..0da8c3a
--- /dev/null
+++ b/ssh/known_hosts
@@ -0,0 +1,6 @@
+github.com,207.97.227.239 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
+crawl.develz.org,46.4.68.88 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqv7Ooz6L/NOLV8VF4fl0KzBZ+9InTEKap05GcLXPqTzfC4toFH8TvBPkjNPZB+E0IAFB6pHnYjXdT4Ja4Mh5WBDHZSLy8g2lysLJeCs48YfOuwGI5E3t4S+dxT2JZIi1JyekXJU4tm7gNsqTSLYnMikigptaklCTBM+rWNE2am4lFY5FAu0UVBfQL7PkK11Uvd84ckMDzrUVTiSx9u4VHTju7+5Gji4y3ldk2/w9AleFX2SPvef4CkTKcHy80aCtEzGH85d/0O52Qyf6qDvkeD5tY2QhitFPZoSt12yAi7X5xZZTJZC/izn/wtSrDeajYHcr6rGunBaujxG94pO0Gw==
+192.168.2.185 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE1EqYb6dE+7BY7os3DvBRxMthGr0pQjwOMNDZWPs76CseGFyLyeOkb7tphNwPbUCOxP+baaU39loDfaQRSDXMk=
+crawl.akrasiac.org,204.140.17.55 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLsNcOQNRhGyjh3lRgl/ewlIWotrEirp9IiplbqgsCzz7kQ5EuATAvptohsC4/j1wt6q8U1LCyYK3kLuoNDcPvA=
+localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE1EqYb6dE+7BY7os3DvBRxMthGr0pQjwOMNDZWPs76CseGFyLyeOkb7tphNwPbUCOxP+baaU39loDfaQRSDXMk=
+204.232.175.90 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
diff --git a/vim/after/syntax/c.vim b/vim/after/syntax/c.vim
new file mode 100644
index 0000000..c6a748a
--- /dev/null
+++ b/vim/after/syntax/c.vim
@@ -0,0 +1,2 @@
+syn keyword cType uchar ushort uint ulong
+
diff --git a/vim/colors/Tomorrow-Night.vim b/vim/colors/Tomorrow-Night.vim
new file mode 100644
index 0000000..3e9e5bf
--- /dev/null
+++ b/vim/colors/Tomorrow-Night.vim
@@ -0,0 +1,362 @@
+" Tomorrow Night - Full Colour and 256 Colour
+" http://chriskempson.com
+"
+" Hex colour conversion functions borrowed from the theme "Desert256""
+
+" Default GUI Colours
+let s:foreground = "c5c8c6"
+let s:background = "1d1f21"
+let s:selection = "373b41"
+let s:line = "282a2e"
+let s:comment = "969896"
+let s:red = "cc6666"
+let s:orange = "de935f"
+let s:yellow = "f0c674"
+let s:green = "b5bd68"
+let s:aqua = "8abeb7"
+let s:blue = "81a2be"
+let s:purple = "b294bb"
+let s:window = "4d5057"
+
+" Console 256 Colours
+if !has("gui_running")
+ let s:background = "303030"
+ let s:window = "5e5e5e"
+ let s:line = "3a3a3a"
+ let s:selection = "585858"
+end
+
+set background=dark
+hi clear
+syntax reset
+
+let g:colors_name = "Tomorrow-Night"
+
+if has("gui_running") || &t_Co == 88 || &t_Co == 256
+ " Returns an approximate grey index for the given grey level
+ fun grey_number(x)
+ if &t_Co == 88
+ if a:x < 23
+ return 0
+ elseif a:x < 69
+ return 1
+ elseif a:x < 103
+ return 2
+ elseif a:x < 127
+ return 3
+ elseif a:x < 150
+ return 4
+ elseif a:x < 173
+ return 5
+ elseif a:x < 196
+ return 6
+ elseif a:x < 219
+ return 7
+ elseif a:x < 243
+ return 8
+ else
+ return 9
+ endif
+ else
+ if a:x < 14
+ return 0
+ else
+ let l:n = (a:x - 8) / 10
+ let l:m = (a:x - 8) % 10
+ if l:m < 5
+ return l:n
+ else
+ return l:n + 1
+ endif
+ endif
+ endif
+ endfun
+
+ " Returns the actual grey level represented by the grey index
+ fun grey_level(n)
+ if &t_Co == 88
+ if a:n == 0
+ return 0
+ elseif a:n == 1
+ return 46
+ elseif a:n == 2
+ return 92
+ elseif a:n == 3
+ return 115
+ elseif a:n == 4
+ return 139
+ elseif a:n == 5
+ return 162
+ elseif a:n == 6
+ return 185
+ elseif a:n == 7
+ return 208
+ elseif a:n == 8
+ return 231
+ else
+ return 255
+ endif
+ else
+ if a:n == 0
+ return 0
+ else
+ return 8 + (a:n * 10)
+ endif
+ endif
+ endfun
+
+ " Returns the palette index for the given grey index
+ fun grey_colour(n)
+ if &t_Co == 88
+ if a:n == 0
+ return 16
+ elseif a:n == 9
+ return 79
+ else
+ return 79 + a:n
+ endif
+ else
+ if a:n == 0
+ return 16
+ elseif a:n == 25
+ return 231
+ else
+ return 231 + a:n
+ endif
+ endif
+ endfun
+
+ " Returns an approximate colour index for the given colour level
+ fun rgb_number(x)
+ if &t_Co == 88
+ if a:x < 69
+ return 0
+ elseif a:x < 172
+ return 1
+ elseif a:x < 230
+ return 2
+ else
+ return 3
+ endif
+ else
+ if a:x < 75
+ return 0
+ else
+ let l:n = (a:x - 55) / 40
+ let l:m = (a:x - 55) % 40
+ if l:m < 20
+ return l:n
+ else
+ return l:n + 1
+ endif
+ endif
+ endif
+ endfun
+
+ " Returns the actual colour level for the given colour index
+ fun rgb_level(n)
+ if &t_Co == 88
+ if a:n == 0
+ return 0
+ elseif a:n == 1
+ return 139
+ elseif a:n == 2
+ return 205
+ else
+ return 255
+ endif
+ else
+ if a:n == 0
+ return 0
+ else
+ return 55 + (a:n * 40)
+ endif
+ endif
+ endfun
+
+ " Returns the palette index for the given R/G/B colour indices
+ fun rgb_colour(x, y, z)
+ if &t_Co == 88
+ return 16 + (a:x * 16) + (a:y * 4) + a:z
+ else
+ return 16 + (a:x * 36) + (a:y * 6) + a:z
+ endif
+ endfun
+
+ " Returns the palette index to approximate the given R/G/B colour levels
+ fun colour(r, g, b)
+ " Get the closest grey
+ let l:gx = grey_number(a:r)
+ let l:gy = grey_number(a:g)
+ let l:gz = grey_number(a:b)
+
+ " Get the closest colour
+ let l:x = rgb_number(a:r)
+ let l:y = rgb_number(a:g)
+ let l:z = rgb_number(a:b)
+
+ if l:gx == l:gy && l:gy == l:gz
+ " There are two possibilities
+ let l:dgr = grey_level(l:gx) - a:r
+ let l:dgg = grey_level(l:gy) - a:g
+ let l:dgb = grey_level(l:gz) - a:b
+ let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
+ let l:dr = rgb_level(l:gx) - a:r
+ let l:dg = rgb_level(l:gy) - a:g
+ let l:db = rgb_level(l:gz) - a:b
+ let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
+ if l:dgrey < l:drgb
+ " Use the grey
+ return grey_colour(l:gx)
+ else
+ " Use the colour
+ return rgb_colour(l:x, l:y, l:z)
+ endif
+ else
+ " Only one possibility
+ return rgb_colour(l:x, l:y, l:z)
+ endif
+ endfun
+
+ " Returns the palette index to approximate the 'rrggbb' hex string
+ fun rgb(rgb)
+ let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
+ let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
+ let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
+
+ return colour(l:r, l:g, l:b)
+ endfun
+
+ " Sets the highlighting for the given group
+ fun X(group, fg, bg, attr)
+ if a:fg != ""
+ exec "hi " . a:group . " guifg=#" . a:fg . " ctermfg=" . rgb(a:fg)
+ endif
+ if a:bg != ""
+ exec "hi " . a:group . " guibg=#" . a:bg . " ctermbg=" . rgb(a:bg)
+ endif
+ if a:attr != ""
+ exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr
+ endif
+ endfun
+
+ " Vim Highlighting
+ call X("Normal", s:foreground, s:background, "")
+ call X("LineNr", s:selection, "", "")
+ call X("NonText", s:selection, "", "")
+ call X("SpecialKey", s:selection, "", "")
+ call X("Search", s:background, s:yellow, "")
+ call X("TabLine", s:foreground, s:background, "reverse")
+ call X("StatusLine", s:window, s:yellow, "reverse")
+ call X("StatusLineNC", s:window, s:foreground, "reverse")
+ call X("VertSplit", s:window, s:window, "none")
+ call X("Visual", "", s:selection, "")
+ call X("Directory", s:blue, "", "")
+ call X("ModeMsg", s:green, "", "")
+ call X("MoreMsg", s:green, "", "")
+ call X("Question", s:green, "", "")
+ call X("WarningMsg", s:red, "", "")
+ call X("MatchParen", "", s:selection, "")
+ call X("Folded", s:comment, s:background, "")
+ call X("FoldColumn", "", s:background, "")
+ if version >= 700
+ call X("CursorLine", "", s:line, "none")
+ call X("CursorColumn", "", s:line, "none")
+ call X("PMenu", s:foreground, s:selection, "none")
+ call X("PMenuSel", s:foreground, s:selection, "reverse")
+ call X("SignColumn", "", s:background, "none")
+ end
+ if version >= 703
+ call X("ColorColumn", "", s:line, "none")
+ end
+
+ " Standard Highlighting
+ call X("Comment", s:comment, "", "")
+ call X("Todo", s:comment, s:background, "")
+ call X("Title", s:comment, "", "")
+ call X("Identifier", s:red, "", "none")
+ call X("Statement", s:foreground, "", "")
+ call X("Conditional", s:foreground, "", "")
+ call X("Repeat", s:foreground, "", "")
+ call X("Structure", s:purple, "", "")
+ call X("Function", s:blue, "", "")
+ call X("Constant", s:orange, "", "")
+ call X("String", s:green, "", "")
+ call X("Special", s:foreground, "", "")
+ call X("PreProc", s:purple, "", "")
+ call X("Operator", s:aqua, "", "none")
+ call X("Type", s:blue, "", "none")
+ call X("Define", s:purple, "", "none")
+ call X("Include", s:blue, "", "")
+ "call X("Ignore", "666666", "", "")
+
+ " Vim Highlighting
+ call X("vimCommand", s:red, "", "none")
+
+ " C Highlighting
+ call X("cType", s:yellow, "", "")
+ call X("cStorageClass", s:purple, "", "")
+ call X("cConditional", s:purple, "", "")
+ call X("cRepeat", s:purple, "", "")
+
+ " PHP Highlighting
+ call X("phpVarSelector", s:red, "", "")
+ call X("phpKeyword", s:purple, "", "")
+ call X("phpRepeat", s:purple, "", "")
+ call X("phpConditional", s:purple, "", "")
+ call X("phpStatement", s:purple, "", "")
+ call X("phpMemberSelector", s:foreground, "", "")
+
+ " Ruby Highlighting
+ call X("rubySymbol", s:green, "", "")
+ call X("rubyConstant", s:yellow, "", "")
+ call X("rubyAttribute", s:blue, "", "")
+ call X("rubyInclude", s:blue, "", "")
+ call X("rubyLocalVariableOrMethod", s:orange, "", "")
+ call X("rubyCurlyBlock", s:orange, "", "")
+ call X("rubyStringDelimiter", s:green, "", "")
+ call X("rubyInterpolationDelimiter", s:orange, "", "")
+ call X("rubyConditional", s:purple, "", "")
+ call X("rubyRepeat", s:purple, "", "")
+
+ " Python Highlighting
+ call X("pythonInclude", s:purple, "", "")
+ call X("pythonStatement", s:purple, "", "")
+ call X("pythonConditional", s:purple, "", "")
+ call X("pythonFunction", s:blue, "", "")
+
+ " JavaScript Highlighting
+ call X("javaScriptBraces", s:foreground, "", "")
+ call X("javaScriptFunction", s:purple, "", "")
+ call X("javaScriptConditional", s:purple, "", "")
+ call X("javaScriptRepeat", s:purple, "", "")
+ call X("javaScriptNumber", s:orange, "", "")
+ call X("javaScriptMember", s:orange, "", "")
+
+ " HTML Highlighting
+ call X("htmlTag", s:red, "", "")
+ call X("htmlTagName", s:red, "", "")
+ call X("htmlArg", s:red, "", "")
+ call X("htmlScriptTag", s:red, "", "")
+
+ " Diff Highlighting
+ call X("diffAdded", s:green, "", "")
+ call X("diffRemoved", s:red, "", "")
+
+ " ShowMarks Highlighting
+ call X("ShowMarksHLl", s:orange, s:background, "none")
+ call X("ShowMarksHLo", s:purple, s:background, "none")
+ call X("ShowMarksHLu", s:yellow, s:background, "none")
+ call X("ShowMarksHLm", s:aqua, s:background, "none")
+
+ " Delete Functions
+ delf X
+ delf rgb
+ delf colour
+ delf rgb_colour
+ delf rgb_level
+ delf rgb_number
+ delf grey_colour
+ delf grey_level
+ delf grey_number
+endif
diff --git a/vim/colors/candycode.vim b/vim/colors/candycode.vim
new file mode 100644
index 0000000..3800d9d
--- /dev/null
+++ b/vim/colors/candycode.vim
@@ -0,0 +1,174 @@
+" Vim color file -- candycode
+" Maintainer: Justin Constantino
+" Last Change: 2006 Aug 12
+
+set background=dark
+highlight clear
+let g:colors_name="candycode"
+
+let save_cpo = &cpo
+set cpo&vim
+
+" basic highlight groups (:help highlight-groups) {{{
+
+" text {{{
+
+hi Normal guifg=#ffffff guibg=#050505 gui=NONE
+ \ ctermfg=white ctermbg=black cterm=NONE
+
+hi Folded guifg=#c2bfa5 guibg=#050505 gui=underline
+ \ ctermfg=lightgray ctermbg=black cterm=underline
+
+hi LineNr guifg=#928c75 guibg=NONE gui=NONE
+ \ ctermfg=darkgray ctermbg=NONE cterm=NONE
+
+hi Directory guifg=#00bbdd guibg=NONE gui=NONE
+ \ ctermfg=cyan ctermbg=NONE cterm=NONE
+hi NonText guifg=#77ff22 guibg=NONE gui=bold
+ \ ctermfg=yellow ctermbg=NONE cterm=NONE
+hi SpecialKey guifg=#559933 guibg=NONE gui=NONE
+ \ ctermfg=green ctermbg=NONE cterm=NONE
+
+hi SpellBad guifg=NONE guibg=NONE gui=undercurl
+ \ ctermfg=white ctermbg=darkred guisp=#ff0011
+hi SpellCap guifg=NONE guibg=NONE gui=undercurl
+ \ ctermfg=white ctermbg=darkblue guisp=#0044ff
+hi SpellLocal guifg=NONE guibg=NONE gui=undercurl
+ \ ctermfg=black ctermbg=cyan guisp=#00dd99
+hi SpellRare guifg=NONE guibg=NONE gui=undercurl
+ \ ctermfg=white ctermbg=darkmagenta guisp=#ff22ee
+
+hi DiffAdd guifg=#ffffff guibg=#126493 gui=NONE
+ \ ctermfg=white ctermbg=darkblue cterm=NONE
+hi DiffChange guifg=#000000 guibg=#976398 gui=NONE
+ \ ctermfg=black ctermbg=darkmagenta cterm=NONE
+hi DiffDelete guifg=#000000 guibg=#be1923 gui=bold
+ \ ctermfg=black ctermbg=red cterm=bold
+hi DiffText guifg=#ffffff guibg=#976398 gui=bold
+ \ ctermfg=white ctermbg=green cterm=bold
+
+" }}}
+" borders / separators / menus {{{
+
+hi FoldColumn guifg=#c8bcb9 guibg=#786d65 gui=bold
+ \ ctermfg=lightgray ctermbg=darkgray cterm=NONE
+hi SignColumn guifg=#c8bcb9 guibg=#786d65 gui=bold
+ \ ctermfg=lightgray ctermbg=darkgray cterm=NONE
+
+hi Pmenu guifg=#000000 guibg=#a6a190 gui=NONE
+ \ ctermfg=white ctermbg=darkgray cterm=NONE
+hi PmenuSel guifg=#ffffff guibg=#133293 gui=NONE
+ \ ctermfg=white ctermbg=lightblue cterm=NONE
+hi PmenuSbar guifg=NONE guibg=#555555 gui=NONE
+ \ ctermfg=black ctermbg=black cterm=NONE
+hi PmenuThumb guifg=NONE guibg=#cccccc gui=NONE
+ \ ctermfg=gray ctermbg=gray cterm=NONE
+
+hi StatusLine guifg=#000000 guibg=#c2bfa5 gui=bold
+ \ ctermfg=black ctermbg=white cterm=bold
+hi StatusLineNC guifg=#444444 guibg=#c2bfa5 gui=NONE
+ \ ctermfg=darkgray ctermbg=white cterm=NONE
+hi WildMenu guifg=#ffffff guibg=#133293 gui=bold
+ \ ctermfg=white ctermbg=darkblue cterm=bold
+hi VertSplit guifg=#c2bfa5 guibg=#c2bfa5 gui=NONE
+ \ ctermfg=white ctermbg=white cterm=NONE
+
+hi TabLine guifg=#000000 guibg=#c2bfa5 gui=NONE
+ \ ctermfg=black ctermbg=white cterm=NONE
+hi TabLineFill guifg=#000000 guibg=#c2bfa5 gui=NONE
+ \ ctermfg=black ctermbg=white cterm=NONE
+hi TabLineSel guifg=#ffffff guibg=#133293 gui=NONE
+ \ ctermfg=white ctermbg=black cterm=NONE
+
+"hi Menu
+"hi Scrollbar
+"hi Tooltip
+
+" }}}
+" cursor / dynamic / other {{{
+
+hi Cursor guifg=#000000 guibg=#ffff99 gui=NONE
+ \ ctermfg=black ctermbg=white cterm=NONE
+hi CursorIM guifg=#000000 guibg=#aaccff gui=NONE
+ \ ctermfg=black ctermbg=white cterm=reverse
+hi CursorLine guifg=NONE guibg=#1b1b1b gui=NONE
+ \ ctermfg=NONE ctermbg=NONE cterm=NONE
+hi CursorColumn guifg=NONE guibg=#1b1b1b gui=NONE
+ \ ctermfg=NONE ctermbg=NONE cterm=NONE
+
+hi Visual guifg=#ffffff guibg=#606070 gui=NONE
+ \ ctermfg=white ctermbg=lightblue cterm=NONE
+
+hi IncSearch guifg=#000000 guibg=#eedd33 gui=bold
+ \ ctermfg=white ctermbg=yellow cterm=NONE
+hi Search guifg=#efefd0 guibg=#937340 gui=NONE
+ \ ctermfg=white ctermbg=darkgreen cterm=NONE
+
+hi MatchParen guifg=NONE guibg=#3377aa gui=NONE
+ \ ctermfg=white ctermbg=blue cterm=NONE
+
+"hi VisualNOS
+
+" }}}
+" listings / messages {{{
+
+hi ModeMsg guifg=#eecc18 guibg=NONE gui=NONE
+ \ ctermfg=yellow ctermbg=NONE cterm=NONE
+hi Title guifg=#dd4452 guibg=NONE gui=bold
+ \ ctermfg=red ctermbg=NONE cterm=bold
+hi Question guifg=#66d077 guibg=NONE gui=NONE
+ \ ctermfg=green ctermbg=NONE cterm=NONE
+hi MoreMsg guifg=#39d049 guibg=NONE gui=NONE
+ \ ctermfg=green ctermbg=NONE cterm=NONE
+
+hi ErrorMsg guifg=#ffffff guibg=#ff0000 gui=bold
+ \ ctermfg=white ctermbg=red cterm=bold
+hi WarningMsg guifg=#ccae22 guibg=NONE gui=bold
+ \ ctermfg=yellow ctermbg=NONE cterm=bold
+
+" }}}
+
+" }}}
+" syntax highlighting groups (:help group-name) {{{
+
+hi Comment guifg=#ff9922 guibg=NONE gui=NONE
+ \ ctermfg=brown ctermbg=NONE cterm=NONE
+
+hi Constant guifg=#ff6050 guibg=NONE gui=NONE
+ \ ctermfg=red ctermbg=NONE cterm=NONE
+hi Boolean guifg=#ff6050 guibg=NONE gui=bold
+ \ ctermfg=red ctermbg=NONE cterm=bold
+
+hi Identifier guifg=#eecc44 guibg=NONE gui=NONE
+ \ ctermfg=yellow ctermbg=NONE cterm=NONE
+
+hi Statement guifg=#66d077 guibg=NONE gui=bold
+ \ ctermfg=green ctermbg=NONE cterm=bold
+
+hi PreProc guifg=#bb88dd guibg=NONE gui=NONE
+ \ ctermfg=darkmagenta ctermbg=NONE cterm=NONE
+
+hi Type guifg=#4093cc guibg=NONE gui=bold
+ \ ctermfg=lightblue ctermbg=NONE cterm=bold
+
+hi Special guifg=#9999aa guibg=NONE gui=bold
+ \ ctermfg=lightgray ctermbg=NONE cterm=bold
+
+hi Underlined guifg=#80a0ff guibg=NONE gui=underline
+ \ ctermfg=NONE ctermbg=NONE cterm=underline
+ \ term=underline
+
+hi Ignore guifg=#888888 guibg=NONE gui=NONE
+ \ ctermfg=darkgray ctermbg=NONE cterm=NONE
+
+hi Error guifg=#ffffff guibg=#ff0000 gui=NONE
+ \ ctermfg=white ctermbg=red cterm=NONE
+
+hi Todo guifg=#ffffff guibg=#ee7700 gui=bold
+ \ ctermfg=black ctermbg=yellow cterm=bold
+
+" }}}
+
+let &cpo = save_cpo
+
+" vim: fdm=marker fdl=0
diff --git a/vim/colors/proper.vim b/vim/colors/proper.vim
new file mode 100644
index 0000000..366d370
--- /dev/null
+++ b/vim/colors/proper.vim
@@ -0,0 +1,121 @@
+" Vim color file -- TODO
+" Maintainer: TODO
+" Last Change: 2012-05-15
+
+set background=dark
+highlight clear
+let g:colors_name="candycode"
+
+let save_cpo = &cpo
+set cpo&vim
+
+" basic highlight groups (:help highlight-groups) {{{
+
+" text {{{
+
+hi Normal ctermfg=7 ctermbg=0 cterm=NONE
+
+hi Folded ctermfg=8 ctermbg=0 cterm=NONE
+
+hi LineNr ctermfg=8 ctermbg=0 cterm=NONE
+
+hi Directory ctermfg=14 ctermbg=NONE cterm=NONE
+hi NonText ctermfg=11 ctermbg=NONE cterm=NONE
+hi SpecialKey ctermfg=10 ctermbg=NONE cterm=NONE
+
+hi SpellBad ctermfg=15 ctermbg=1
+hi SpellCap ctermfg=15 ctermbg=4
+hi SpellLocal ctermfg=0 ctermbg=14
+hi SpellRare ctermfg=15 ctermbg=5
+
+hi DiffAdd ctermfg=15 ctermbg=4 cterm=NONE
+hi DiffChange ctermfg=0 ctermbg=5 cterm=NONE
+hi DiffDelete ctermfg=0 ctermbg=9 cterm=NONE
+hi DiffText ctermfg=15 ctermbg=10 cterm=NONE
+
+" }}}
+" borders / separators / menus {{{
+
+hi FoldColumn ctermfg=7 ctermbg=8 cterm=NONE
+hi SignColumn ctermfg=7 ctermbg=8 cterm=NONE
+hi ColorColumn ctermfg=NONE ctermbg=8
+
+hi Pmenu ctermfg=15 ctermbg=8 cterm=NONE
+hi PmenuSel ctermfg=15 ctermbg=12 cterm=NONE
+hi PmenuSbar ctermfg=0 ctermbg=0 cterm=NONE
+hi PmenuThumb ctermfg=7 ctermbg=7 cterm=NONE
+
+hi StatusLine ctermfg=0 ctermbg=15 cterm=NONE
+hi StatusLineNC ctermfg=8 ctermbg=15 cterm=NONE
+hi WildMenu ctermfg=15 ctermbg=4 cterm=NONE
+hi VertSplit ctermfg=15 ctermbg=15 cterm=NONE
+
+hi TabLine ctermfg=0 ctermbg=15 cterm=NONE
+hi TabLineFill ctermfg=0 ctermbg=15 cterm=NONE
+hi TabLineSel ctermfg=15 ctermbg=0 cterm=NONE
+
+"hi Menu
+"hi Scrollbar
+"hi Tooltip
+
+" }}}
+" cursor / dynamic / other {{{
+
+hi Cursor ctermfg=0 ctermbg=15 cterm=NONE
+hi CursorIM ctermfg=0 ctermbg=15 cterm=reverse
+hi CursorLine ctermfg=NONE ctermbg=NONE cterm=NONE
+hi CursorColumn ctermfg=NONE ctermbg=NONE cterm=NONE
+
+hi Visual ctermfg=15 ctermbg=12 cterm=NONE
+
+hi IncSearch ctermfg=15 ctermbg=3 cterm=NONE
+hi Search ctermfg=15 ctermbg=2 cterm=NONE
+
+hi MatchParen ctermfg=15 ctermbg=6 cterm=NONE
+
+"hi VisualNOS
+
+" }}}
+" listings / messages {{{
+
+hi ModeMsg ctermfg=11 ctermbg=NONE cterm=NONE
+hi Title ctermfg=9 ctermbg=NONE cterm=NONE
+hi Question ctermfg=10 ctermbg=NONE cterm=NONE
+hi MoreMsg ctermfg=10 ctermbg=NONE cterm=NONE
+
+hi ErrorMsg ctermfg=15 ctermbg=9 cterm=NONE
+hi WarningMsg ctermfg=11 ctermbg=NONE cterm=NONE
+
+" }}}
+
+" }}}
+" syntax highlighting groups (:help group-name) {{{
+
+hi Comment ctermfg=3 ctermbg=NONE cterm=NONE
+
+hi Constant ctermfg=9 ctermbg=NONE cterm=NONE
+hi Boolean ctermfg=9 ctermbg=NONE cterm=NONE
+
+hi Identifier ctermfg=11 ctermbg=NONE cterm=NONE
+
+hi Statement ctermfg=10 ctermbg=NONE cterm=NONE
+
+hi PreProc ctermfg=5 ctermbg=NONE cterm=NONE
+
+hi Type ctermfg=12 ctermbg=NONE cterm=NONE
+
+hi Special ctermfg=7 ctermbg=NONE cterm=NONE
+
+hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
+
+hi Ignore ctermfg=8 ctermbg=NONE cterm=NONE
+
+hi Error ctermfg=15 ctermbg=9 cterm=NONE
+
+hi Todo ctermfg=0 ctermbg=11 cterm=NONE
+
+" }}}
+
+let &cpo = save_cpo
+
+" vim: fdm=marker fdl=0
diff --git a/vim/colors/tomorrow.vim b/vim/colors/tomorrow.vim
new file mode 100644
index 0000000..a78a089
--- /dev/null
+++ b/vim/colors/tomorrow.vim
@@ -0,0 +1,117 @@
+" terminal color assuming tomorrow night are the 16 colors
+set background=dark
+hi clear
+syntax reset
+
+let g:colors_name = "tomorrow"
+
+"%s/call X("\(\w\+\)", \([^,]*\), \([^,]*\), \([^)]*\))/hi \1 ctermfg=\2 ctermbg=\3 cterm=\4/g
+
+" Vim Highlighting
+hi Normal ctermfg=7 ctermbg=0
+hi LineNr ctermfg=238
+hi NonText ctermfg=8
+hi SpecialKey ctermfg=8
+hi Search ctermfg=0 ctermbg=11
+hi TabLine ctermfg=7 ctermbg=0 cterm=reverse
+hi StatusLine ctermfg=239 ctermbg=11 cterm=reverse
+hi StatusLineNC ctermfg=239 ctermbg=7 cterm=reverse
+hi VertSplit ctermfg=239 ctermbg=239 cterm=none
+hi Visual ctermbg=8
+hi Directory ctermfg=4
+hi ModeMsg ctermfg=2
+hi MoreMsg ctermfg=2
+hi Question ctermfg=2
+hi WarningMsg ctermfg=1
+hi MatchParen ctermbg=8
+hi Folded ctermfg=245 ctermbg=0
+hi FoldColumn ctermbg=0
+if version >= 700
+ hi CursorLine ctermbg=239 cterm=none
+ hi CursorColumn ctermbg=239 cterm=none
+ hi PMenu ctermfg=7 ctermbg=8 cterm=none
+ hi PMenuSel ctermfg=7 ctermbg=8 cterm=reverse
+ hi SignColumn ctermbg=0 cterm=none
+end
+if version >= 703
+ hi ColorColumn ctermbg=233 cterm=none
+end
+
+" Standard Highlighting
+hi Comment ctermfg=245
+hi Todo ctermfg=245 ctermbg=0
+hi Title ctermfg=245
+hi Identifier ctermfg=1 cterm=none
+hi Statement ctermfg=7
+hi Conditional ctermfg=7
+hi Repeat ctermfg=7
+hi Structure ctermfg=5
+hi Function ctermfg=4
+hi Constant ctermfg=3
+hi String ctermfg=2
+hi Special ctermfg=7
+hi PreProc ctermfg=5
+hi Operator ctermfg=6 cterm=none
+hi Type ctermfg=4 cterm=none
+hi Define ctermfg=5 cterm=none
+hi Include ctermfg=4
+"hi Ignore ctermfg="666666"
+
+" Vim Highlighting
+hi vimCommand ctermfg=1 cterm=none
+
+" C Highlighting
+hi cType ctermfg=11
+hi cStorageClass ctermfg=5
+hi cConditional ctermfg=5
+hi cRepeat ctermfg=5
+
+" PHP Highlighting
+hi phpVarSelector ctermfg=1
+hi phpKeyword ctermfg=5
+hi phpRepeat ctermfg=5
+hi phpConditional ctermfg=5
+hi phpStatement ctermfg=5
+hi phpMemberSelector ctermfg=7
+
+" Ruby Highlighting
+hi rubySymbol ctermfg=2
+hi rubyConstant ctermfg=11
+hi rubyAttribute ctermfg=4
+hi rubyInclude ctermfg=4
+hi rubyLocalVariableOrMethod ctermfg=3
+hi rubyCurlyBlock ctermfg=3
+hi rubyStringDelimiter ctermfg=2
+hi rubyInterpolationDelimiter ctermfg=3
+hi rubyConditional ctermfg=5
+hi rubyRepeat ctermfg=5
+
+" Python Highlighting
+hi pythonInclude ctermfg=5
+hi pythonStatement ctermfg=5
+hi pythonConditional ctermfg=5
+hi pythonFunction ctermfg=4
+
+" JavaScript Highlighting
+hi javaScriptBraces ctermfg=7
+hi javaScriptFunction ctermfg=5
+hi javaScriptConditional ctermfg=5
+hi javaScriptRepeat ctermfg=5
+hi javaScriptNumber ctermfg=3
+hi javaScriptMember ctermfg=3
+
+" HTML Highlighting
+hi htmlTag ctermfg=1
+hi htmlTagName ctermfg=1
+hi htmlArg ctermfg=1
+hi htmlScriptTag ctermfg=1
+
+" Diff Highlighting
+hi diffAdded ctermfg=2
+hi diffRemoved ctermfg=1
+
+" ShowMarks Highlighting
+hi ShowMarksHLl ctermfg=3 ctermbg=0 cterm=none
+hi ShowMarksHLo ctermfg=5 ctermbg=0 cterm=none
+hi ShowMarksHLu ctermfg=11 ctermbg=0 cterm=none
+hi ShowMarksHLm ctermfg=6 ctermbg=0 cterm=none
diff --git a/xinitrc b/xinitrc
new file mode 100644
index 0000000..82fe191
--- /dev/null
+++ b/xinitrc
@@ -0,0 +1,2 @@
+autocutsel -fork &
+autocutsel -selection PRIMARY -fork &
diff --git a/zshrc b/zshrc
new file mode 100644
index 0000000..cc92279
--- /dev/null
+++ b/zshrc
@@ -0,0 +1,103 @@
+setopt extended_glob
+
+fpath=(~/sh $fpath)
+
+function {
+ local f
+ for f in ~/sh/^([_.]*)(N^/:t); do
+ autoload -Uz $f
+ done
+
+ zsc() {
+ local s=$1; shift
+ zstyle ':completion:*'$s $@
+ }
+ zsc '*:default' list-colors ''
+ zsc '*' completer _complete _ignored _match _correct _approximate _prefix
+ zsc '*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3)))'
+ #zsc '*:corrections' format '%B%d (errors %e)%b'
+ zsc '*:default' list-prompt '%S%M matches%s'
+ zsc '*:default' menu select=0
+ zsc '*' ignore-parents parent pwd
+ zsc '*' ignored-patterns '*?.sw[po]' '*?.pyc' '__pycache__'
+ zsc '*:*:rm:*:*' ignored-patterns
+ # matching: try exact, case insensitive, then partial word completion.
+ # ** for recursive, i think
+ zsc '*' matcher-list 'm:{[:lower:]}={[:upper:]}' 'r:|[._-]=** r:|=**'
+ # caching, for huge lists eg. package managers
+ zsc '*' use-cache on
+ zsc '*' cache-path ~/.zsh/cache
+ zsc '*:pacman:*' force-list always
+ zsc '*:*:pacman:*' menu yes select
+ # when listing completions, show type names and group by them
+ zsc '*:descriptions' format "$fg_bold[black]» %d$reset_color"
+ zsc '*' group-name ''
+}
+
+autoload -Uz compinit
+compinit
+
+HISTFILE=~/.histfile
+HISTSIZE=10000
+SAVEHIST=10000
+
+function {
+ local -a opts
+ opts=( no_beep
+ append_history share_history # across sessions
+ hist_expire_dups_first # sharing/appending will result in dups
+ hist_ignore_dups # don't push lines identical to the previous
+ auto_cd # exec a dir to cd
+ auto_pushd pushd_ignore_dups # try `dirs -v` to find N and `is ~N`
+ no_match # error on bad tab-complete
+ check_jobs notify # automatic job reporting
+ chase_links # cd into link resolves link
+ complete_aliases # allow original command completion within alias
+ complete_in_word # enable tab completion when cursor between words
+ rc_quotes # 'you''re dumb' like "you're dumb"
+ )
+ setopt "${opts[@]}"
+ unsetopt rm_star_silent rm_star_wait # yolo
+}
+
+bindkey -e # emacs-style keybinds
+bindkey '^[[A' history-search-backward # up
+bindkey '^[[B' history-search-forward # down
+bindkey ';5D' emacs-backward-word # ctrl+left
+bindkey ';5C' emacs-forward-word # ctrl+right
+# we type a space (and delete it afterwards) to force ^Y to yank from ^U
+bindkey -s ';3A' ' ^Ucd ..^M^Y^H' # alt+up
+bindkey -s '^[s' '^Asudo ^E' # alt+s
+
+autoload edit-command-line
+zle -N edit-command-line # new widget of the same function name
+bindkey '^Xe' edit-command-line # ctrl+x -> e
+
+. ~/shrc.zsh
+
+alias -g STFU="2>/dev/null"
+
+for c in ack cd cp ebuild gcc gist grep ln man mkdir mv rm
+ alias $c="nocorrect $c"
+for c in arith fc find ftp history let locate rsync scp sftp wget
+ alias $c="noglob $c"
+
+if [[ "$TERM" = xterm* ]]; then
+ precmd() { print -Pn "\e]2;%M: %~\a" }
+fi
+
+# note: zsh adds a % symbol to newline-less output, so bash prompt is overkill
+PROMPT='%b%(?.%2K.%1K)%15F%#%f%k '
+RPROMPT='%8F%h%b'
+
+reload() {
+ # This doesn't seem to help with _vim_files errors, ehh
+ # you wanna rm .zcompdump then exit, that's why
+ cd ~
+ autoload -U zrecompile
+ [ -f .zshrc ] && zrecompile -p .zshrc
+ rm -f .zcompdump
+ [ -f .zshrc.zwc.old ] && rm -f .zshrc.zwc.old
+ [ -f .zcompdump.zwc.old ] && rm -f .zcompdump.zwc.old
+ exec zsh # reload zsh (ends script execution)
+}