Commits

David Wolever committed 37dd67f

More stuff

Comments (0)

Files changed (9)

+#
+#   bash_completion - programmable completion functions for bash 3.2+
+#
+#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
+#             © 2009-2011, Bash Completion Maintainers
+#                     <bash-completion-devel@lists.alioth.debian.org>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2, or (at your option)
+#   any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software Foundation,
+#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#   The latest version of this software can be obtained here:
+#
+#   http://bash-completion.alioth.debian.org/
+#
+#   RELEASE: 1.3
+
+if [[ $- == *v* ]]; then
+    BASH_COMPLETION_ORIGINAL_V_VALUE="-v"
+else
+    BASH_COMPLETION_ORIGINAL_V_VALUE="+v"
+fi
+
+if [[ -n $BASH_COMPLETION_DEBUG ]]; then
+    set -v
+else
+    set +v
+fi
+
+# Alter the following to reflect the location of this file.
+#
+[ -n "$BASH_COMPLETION" ] || BASH_COMPLETION=/usr/local/etc/bash_completion
+[ -n "$BASH_COMPLETION_DIR" ] || BASH_COMPLETION_DIR=/usr/local/etc/bash_completion.d
+[ -n "$BASH_COMPLETION_COMPAT_DIR" ] || BASH_COMPLETION_COMPAT_DIR=/usr/local/etc/bash_completion.d
+readonly BASH_COMPLETION BASH_COMPLETION_DIR BASH_COMPLETION_COMPAT_DIR
+
+# Set a couple of useful vars
+#
+UNAME=$( uname -s )
+# strip OS type and version under Cygwin (e.g. CYGWIN_NT-5.1 => Cygwin)
+UNAME=${UNAME/CYGWIN_*/Cygwin}
+
+case ${UNAME} in
+    Linux|GNU|GNU/*) USERLAND=GNU ;;
+    *) USERLAND=${UNAME} ;;
+esac
+
+# Turn on extended globbing and programmable completion
+shopt -s extglob progcomp
+
+# A lot of the following one-liners were taken directly from the
+# completion examples provided with the bash 2.04 source distribution
+
+# Make directory commands see only directories
+complete -d pushd
+
+# The following section lists completions that are redefined later
+# Do NOT break these over multiple lines.
+#
+# START exclude -- do NOT remove this line
+# bzcmp, bzdiff, bz*grep, bzless, bzmore intentionally not here, see Debian: #455510
+complete -f -X '!*.?(t)bz?(2)' bunzip2 bzcat pbunzip2 pbzcat
+complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk)' unzip zipinfo
+complete -f -X '*.Z' compress znew
+# zcmp, zdiff, z*grep, zless, zmore intentionally not here, see Debian: #455510
+complete -f -X '!*.@(Z|[gGd]z|t[ag]z)' gunzip zcat unpigz
+complete -f -X '!*.Z' uncompress
+# lzcmp, lzdiff intentionally not here, see Debian: #455510
+complete -f -X '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzma
+complete -f -X '!*.@(?(t)xz|tlz|lzma)' unxz xzcat
+complete -f -X '!*.lrz' lrunzip
+complete -f -X '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee
+complete -f -X '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm)' xv qiv
+complete -f -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview
+complete -f -X '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi
+complete -f -X '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx
+complete -f -X '!*.[pf]df' acroread gpdf xpdf
+complete -f -X '!*.@(?(e)ps|pdf)' kpdf
+complete -f -X '!*.@(@(?(e)ps|?(E)PS|[pf]df|[PF]DF|dvi|DVI)?(.gz|.GZ|.bz2|.BZ2)|cb[rz]|djv?(u)|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|fdf)' evince
+complete -f -X '!*.@(okular|@(?(e|x)ps|?(E|X)PS|pdf|PDF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb?(2)|FB?(2)|mobi|MOBI|g3|G3|chm|CHM|fdf|FDF)?(.?(gz|GZ|bz2|BZ2)))' okular
+complete -f -X '!*.@(?(e)ps|pdf)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr
+complete -f -X '!*.texi*' makeinfo texi2html
+complete -f -X '!*.@(?(la)tex|texi|dtx|ins|ltx)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi
+complete -f -X '!*.mp3' mpg123 mpg321 madplay
+complete -f -X '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))?(.part)' xine aaxine fbxine
+complete -f -X '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.part)' kaffeine dragon
+complete -f -X '!*.@(avi|asf|wmv)' aviplay
+complete -f -X '!*.@(rm?(j)|ra?(m)|smi?(l))' realplay
+complete -f -X '!*.@(mpg|mpeg|avi|mov|qt)' xanim
+complete -f -X '!*.@(ogg|m3u|flac|spx)' ogg123
+complete -f -X '!*.@(mp3|ogg|pls|m3u)' gqmpeg freeamp
+complete -f -X '!*.fig' xfig
+complete -f -X '!*.@(mid?(i)|cmf)' playmidi
+complete -f -X '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity
+complete -f -X '!*.@(m[eo]d|s[3t]m|xm|it)' modplugplay modplug123
+complete -f -X '*.@(o|so|so.!(conf)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
+complete -f -X '!*.@([eE][xX][eE]?(.[sS][oO])|[cC][oO][mM]|[sS][cC][rR])' wine
+complete -f -X '!*.@(zip|z|gz|tgz)' bzme
+# konqueror not here on purpose, it's more than a web/html browser
+complete -f -X '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx opera galeon dillo elinks amaya firefox mozilla-firefox iceweasel google-chrome chromium-browser epiphany
+complete -f -X '!*.@(sxw|stw|sxg|sgl|doc?([mx])|dot?([mx])|rtf|txt|htm|html|odt|ott|odm)' oowriter
+complete -f -X '!*.@(sxi|sti|pps?(x)|ppt?([mx])|pot?([mx])|odp|otp)' ooimpress
+complete -f -X '!*.@(sxc|stc|xls?([bmx])|xlw|xlt?([mx])|[ct]sv|ods|ots)' oocalc
+complete -f -X '!*.@(sxd|std|sda|sdd|odg|otg)' oodraw
+complete -f -X '!*.@(sxm|smf|mml|odf)' oomath
+complete -f -X '!*.odb' oobase
+complete -f -X '!*.[rs]pm' rpm2cpio
+complete -f -X '!*.aux' bibtex
+complete -f -X '!*.po' poedit gtranslator kbabel lokalize
+complete -f -X '!*.@([Pp][Rr][Gg]|[Cc][Ll][Pp])' harbour gharbour hbpp
+complete -f -X '!*.[Hh][Rr][Bb]' hbrun
+complete -f -X '!*.ly' lilypond ly2dvi
+complete -f -X '!*.@(dif?(f)|?(d)patch)?(.@([gx]z|bz2|lzma))' cdiff
+complete -f -X '!*.lyx' lyx
+complete -f -X '!@(*.@(ks|jks|jceks|p12|pfx|bks|ubr|gkr|cer|crt|cert|p7b|pkipath|pem|p10|csr|crl)|cacerts)' portecle
+complete -f -X '!*.@(mp[234c]|og[ag]|@(fl|a)ac|m4[abp]|spx|tta|w?(a)v|wma|aif?(f)|asf|ape)' kid3 kid3-qt
+# FINISH exclude -- do not remove this line
+
+# start of section containing compspecs that can be handled within bash
+
+# user commands see only users
+complete -u su write chfn groups slay w sux runuser
+
+# bg completes with stopped jobs
+complete -A stopped -P '"%' -S '"' bg
+
+# other job commands
+complete -j -P '"%' -S '"' fg jobs disown
+
+# readonly and unset complete with shell variables
+complete -v readonly unset
+
+# set completes with set options
+complete -A setopt set
+
+# shopt completes with shopt options
+complete -A shopt shopt
+
+# helptopics
+complete -A helptopic help
+
+# unalias completes with aliases
+complete -a unalias
+
+# bind completes with readline bindings (make this more intelligent)
+complete -A binding bind
+
+# type and which complete on commands
+complete -c command type which
+
+# builtin completes on builtins
+complete -b builtin
+
+# start of section containing completion functions called by other functions
+
+# This function checks whether we have a given program on the system.
+# No need for bulky functions in memory if we don't.
+#
+have()
+{
+    unset -v have
+    # Completions for system administrator commands are installed as well in
+    # case completion is attempted via `sudo command ...'.
+    PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&
+    have="yes"
+}
+
+# This function checks whether a given readline variable
+# is `on'.
+#
+_rl_enabled()
+{
+    [[ "$( bind -v )" = *$1+([[:space:]])on* ]]
+}
+
+# This function shell-quotes the argument
+quote()
+{
+    echo \'${1//\'/\'\\\'\'}\' #'# Help vim syntax highlighting
+}
+
+# @see _quote_readline_by_ref()
+quote_readline()
+{
+    local quoted
+    _quote_readline_by_ref "$1" ret
+    printf %s "$ret"
+} # quote_readline()
+
+
+# This function shell-dequotes the argument
+dequote()
+{
+    eval echo "$1" 2> /dev/null
+}
+
+
+# Assign variable one scope above the caller
+# Usage: local "$1" && _upvar $1 "value(s)"
+# Param: $1  Variable name to assign value to
+# Param: $*  Value(s) to assign.  If multiple values, an array is
+#            assigned, otherwise a single value is assigned.
+# NOTE: For assigning multiple variables, use '_upvars'.  Do NOT
+#       use multiple '_upvar' calls, since one '_upvar' call might
+#       reassign a variable to be used by another '_upvar' call.
+# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
+_upvar() {
+    if unset -v "$1"; then           # Unset & validate varname
+        if (( $# == 2 )); then
+            eval $1=\"\$2\"          # Return single value
+        else
+            eval $1=\(\"\${@:2}\"\)  # Return array
+        fi
+    fi
+}
+
+
+# Assign variables one scope above the caller
+# Usage: local varname [varname ...] && 
+#        _upvars [-v varname value] | [-aN varname [value ...]] ...
+# Available OPTIONS:
+#     -aN  Assign next N values to varname as array
+#     -v   Assign single value to varname
+# Return: 1 if error occurs
+# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
+_upvars() {
+    if ! (( $# )); then
+        echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\
+            "value] | [-aN varname [value ...]] ..." 1>&2
+        return 2
+    fi
+    while (( $# )); do
+        case $1 in
+            -a*)
+                # Error checking
+                [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
+                    "number specifier" 1>&2; return 1; }
+                printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
+                    "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
+                    return 1; }
+                # Assign array of -aN elements
+                [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) && 
+                shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
+                    "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }
+                ;;
+            -v)
+                # Assign single value
+                [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" &&
+                shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\
+                "argument(s)" 1>&2; return 1; }
+                ;;
+            *)
+                echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2
+                return 1 ;;
+        esac
+    done
+}
+
+
+# Reassemble command line words, excluding specified characters from the
+# list of word completion separators (COMP_WORDBREAKS).
+# @param $1 chars  Characters out of $COMP_WORDBREAKS which should
+#     NOT be considered word breaks. This is useful for things like scp where
+#     we want to return host:path and not only path, so we would pass the
+#     colon (:) as $1 here.
+# @param $2 words  Name of variable to return words to
+# @param $3 cword  Name of variable to return cword to
+#
+__reassemble_comp_words_by_ref() {
+    local exclude i j ref
+    # Exclude word separator characters?
+    if [[ $1 ]]; then
+        # Yes, exclude word separator characters;
+        # Exclude only those characters, which were really included
+        exclude="${1//[^$COMP_WORDBREAKS]}"
+    fi
+        
+    # Default to cword unchanged
+    eval $3=$COMP_CWORD
+    # Are characters excluded which were former included?
+    if [[ $exclude ]]; then
+        # Yes, list of word completion separators has shrunk;
+        # Re-assemble words to complete
+        for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
+            # Is current word not word 0 (the command itself) and is word not
+            # empty and is word made up of just word separator characters to be
+            # excluded?
+            while [[ $i -gt 0 && ${COMP_WORDS[$i]} && 
+                ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]} 
+            ]]; do
+                [ $j -ge 2 ] && ((j--))
+                # Append word separator to current word
+                ref="$2[$j]"
+                eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+                # Indicate new cword
+                [ $i = $COMP_CWORD ] && eval $3=$j
+                # Indicate next word if available, else end *both* while and for loop
+                (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
+            done
+            # Append word to current word
+            ref="$2[$j]"
+            eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+            # Indicate new cword
+            [[ $i == $COMP_CWORD ]] && eval $3=$j
+        done
+    else
+        # No, list of word completions separators hasn't changed;
+        eval $2=\( \"\${COMP_WORDS[@]}\" \)
+    fi
+} # __reassemble_comp_words_by_ref()
+
+
+# @param $1 exclude  Characters out of $COMP_WORDBREAKS which should NOT be
+#     considered word breaks. This is useful for things like scp where
+#     we want to return host:path and not only path, so we would pass the
+#     colon (:) as $1 in this case.  Bash-3 doesn't do word splitting, so this
+#     ensures we get the same word on both bash-3 and bash-4.
+# @param $2 words  Name of variable to return words to
+# @param $3 cword  Name of variable to return cword to
+# @param $4 cur  Name of variable to return current word to complete to
+# @see ___get_cword_at_cursor_by_ref()
+__get_cword_at_cursor_by_ref() {
+    local cword words=()
+    __reassemble_comp_words_by_ref "$1" words cword
+
+    local i cur2
+    local cur="$COMP_LINE"
+    local index="$COMP_POINT"
+    for (( i = 0; i <= cword; ++i )); do
+        while [[
+            # Current word fits in $cur?
+            "${#cur}" -ge ${#words[i]} &&
+            # $cur doesn't match cword?
+            "${cur:0:${#words[i]}}" != "${words[i]}"
+        ]]; do
+            # Strip first character
+            cur="${cur:1}"
+            # Decrease cursor position
+            ((index--))
+        done
+
+        # Does found word matches cword?
+        if [[ "$i" -lt "$cword" ]]; then
+            # No, cword lies further;
+            local old_size="${#cur}"
+            cur="${cur#${words[i]}}"
+            local new_size="${#cur}"
+            index=$(( index - old_size + new_size ))
+        fi
+    done
+
+    if [[ "${words[cword]:0:${#cur}}" != "$cur" ]]; then
+        # We messed up. At least return the whole word so things keep working
+        cur2=${words[cword]}
+    else
+        cur2=${cur:0:$index}
+    fi
+
+    local "$2" "$3" "$4" && 
+        _upvars -a${#words[@]} $2 "${words[@]}" -v $3 "$cword" -v $4 "$cur2"
+}
+
+
+# Get the word to complete and optional previous words.
+# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
+# where the user is completing in the middle of a word.
+# (For example, if the line is "ls foobar",
+# and the cursor is here -------->   ^
+# Also one is able to cross over possible wordbreak characters.
+# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
+# Available VARNAMES:
+#     cur         Return cur via $cur
+#     prev        Return prev via $prev
+#     words       Return words via $words
+#     cword       Return cword via $cword
+#
+# Available OPTIONS:
+#     -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT be 
+#                 considered word breaks. This is useful for things like scp
+#                 where we want to return host:path and not only path, so we
+#                 would pass the colon (:) as -n option in this case.  Bash-3
+#                 doesn't do word splitting, so this ensures we get the same
+#                 word on both bash-3 and bash-4.
+#     -c VARNAME  Return cur via $VARNAME
+#     -p VARNAME  Return prev via $VARNAME
+#     -w VARNAME  Return words via $VARNAME
+#     -i VARNAME  Return cword via $VARNAME
+#
+# Example usage:
+#
+#    $ _get_comp_words_by_ref -n : cur prev
+#
+_get_comp_words_by_ref()
+{
+    local exclude flag i OPTIND=1
+    local cur cword words=()
+    local upargs=() upvars=() vcur vcword vprev vwords
+
+    while getopts "c:i:n:p:w:" flag "$@"; do
+        case $flag in
+            c) vcur=$OPTARG ;;
+            i) vcword=$OPTARG ;;
+            n) exclude=$OPTARG ;;
+            p) vprev=$OPTARG ;;
+            w) vwords=$OPTARG ;;
+        esac
+    done
+    while [[ $# -ge $OPTIND ]]; do 
+        case ${!OPTIND} in
+            cur)   vcur=cur ;;
+            prev)  vprev=prev ;;
+            cword) vcword=cword ;;
+            words) vwords=words ;;
+            *) echo "bash: $FUNCNAME(): \`${!OPTIND}': unknown argument" \
+                1>&2; return 1
+        esac
+        let "OPTIND += 1"
+    done
+
+    __get_cword_at_cursor_by_ref "$exclude" words cword cur
+
+    [[ $vcur   ]] && { upvars+=("$vcur"  ); upargs+=(-v $vcur   "$cur"  ); }
+    [[ $vcword ]] && { upvars+=("$vcword"); upargs+=(-v $vcword "$cword"); }
+    [[ $vprev  ]] && { upvars+=("$vprev" ); upargs+=(-v $vprev 
+        "${words[cword - 1]}"); }
+    [[ $vwords ]] && { upvars+=("$vwords"); upargs+=(-a${#words[@]} $vwords
+        "${words[@]}"); }
+
+    (( ${#upvars[@]} )) && local "${upvars[@]}" && _upvars "${upargs[@]}"
+}
+
+
+# Get the word to complete.
+# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
+# where the user is completing in the middle of a word.
+# (For example, if the line is "ls foobar",
+# and the cursor is here -------->   ^
+# @param $1 string  Characters out of $COMP_WORDBREAKS which should NOT be
+#     considered word breaks. This is useful for things like scp where
+#     we want to return host:path and not only path, so we would pass the
+#     colon (:) as $1 in this case.  Bash-3 doesn't do word splitting, so this
+#     ensures we get the same word on both bash-3 and bash-4.
+# @param $2 integer  Index number of word to return, negatively offset to the
+#     current word (default is 0, previous is 1), respecting the exclusions
+#     given at $1.  For example, `_get_cword "=:" 1' returns the word left of
+#     the current word, respecting the exclusions "=:".
+# @deprecated  Use `_get_comp_words_by_ref cur' instead
+# @see _get_comp_words_by_ref()
+_get_cword()
+{
+    local LC_CTYPE=C
+    local cword words
+    __reassemble_comp_words_by_ref "$1" words cword
+
+    # return previous word offset by $2
+    if [[ ${2//[^0-9]/} ]]; then
+        printf "%s" "${words[cword-$2]}"
+    elif [[ "${#words[cword]}" -eq 0 || "$COMP_POINT" == "${#COMP_LINE}" ]]; then
+        printf "%s" "${words[cword]}"
+    else
+        local i
+        local cur="$COMP_LINE"
+        local index="$COMP_POINT"
+        for (( i = 0; i <= cword; ++i )); do
+            while [[
+                # Current word fits in $cur?
+                "${#cur}" -ge ${#words[i]} &&
+                # $cur doesn't match cword?
+                "${cur:0:${#words[i]}}" != "${words[i]}"
+            ]]; do
+                # Strip first character
+                cur="${cur:1}"
+                # Decrease cursor position
+                ((index--))
+            done
+
+            # Does found word matches cword?
+            if [[ "$i" -lt "$cword" ]]; then
+                # No, cword lies further;
+                local old_size="${#cur}"
+                cur="${cur#${words[i]}}"
+                local new_size="${#cur}"
+                index=$(( index - old_size + new_size ))
+            fi
+        done
+
+        if [[ "${words[cword]:0:${#cur}}" != "$cur" ]]; then
+            # We messed up! At least return the whole word so things
+            # keep working
+            printf "%s" "${words[cword]}"
+        else
+            printf "%s" "${cur:0:$index}"
+        fi
+    fi
+} # _get_cword()
+
+
+# Get word previous to the current word.
+# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
+# will properly return the previous word with respect to any given exclusions to
+# COMP_WORDBREAKS.
+# @deprecated  Use `_get_comp_words_by_ref cur prev' instead
+# @see _get_comp_words_by_ref()
+#
+_get_pword() 
+{
+    if [ $COMP_CWORD -ge 1 ]; then
+        _get_cword "${@:-}" 1;
+    fi
+}
+
+
+# If the word-to-complete contains a colon (:), left-trim COMPREPLY items with
+# word-to-complete.
+# On bash-3, and bash-4 with a colon in COMP_WORDBREAKS, words containing
+# colons are always completed as entire words if the word to complete contains
+# a colon.  This function fixes this, by removing the colon-containing-prefix
+# from COMPREPLY items.
+# The preferred solution is to remove the colon (:) from COMP_WORDBREAKS in
+# your .bashrc:
+#
+#    # Remove colon (:) from list of word completion separators
+#    COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
+#
+# See also: Bash FAQ - E13) Why does filename completion misbehave if a colon
+# appears in the filename? - http://tiswww.case.edu/php/chet/bash/FAQ
+# @param $1 current word to complete (cur)
+# @modifies global array $COMPREPLY
+#
+__ltrim_colon_completions() {
+    # If word-to-complete contains a colon,
+    # and bash-version < 4,
+    # or bash-version >= 4 and COMP_WORDBREAKS contains a colon
+    if [[
+        "$1" == *:* && (
+            ${BASH_VERSINFO[0]} -lt 4 || 
+            (${BASH_VERSINFO[0]} -ge 4 && "$COMP_WORDBREAKS" == *:*) 
+        )
+    ]]; then
+        # Remove colon-word prefix from COMPREPLY items
+        local colon_word=${1%${1##*:}}
+        local i=${#COMPREPLY[*]}
+        while [ $((--i)) -ge 0 ]; do
+            COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
+        done
+    fi
+} # __ltrim_colon_completions()
+
+
+# This function quotes the argument in a way so that readline dequoting
+# results in the original argument.  This is necessary for at least
+# `compgen' which requires its arguments quoted/escaped:
+#
+#     $ ls "a'b/"
+#     c
+#     $ compgen -f "a'b/"       # Wrong, doesn't return output
+#     $ compgen -f "a\'b/"      # Good (bash-4)
+#     a\'b/c
+#     $ compgen -f "a\\\\\'b/"  # Good (bash-3)
+#     a\'b/c
+#
+# On bash-3, special characters need to be escaped extra.  This is
+# unless the first character is a single quote (').  If the single
+# quote appears further down the string, bash default completion also
+# fails, e.g.:
+#
+#     $ ls 'a&b/'
+#     f
+#     $ foo 'a&b/<TAB>  # Becomes: foo 'a&b/f'
+#     $ foo a'&b/<TAB>  # Nothing happens
+#
+# See also:
+# - http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html
+# - http://www.mail-archive.com/bash-completion-devel@lists.alioth.\
+#   debian.org/msg01944.html
+# @param $1  Argument to quote
+# @param $2  Name of variable to return result to
+_quote_readline_by_ref()
+{
+    if [[ ${1:0:1} == "'" ]]; then
+        if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
+            # Leave out first character
+            printf -v $2 %s "${1:1}"
+        else
+            # Quote word, leaving out first character
+            printf -v $2 %q "${1:1}"
+            # Double-quote word (bash-3)
+            printf -v $2 %q ${!2}
+        fi
+    elif [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == '"' ]]; then
+        printf -v $2 %q "${1:1}"
+    else
+        printf -v $2 %q "$1"
+    fi
+
+    # If result becomes quoted like this: $'string', re-evaluate in order to
+    # drop the additional quoting.  See also: http://www.mail-archive.com/
+    # bash-completion-devel@lists.alioth.debian.org/msg01942.html
+    [[ ${!2:0:1} == '$' ]] && eval $2=${!2}
+} # _quote_readline_by_ref()
+
+
+# This function turns on "-o filenames" behavior dynamically. It is present
+# for bash < 4 reasons. See http://bugs.debian.org/272660#64 for info about
+# the bash < 4 compgen hack.
+_compopt_o_filenames()
+{
+    # We test for compopt availability first because directly invoking it on
+    # bash < 4 at this point may cause terminal echo to be turned off for some
+    # reason, see https://bugzilla.redhat.com/653669 for more info.
+    type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \
+        compgen -f /non-existing-dir/ >/dev/null
+}
+
+
+# This function performs file and directory completion. It's better than
+# simply using 'compgen -f', because it honours spaces in filenames.
+# @param $1  If `-d', complete only on directories.  Otherwise filter/pick only
+#            completions with `.$1' and the uppercase version of it as file
+#            extension.
+#
+_filedir()
+{
+    local i IFS=$'\n' xspec
+
+    _tilde "$cur" || return 0
+
+    local -a toks
+    local quoted tmp
+
+    _quote_readline_by_ref "$cur" quoted
+    toks=( ${toks[@]-} $(
+        compgen -d -- "$quoted" | {
+            while read -r tmp; do
+                # TODO: I have removed a "[ -n $tmp ] &&" before 'printf ..',
+                #       and everything works again. If this bug suddenly
+                #       appears again (i.e. "cd /b<TAB>" becomes "cd /"),
+                #       remember to check for other similar conditionals (here
+                #       and _filedir_xspec()). --David
+                printf '%s\n' $tmp
+            done
+        }
+    ))
+
+    if [[ "$1" != -d ]]; then
+        # Munge xspec to contain uppercase version too
+        [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
+            xspec=${1:+"!*.@($1|${1^^})"} || \
+            xspec=${1:+"!*.@($1|$(printf %s $1 | tr '[:lower:]' '[:upper:]'))"}
+        toks=( ${toks[@]-} $( compgen -f -X "$xspec" -- $quoted) )
+    fi
+    [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames
+
+    COMPREPLY=( "${COMPREPLY[@]}" "${toks[@]}" )
+} # _filedir()
+
+
+# This function splits $cur=--foo=bar into $prev=--foo, $cur=bar, making it
+# easier to support both "--foo bar" and "--foo=bar" style completions.
+# Returns 0 if current option was split, 1 otherwise.
+#
+_split_longopt()
+{
+    if [[ "$cur" == --?*=* ]]; then
+        # Cut also backslash before '=' in case it ended up there
+        # for some reason.
+        prev="${cur%%?(\\)=*}"
+        cur="${cur#*=}"
+        return 0
+    fi
+
+    return 1
+}
+
+# This function tries to parse the help output of the given command.
+# @param $1  command
+# @param $2  command options (default: --help)
+#
+_parse_help() {
+    $1 ${2:---help} 2>&1 | sed -e '/^[[:space:]]*-/!d' -e 's|[,/]| |g' | \
+        awk '{ print $1; if ($2 ~ /^-/) { print $2 } }' | sed -e 's|[<=].*||'
+}
+
+# This function completes on signal names
+#
+_signals()
+{
+    local i
+
+    # standard signal completion is rather braindead, so we need
+    # to hack around to get what we want here, which is to
+    # complete on a dash, followed by the signal name minus
+    # the SIG prefix
+    COMPREPLY=( $( compgen -A signal SIG${cur#-} ))
+    for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
+        COMPREPLY[i]=-${COMPREPLY[i]#SIG}
+    done
+}
+
+# This function completes on known mac addresses
+#
+_mac_addresses()
+{
+    local re='\([A-Fa-f0-9]\{2\}:\)\{5\}[A-Fa-f0-9]\{2\}'
+    local PATH="$PATH:/sbin:/usr/sbin"
+
+    # Local interfaces (Linux only?)
+    COMPREPLY=( "${COMPREPLY[@]}" $( ifconfig -a 2>/dev/null | sed -ne \
+        "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" ) )
+
+    # ARP cache
+    COMPREPLY=( "${COMPREPLY[@]}" $( arp -an 2>/dev/null | sed -ne \
+        "s/.*[[:space:]]\($re\)[[:space:]].*/\1/p" -ne \
+        "s/.*[[:space:]]\($re\)[[:space:]]*$/\1/p" ) )
+
+    # /etc/ethers
+    COMPREPLY=( "${COMPREPLY[@]}" $( sed -ne \
+        "s/^[[:space:]]*\($re\)[[:space:]].*/\1/p" /etc/ethers 2>/dev/null ) )
+
+    COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) )
+    __ltrim_colon_completions "$cur"
+}
+
+# This function completes on configured network interfaces
+#
+_configured_interfaces()
+{
+    if [ -f /etc/debian_version ]; then
+        # Debian system
+        COMPREPLY=( $( compgen -W "$( sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p'\
+            /etc/network/interfaces )" -- "$cur" ) )
+    elif [ -f /etc/SuSE-release ]; then
+        # SuSE system
+        COMPREPLY=( $( compgen -W "$( printf '%s\n' \
+            /etc/sysconfig/network/ifcfg-* | \
+            sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
+    elif [ -f /etc/pld-release ]; then
+        # PLD Linux
+        COMPREPLY=( $( compgen -W "$( command ls -B \
+            /etc/sysconfig/interfaces | \
+            sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
+    else
+        # Assume Red Hat
+        COMPREPLY=( $( compgen -W "$( printf '%s\n' \
+            /etc/sysconfig/network-scripts/ifcfg-* | \
+            sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
+    fi
+}
+
+# This function completes on available kernels
+#
+_kernel_versions()
+{
+    COMPREPLY=( $( compgen -W '$( command ls /lib/modules )' -- "$cur" ) )
+}
+
+# This function completes on all available network interfaces
+# -a: restrict to active interfaces only
+# -w: restrict to wireless interfaces only
+#
+_available_interfaces()
+{
+    local cmd
+
+    if [ "${1:-}" = -w ]; then
+        cmd="iwconfig"
+    elif [ "${1:-}" = -a ]; then
+        cmd="ifconfig"
+    else
+        cmd="ifconfig -a"
+    fi
+
+    COMPREPLY=( $( eval PATH="$PATH:/sbin" $cmd 2>/dev/null | \
+        awk '/^[^ \t]/ { print $1 }' ) )
+    COMPREPLY=( $( compgen -W '${COMPREPLY[@]/%[[:punct:]]/}' -- "$cur" ) )
+}
+
+
+# Perform tilde (~) completion
+# @return  True (0) if completion needs further processing, 
+#          False (> 0) if tilde is followed by a valid username, completions
+#          are put in COMPREPLY and no further processing is necessary.
+_tilde() {
+    local result=0
+    # Does $1 start with tilde (~) and doesn't contain slash (/)?
+    if [[ ${1:0:1} == "~" && $1 == ${1//\/} ]]; then
+        _compopt_o_filenames
+        # Try generate username completions
+        COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
+        result=${#COMPREPLY[@]}
+    fi
+    return $result
+}
+
+
+# Expand variable starting with tilde (~)
+# We want to expand ~foo/... to /home/foo/... to avoid problems when
+# word-to-complete starting with a tilde is fed to commands and ending up
+# quoted instead of expanded.
+# Only the first portion of the variable from the tilde up to the first slash
+# (~../) is expanded.  The remainder of the variable, containing for example
+# a dollar sign variable ($) or asterisk (*) is not expanded.
+# Example usage:
+#
+#    $ v="~"; __expand_tilde_by_ref v; echo "$v"
+#
+# Example output:
+#
+#       v                  output
+#    --------         ----------------
+#    ~                /home/user
+#    ~foo/bar         /home/foo/bar
+#    ~foo/$HOME       /home/foo/$HOME
+#    ~foo/a  b        /home/foo/a  b
+#    ~foo/*           /home/foo/*
+#  
+# @param $1  Name of variable (not the value of the variable) to expand
+__expand_tilde_by_ref() {
+    # Does $1 start with tilde (~)?
+    if [ "${!1:0:1}" = "~" ]; then
+        # Does $1 contain slash (/)?
+        if [ "${!1}" != "${!1//\/}" ]; then
+            # Yes, $1 contains slash;
+            # 1: Remove * including and after first slash (/), i.e. "~a/b"
+            #    becomes "~a".  Double quotes allow eval.
+            # 2: Remove * before the first slash (/), i.e. "~a/b"
+            #    becomes "b".  Single quotes prevent eval.
+            #       +-----1----+ +---2----+
+            eval $1="${!1/%\/*}"/'${!1#*/}'
+        else 
+            # No, $1 doesn't contain slash
+            eval $1="${!1}"
+        fi
+    fi
+} # __expand_tilde_by_ref()
+
+
+# This function expands tildes in pathnames
+#
+_expand()
+{
+    # FIXME: Why was this here?
+    #[ "$cur" != "${cur%\\}" ] && cur="$cur\\"
+
+    # Expand ~username type directory specifications.  We want to expand
+    # ~foo/... to /home/foo/... to avoid problems when $cur starting with
+    # a tilde is fed to commands and ending up quoted instead of expanded.
+
+    if [[ "$cur" == \~*/* ]]; then
+        eval cur=$cur
+    elif [[ "$cur" == \~* ]]; then
+        cur=${cur#\~}
+        COMPREPLY=( $( compgen -P '~' -u "$cur" ) )
+        [ ${#COMPREPLY[@]} -eq 1 ] && eval COMPREPLY[0]=${COMPREPLY[0]}
+        return ${#COMPREPLY[@]}
+    fi
+}
+
+# This function completes on process IDs.
+# AIX and Solaris ps prefers X/Open syntax.
+[[ $UNAME == SunOS || $UNAME == AIX ]] &&
+_pids()
+{
+    COMPREPLY=( $( compgen -W '$( command ps -efo pid | sed 1d )' -- "$cur" ))
+} ||
+_pids()
+{
+    COMPREPLY=( $( compgen -W '$( command ps axo pid= )' -- "$cur" ) )
+}
+
+# This function completes on process group IDs.
+# AIX and SunOS prefer X/Open, all else should be BSD.
+[[ $UNAME == SunOS || $UNAME == AIX ]] &&
+_pgids()
+{
+    COMPREPLY=( $( compgen -W '$( command ps -efo pgid | sed 1d )' -- "$cur" ))
+} ||
+_pgids()
+{
+    COMPREPLY=( $( compgen -W '$( command ps axo pgid= )' -- "$cur" ))
+}
+
+# This function completes on process names.
+# AIX and SunOS prefer X/Open, all else should be BSD.
+[[ $UNAME == SunOS || $UNAME == AIX ]] &&
+_pnames()
+{
+    COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps -efo comm | \
+        sed -e 1d -e "s:.*/::" -e "s/^-//" | sort -u )' -- "$cur" ) )
+} ||
+_pnames()
+{
+    # FIXME: completes "[kblockd/0]" to "0". Previously it was completed
+    # to "kblockd" which isn't correct either. "kblockd/0" would be
+    # arguably most correct, but killall from psmisc 22 treats arguments
+    # containing "/" specially unless -r is given so that wouldn't quite
+    # work either. Perhaps it'd be best to not complete these to anything
+    # for now.
+    # Not using "ps axo comm" because under some Linux kernels, it
+    # truncates command names (see e.g. http://bugs.debian.org/497540#19)
+    COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps axo command= | \
+        sed -e "s/ .*//" -e "s:.*/::" -e "s/:$//" -e "s/^[[(-]//" \
+            -e "s/[])]$//" | sort -u )' -- "$cur" ) )
+}
+
+# This function completes on user IDs
+#
+_uids()
+{
+    if type getent &>/dev/null; then
+        COMPREPLY=( $( compgen -W '$( getent passwd | cut -d: -f3 )' -- "$cur" ) )
+    elif type perl &>/dev/null; then
+        COMPREPLY=( $( compgen -W '$( perl -e '"'"'while (($uid) = (getpwent)[2]) { print $uid . "\n" }'"'"' )' -- "$cur" ) )
+    else
+        # make do with /etc/passwd
+        COMPREPLY=( $( compgen -W '$( cut -d: -f3 /etc/passwd )' -- "$cur" ) )
+    fi
+}
+
+# This function completes on group IDs
+#
+_gids()
+{
+    if type getent &>/dev/null; then
+        COMPREPLY=( $( compgen -W '$( getent group | cut -d: -f3 )' \
+            -- "$cur" ) )
+    elif type perl &>/dev/null; then
+        COMPREPLY=( $( compgen -W '$( perl -e '"'"'while (($gid) = (getgrent)[2]) { print $gid . "\n" }'"'"' )' -- "$cur" ) )
+    else
+        # make do with /etc/group
+        COMPREPLY=( $( compgen -W '$( cut -d: -f3 /etc/group )' -- "$cur" ) )
+    fi
+}
+
+# This function completes on services
+#
+_services()
+{
+    local sysvdir famdir
+    [ -d /etc/rc.d/init.d ] && sysvdir=/etc/rc.d/init.d || sysvdir=/etc/init.d
+    famdir=/etc/xinetd.d
+    COMPREPLY=( $( printf '%s\n' \
+        $sysvdir/!(*.rpm@(orig|new|save)|*~|functions) ) )
+
+    if [ -d $famdir ]; then
+        COMPREPLY=( "${COMPREPLY[@]}" $( printf '%s\n' \
+            $famdir/!(*.rpm@(orig|new|save)|*~) ) )
+    fi
+
+    COMPREPLY=( $( compgen -W '${COMPREPLY[@]#@($sysvdir|$famdir)/}' -- "$cur" ) )
+}
+
+# This function completes on modules
+#
+_modules()
+{
+    local modpath
+    modpath=/lib/modules/$1
+    COMPREPLY=( $( compgen -W "$( command ls -R $modpath | \
+        sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.gz\)\{0,1\}$/\1/p' )" -- "$cur" ) )
+}
+
+# This function completes on installed modules
+#
+_installed_modules()
+{
+    COMPREPLY=( $( compgen -W "$( PATH="$PATH:/sbin" lsmod | \
+        awk '{if (NR != 1) print $1}' )" -- "$1" ) )
+}
+
+# This function completes on user or user:group format; as for chown and cpio.
+#
+# The : must be added manually; it will only complete usernames initially.
+# The legacy user.group format is not supported.
+#
+# @param $1  If -u, only return users/groups the user has access to in
+#            context of current completion.
+_usergroup()
+{
+    if [[ $cur = *\\\\* || $cur = *:*:* ]]; then
+        # Give up early on if something seems horribly wrong.
+        return
+    elif [[ $cur = *\\:* ]]; then
+        # Completing group after 'user\:gr<TAB>'.
+        # Reply with a list of groups prefixed with 'user:', readline will
+        # escape to the colon.
+        local prefix
+        prefix=${cur%%*([^:])}
+        prefix=${prefix//\\}
+        local mycur="${cur#*[:]}"
+        if [[ $1 == -u ]]; then
+            _allowed_groups "$mycur"
+        else
+            local IFS=$'\n'
+            COMPREPLY=( $( compgen -g -- "$mycur" ) )
+        fi
+        COMPREPLY=( $( compgen -P "$prefix" -W "${COMPREPLY[@]}" ) )
+    elif [[ $cur = *:* ]]; then
+        # Completing group after 'user:gr<TAB>'.
+        # Reply with a list of unprefixed groups since readline with split on :
+        # and only replace the 'gr' part
+        local mycur="${cur#*:}"
+        if [[ $1 == -u ]]; then
+            _allowed_groups "$mycur"
+        else
+            local IFS=$'\n'
+            COMPREPLY=( $( compgen -g -- "$mycur" ) )
+        fi
+    else
+        # Completing a partial 'usernam<TAB>'.
+        #
+        # Don't suffix with a : because readline will escape it and add a
+        # slash. It's better to complete into 'chown username ' than 'chown
+        # username\:'.
+        if [[ $1 == -u ]]; then
+            _allowed_users "$cur"
+        else
+            local IFS=$'\n'
+            COMPREPLY=( $( compgen -u -- "$cur" ) )
+        fi
+    fi
+}
+
+_allowed_users()
+{
+    if _complete_as_root; then
+        local IFS=$'\n'
+        COMPREPLY=( $( compgen -u -- "${1:-$cur}" ) )
+    else
+        local IFS=$'\n '
+        COMPREPLY=( $( compgen -W \
+            "$( id -un 2>/dev/null || whoami 2>/dev/null )" -- "${1:-$cur}" ) )
+    fi
+}
+
+_allowed_groups()
+{
+    if _complete_as_root; then
+        local IFS=$'\n'
+        COMPREPLY=( $( compgen -g -- "$1" ) )
+    else
+        local IFS=$'\n '
+        COMPREPLY=( $( compgen -W \
+            "$( id -Gn 2>/dev/null || groups 2>/dev/null )" -- "$1" ) )
+    fi
+}
+
+# This function completes on valid shells
+#
+_shells()
+{
+    COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W \
+        '$( command grep "^[[:space:]]*/" /etc/shells 2>/dev/null )' \
+        -- "$cur" ) )
+}
+
+# This function completes on valid filesystem types
+#
+_fstypes()
+{
+    local fss
+
+    if [ -e /proc/filesystems ] ; then
+        # Linux
+        fss="$( cut -d$'\t' -f2 /proc/filesystems )
+             $( awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null )"
+    else
+        # Generic
+        fss="$( awk '/^[ \t]*[^#]/ { print $3 }' /etc/fstab 2>/dev/null )
+             $( awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null )
+             $( awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null )
+             $( awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null )
+             $( [ -d /etc/fs ] && command ls /etc/fs )"
+    fi
+
+    [ -n "$fss" ] && \
+        COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$fss" -- "$cur" ) )
+}
+
+# Get real command.
+# - arg: $1  Command
+# - stdout:  Filename of command in PATH with possible symbolic links resolved.
+#            Empty string if command not found.
+# - return:  True (0) if command found, False (> 0) if not.
+_realcommand()
+{
+    type -P "$1" > /dev/null && {
+        if type -p realpath > /dev/null; then
+            realpath "$(type -P "$1")"
+        elif type -p readlink > /dev/null; then
+            readlink "$(type -P "$1")"
+        else
+            type -P "$1"
+        fi
+    }
+}
+
+# This function returns the first arugment, excluding options
+# @param $1 chars  Characters out of $COMP_WORDBREAKS which should
+#     NOT be considered word breaks. See __reassemble_comp_words_by_ref.
+_get_first_arg()
+{
+    local i
+
+    arg=
+    for (( i=1; i < COMP_CWORD; i++ )); do
+        if [[ "${COMP_WORDS[i]}" != -* ]]; then
+            arg=${COMP_WORDS[i]}
+            break
+        fi
+    done
+}
+
+
+# This function counts the number of args, excluding options
+# @param $1 chars  Characters out of $COMP_WORDBREAKS which should
+#     NOT be considered word breaks. See __reassemble_comp_words_by_ref.
+_count_args()
+{
+    local i cword words
+    __reassemble_comp_words_by_ref "$1" words cword
+
+    args=1
+    for i in "${words[@]:1:cword-1}"; do
+        [[ "$i" != -* ]] && args=$(($args+1))
+    done
+}
+
+# This function completes on PCI IDs
+#
+_pci_ids()
+{
+    COMPREPLY=( ${COMPREPLY[@]:-} $( compgen -W \
+        "$( PATH="$PATH:/sbin" lspci -n | awk '{print $3}')" -- "$cur" ) )
+}
+
+# This function completes on USB IDs
+#
+_usb_ids()
+{
+    COMPREPLY=( ${COMPREPLY[@]:-} $( compgen -W \
+        "$( PATH="$PATH:/sbin" lsusb | awk '{print $6}' )" -- "$cur" ) )
+}
+
+# CD device names
+_cd_devices()
+{
+    COMPREPLY=( "${COMPREPLY[@]}"
+        $( compgen -f -d -X "!*/?([amrs])cd*" -- "${cur:-/dev/}" ) )
+}
+
+# DVD device names
+_dvd_devices()
+{
+    COMPREPLY=( "${COMPREPLY[@]}"
+        $( compgen -f -d -X "!*/?(r)dvd*" -- "${cur:-/dev/}" ) )
+}
+
+# start of section containing completion functions for external programs
+
+# a little help for FreeBSD ports users
+[ $UNAME = FreeBSD ] && complete -W 'index search fetch fetch-list extract \
+    patch configure build install reinstall deinstall clean clean-depends \
+    kernel buildworld' make
+
+# This function provides simple user@host completion
+#
+_user_at_host() {
+    local cur
+
+    COMPREPLY=()
+    _get_comp_words_by_ref -n : cur
+
+    if [[ $cur == *@* ]]; then
+        _known_hosts_real "$cur"
+    else
+        COMPREPLY=( $( compgen -u -- "$cur" ) )
+    fi
+
+    return 0
+}
+shopt -u hostcomplete && complete -F _user_at_host -o nospace talk ytalk finger
+
+# NOTE: Using this function as a helper function is deprecated.  Use
+#       `_known_hosts_real' instead.
+_known_hosts()
+{
+    local options
+    COMPREPLY=()
+
+    # NOTE: Using `_known_hosts' as a helper function and passing options
+    #       to `_known_hosts' is deprecated: Use `_known_hosts_real' instead.
+    [[ "$1" == -a || "$2" == -a ]] && options=-a
+    [[ "$1" == -c || "$2" == -c ]] && options="$options -c"
+    _known_hosts_real $options "$(_get_cword :)"
+} # _known_hosts()
+
+# Helper function for completing _known_hosts.
+# This function performs host completion based on ssh's config and known_hosts
+# files, as well as hostnames reported by avahi-browse if
+# COMP_KNOWN_HOSTS_WITH_AVAHI is set to a non-empty value.  Also hosts from
+# HOSTFILE (compgen -A hostname) are added, unless
+# COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an empty value.
+# Usage: _known_hosts_real [OPTIONS] CWORD
+# Options:  -a             Use aliases
+#           -c             Use `:' suffix
+#           -F configfile  Use `configfile' for configuration settings
+#           -p PREFIX      Use PREFIX
+# Return: Completions, starting with CWORD, are added to COMPREPLY[]
+_known_hosts_real()
+{
+    local configfile flag prefix
+    local cur curd awkcur user suffix aliases i host
+    local -a kh khd config
+
+    local OPTIND=1
+    while getopts "acF:p:" flag "$@"; do
+        case $flag in
+            a) aliases='yes' ;;
+            c) suffix=':' ;;
+            F) configfile=$OPTARG ;;
+            p) prefix=$OPTARG ;;
+        esac
+    done
+    [ $# -lt $OPTIND ] && echo "error: $FUNCNAME: missing mandatory argument CWORD"
+    cur=${!OPTIND}; let "OPTIND += 1"
+    [ $# -ge $OPTIND ] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\
+    $(while [ $# -ge $OPTIND ]; do printf '%s\n' ${!OPTIND}; shift; done)
+
+    [[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
+    kh=()
+
+    # ssh config files
+    if [ -n "$configfile" ]; then
+        [ -r "$configfile" ] &&
+        config=( "${config[@]}" "$configfile" )
+    else
+        for i in /etc/ssh/ssh_config "${HOME}/.ssh/config" \
+            "${HOME}/.ssh2/config"; do
+            [ -r $i ] && config=( "${config[@]}" "$i" )
+        done
+    fi
+
+    # Known hosts files from configs
+    if [ ${#config[@]} -gt 0 ]; then
+        local OIFS=$IFS IFS=$'\n'
+        local -a tmpkh
+        # expand paths (if present) to global and user known hosts files
+        # TODO(?): try to make known hosts files with more than one consecutive
+        #          spaces in their name work (watch out for ~ expansion
+        #          breakage! Alioth#311595)
+        tmpkh=( $( awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u ) )
+        for i in "${tmpkh[@]}"; do
+            # Remove possible quotes
+            i=${i//\"}
+            # Eval/expand possible `~' or `~user'
+            __expand_tilde_by_ref i
+            [ -r "$i" ] && kh=( "${kh[@]}" "$i" )
+        done
+        IFS=$OIFS
+    fi
+
+    if [ -z "$configfile" ]; then
+        # Global and user known_hosts files
+        for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \
+            /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \
+            ~/.ssh/known_hosts2; do
+            [ -r $i ] && kh=( "${kh[@]}" $i )
+        done
+        for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do
+            [ -d $i ] && khd=( "${khd[@]}" $i/*pub )
+        done
+    fi
+
+    # If we have known_hosts files to use
+    if [[ ${#kh[@]} -gt 0 || ${#khd[@]} -gt 0 ]]; then
+        # Escape slashes and dots in paths for awk
+        awkcur=${cur//\//\\\/}
+        awkcur=${awkcur//\./\\\.}
+        curd=$awkcur
+
+        if [[ "$awkcur" == [0-9]*[.:]* ]]; then
+            # Digits followed by a dot or a colon - just search for that
+            awkcur="^$awkcur[.:]*"
+        elif [[ "$awkcur" == [0-9]* ]]; then
+            # Digits followed by no dot or colon - search for digits followed
+            # by a dot or a colon
+            awkcur="^$awkcur.*[.:]"
+        elif [ -z "$awkcur" ]; then
+            # A blank - search for a dot, a colon, or an alpha character
+            awkcur="[a-z.:]"
+        else
+            awkcur="^$awkcur"
+        fi
+
+        if [ ${#kh[@]} -gt 0 ]; then
+            # FS needs to look for a comma separated list
+            COMPREPLY=( "${COMPREPLY[@]}" $( awk 'BEGIN {FS=","}
+            /^\s*[^|\#]/ {for (i=1; i<=2; ++i) { \
+            sub(" .*$", "", $i); \
+            sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \
+            if ($i ~ /'"$awkcur"'/) {print $i} \
+            }}' "${kh[@]}" 2>/dev/null ) )
+        fi
+        if [ ${#khd[@]} -gt 0 ]; then
+            # Needs to look for files called
+            # .../.ssh2/key_22_<hostname>.pub
+            # dont fork any processes, because in a cluster environment,
+            # there can be hundreds of hostkeys
+            for i in "${khd[@]}" ; do
+                if [[ "$i" == *key_22_$curd*.pub && -r "$i" ]]; then
+                    host=${i/#*key_22_/}
+                    host=${host/%.pub/}
+                    COMPREPLY=( "${COMPREPLY[@]}" $host )
+                fi
+            done
+        fi
+
+        # apply suffix and prefix
+        for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
+            COMPREPLY[i]=$prefix$user${COMPREPLY[i]}$suffix
+        done
+    fi
+
+    # append any available aliases from config files
+    if [[ ${#config[@]} -gt 0 && -n "$aliases" ]]; then
+        local hosts=$( sed -ne 's/^[ \t]*[Hh][Oo][Ss][Tt]\([Nn][Aa][Mm][Ee]\)\{0,1\}['"$'\t '"']\{1,\}\([^#*?]*\)\(#.*\)\{0,1\}$/\2/p' "${config[@]}" )
+        COMPREPLY=( "${COMPREPLY[@]}" $( compgen  -P "$prefix$user" \
+            -S "$suffix" -W "$hosts" -- "$cur" ) )
+    fi
+
+    # Add hosts reported by avahi-browse, if desired and it's available.
+    if [[ ${COMP_KNOWN_HOSTS_WITH_AVAHI:-} ]] && \
+        type avahi-browse &>/dev/null; then
+        # The original call to avahi-browse also had "-k", to avoid lookups
+        # into avahi's services DB. We don't need the name of the service, and
+        # if it contains ";", it may mistify the result. But on Gentoo (at
+        # least), -k wasn't available (even if mentioned in the manpage) some
+        # time ago, so...
+        COMPREPLY=( "${COMPREPLY[@]}" $( \
+            compgen -P "$prefix$user" -S "$suffix" -W \
+            "$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
+                 awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
+    fi
+
+    # Add results of normal hostname completion, unless
+    # `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value.
+    if [ -n "${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1}" ]; then
+        COMPREPLY=( "${COMPREPLY[@]}"
+            $( compgen -A hostname -P "$prefix$user" -S "$suffix" -- "$cur" ) )
+    fi
+
+    __ltrim_colon_completions "$prefix$user$cur"
+
+    return 0
+} # _known_hosts_real()
+complete -F _known_hosts traceroute traceroute6 tracepath tracepath6 ping \
+    ping6 fping fping6 telnet host nslookup rsh rlogin ftp dig mtr \
+    ssh-installkeys showmount
+
+# This meta-cd function observes the CDPATH variable, so that cd additionally
+# completes on directories under those specified in CDPATH.
+#
+_cd()
+{
+    local cur IFS=$'\n' i j k
+    _get_comp_words_by_ref cur
+
+    # try to allow variable completion
+    if [[ "$cur" == ?(\\)\$* ]]; then
+        COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\\)$}" ) )
+        return 0
+    fi
+
+    _compopt_o_filenames
+
+    # Use standard dir completion if no CDPATH or parameter starts with /,
+    # ./ or ../
+    if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
+        _filedir -d
+        return 0
+    fi
+
+    local -r mark_dirs=$(_rl_enabled mark-directories && echo y)
+    local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y)
+
+    # we have a CDPATH, so loop on its contents
+    for i in ${CDPATH//:/$'\n'}; do
+        # create an array of matched subdirs
+        k="${#COMPREPLY[@]}"
+        for j in $( compgen -d $i/$cur ); do
+            if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
+                j="${j}/"
+            fi
+            COMPREPLY[k++]=${j#$i/}
+        done
+    done
+
+    _filedir -d
+
+    if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
+        i=${COMPREPLY[0]}
+        if [[ "$i" == "$cur" && $i != "*/" ]]; then
+            COMPREPLY[0]="${i}/"
+        fi
+    fi
+
+    return 0
+}
+if shopt -q cdable_vars; then
+    complete -v -F _cd -o nospace cd
+else
+    complete -F _cd -o nospace cd
+fi
+
+# a wrapper method for the next one, when the offset is unknown
+_command()
+{
+    local offset i
+
+    # find actual offset, as position of the first non-option
+    offset=1
+    for (( i=1; i <= COMP_CWORD; i++ )); do
+        if [[ "${COMP_WORDS[i]}" != -* ]]; then
+            offset=$i
+            break
+        fi
+    done
+    _command_offset $offset
+}
+
+# A meta-command completion function for commands like sudo(8), which need to
+# first complete on a command, then complete according to that command's own
+# completion definition - currently not quite foolproof (e.g. mount and umount
+# don't work properly), but still quite useful.
+#
+_command_offset()
+{
+    local cur func cline cspec noglob cmd i char_offset word_offset \
+        _COMMAND_FUNC _COMMAND_FUNC_ARGS
+
+    word_offset=$1
+
+    # rewrite current completion context before invoking
+    # actual command completion
+
+    # find new first word position, then
+    # rewrite COMP_LINE and adjust COMP_POINT
+    local first_word=${COMP_WORDS[$word_offset]}
+    for (( i=0; i <= ${#COMP_LINE}; i++ )); do
+        if [[ "${COMP_LINE:$i:${#first_word}}" == "$first_word" ]]; then
+            char_offset=$i
+            break
+        fi
+    done
+    COMP_LINE=${COMP_LINE:$char_offset}
+    COMP_POINT=$(( COMP_POINT - $char_offset ))
+
+    # shift COMP_WORDS elements and adjust COMP_CWORD
+    for (( i=0; i <= COMP_CWORD - $word_offset; i++ )); do
+        COMP_WORDS[i]=${COMP_WORDS[i+$word_offset]}
+    done
+    for (( i; i <= COMP_CWORD; i++ )); do
+        unset COMP_WORDS[i];
+    done
+    COMP_CWORD=$(( $COMP_CWORD - $word_offset ))
+
+    COMPREPLY=()
+    _get_comp_words_by_ref cur
+
+    if [[ $COMP_CWORD -eq 0 ]]; then
+        _compopt_o_filenames
+        COMPREPLY=( $( compgen -c -- "$cur" ) )
+    else
+        cmd=${COMP_WORDS[0]}
+        if complete -p ${cmd##*/} &>/dev/null; then
+            cspec=$( complete -p ${cmd##*/} )
+            if [ "${cspec#* -F }" != "$cspec" ]; then
+                # complete -F <function>
+
+                # get function name
+                func=${cspec#*-F }
+                func=${func%% *}
+
+                if [[ ${#COMP_WORDS[@]} -ge 2 ]]; then
+                    $func $cmd "${COMP_WORDS[${#COMP_WORDS[@]}-1]}" "${COMP_WORDS[${#COMP_WORDS[@]}-2]}"
+                else
+                    $func $cmd "${COMP_WORDS[${#COMP_WORDS[@]}-1]}"
+                fi
+
+                # remove any \: generated by a command that doesn't
+                # default to filenames or dirnames (e.g. sudo chown)
+                # FIXME: I'm pretty sure this does not work!
+                if [ "${cspec#*-o }" != "$cspec" ]; then
+                    cspec=${cspec#*-o }
+                    cspec=${cspec%% *}
+                    if [[ "$cspec" != @(dir|file)names ]]; then
+                        COMPREPLY=("${COMPREPLY[@]//\\\\:/:}")
+                    else
+                        _compopt_o_filenames
+                    fi
+                fi
+            elif [ -n "$cspec" ]; then
+                cspec=${cspec#complete};
+                cspec=${cspec%%${cmd##*/}};
+                COMPREPLY=( $( eval compgen "$cspec" -- "$cur" ) );
+            fi
+        elif [ ${#COMPREPLY[@]} -eq 0 ]; then
+            _filedir
+        fi
+    fi
+}
+complete -F _command aoss command do else eval exec ltrace nice nohup padsp \
+    then time tsocks vsound xargs
+
+_root_command()
+{
+    local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
+    local root_command=$1
+    _command $1 $2 $3
+}
+complete -F _root_command fakeroot gksu gksudo kdesudo really sudo
+
+# Return true if the completion should be treated as running as root
+_complete_as_root()
+{
+    [[ $EUID -eq 0 || ${root_command:-} ]]
+}
+
+_longopt()
+{
+    local cur prev split=false
+    _get_comp_words_by_ref -n = cur prev
+
+    _split_longopt && split=true
+
+    case "$prev" in
+        --*[Dd][Ii][Rr]*)
+            _filedir -d
+            return 0
+            ;;
+        --*[Ff][Ii][Ll][Ee]*|--*[Pp][Aa][Tt][Hh]*)
+            _filedir
+            return 0
+            ;;
+    esac
+
+    $split && return 0
+
+    if [[ "$cur" == -* ]]; then
+        COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \
+            sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}\).*/\1/p' | sort -u )" \
+            -- "$cur" ) )
+    elif [[ "$1" == @(mk|rm)dir ]]; then
+        _filedir -d
+    else
+        _filedir
+    fi
+}
+# makeinfo and texi2dvi are defined elsewhere.
+for i in a2ps awk bash bc bison cat colordiff cp csplit \
+    curl cut date df diff dir du enscript env expand fmt fold gperf gprof \
+    grep grub head indent irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
+    mv netstat nl nm objcopy objdump od paste patch pr ptx readelf rm rmdir \
+    sed seq sha{,1,224,256,384,512}sum shar sort split strip tac tail tee \
+    texindex touch tr uname unexpand uniq units vdir wc wget who; do
+    have $i && complete -F _longopt -o default $i
+done
+unset i
+
+_filedir_xspec()
+{
+    local IFS cur xspec
+
+    IFS=$'\n'
+    COMPREPLY=()
+    _get_comp_words_by_ref cur
+
+    _expand || return 0
+
+    # get first exclusion compspec that matches this command
+    xspec=$( awk "/^complete[ \t]+.*[ \t]${1##*/}([ \t]|\$)/ { print \$0; exit }" \
+        "$BASH_COMPLETION" )
+    # prune to leave nothing but the -X spec
+    xspec=${xspec#*-X }
+    xspec=${xspec%% *}
+
+    local -a toks
+    local tmp
+
+    toks=( ${toks[@]-} $(
+        compgen -d -- "$(quote_readline "$cur")" | {
+        while read -r tmp; do
+            # see long TODO comment in _filedir() --David
+            printf '%s\n' $tmp
+        done
+        }
+        ))
+
+    # Munge xspec to contain uppercase version too
+    eval xspec="${xspec}"
+    local matchop=!
+    if [[ $xspec == !* ]]; then
+        xspec=${xspec#!}
+        matchop=@
+    fi
+    [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
+        xspec="$matchop($xspec|${xspec^^})" || \
+        xspec="$matchop($xspec|$(printf %s $xspec | tr '[:lower:]' '[:upper:]'))"
+
+    toks=( ${toks[@]-} $(
+        eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | {
+        while read -r tmp; do
+            [ -n $tmp ] && printf '%s\n' $tmp
+        done
+        }
+        ))
+
+    [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames
+    COMPREPLY=( "${toks[@]}" )
+}
+list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' "$BASH_COMPLETION" | \
+    # read exclusion compspecs
+    (
+    while read line
+    do
+        # ignore compspecs that are commented out
+        if [ "${line#\#}" != "$line" ]; then continue; fi
+        line=${line%# START exclude*}
+        line=${line%# FINISH exclude*}
+        line=${line##*\'}
+        list=( "${list[@]}" $line )
+    done
+    printf '%s ' "${list[@]}"
+    )
+    ) )
+# remove previous compspecs
+if [ ${#list[@]} -gt 0 ]; then
+    eval complete -r ${list[@]}
+    # install new compspecs
+    eval complete -F _filedir_xspec "${list[@]}"
+fi
+unset list
+
+# source completion directory definitions
+if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
+    -x $BASH_COMPLETION_COMPAT_DIR ]]; then
+    for i in $(LC_ALL=C command ls "$BASH_COMPLETION_COMPAT_DIR"); do
+        i=$BASH_COMPLETION_COMPAT_DIR/$i
+        [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)|Makefile*) \
+            && -f $i && -r $i ]] && . "$i"
+    done
+fi
+if [[ $BASH_COMPLETION_DIR != $BASH_COMPLETION_COMPAT_DIR && \
+    -d $BASH_COMPLETION_DIR && -r $BASH_COMPLETION_DIR && \
+    -x $BASH_COMPLETION_DIR ]]; then
+    for i in $(LC_ALL=C command ls "$BASH_COMPLETION_DIR"); do
+        i=$BASH_COMPLETION_DIR/$i
+        [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)|Makefile*) \
+            && -f $i && -r $i ]] && . "$i"
+    done
+fi
+unset i
+
+# source user completion file
+[[ $BASH_COMPLETION != ~/.bash_completion && -r ~/.bash_completion ]] \
+    && . ~/.bash_completion
+unset -f have
+unset UNAME USERLAND have
+
+set $BASH_COMPLETION_ORIGINAL_V_VALUE
+unset BASH_COMPLETION_ORIGINAL_V_VALUE
+
+# Local variables:
+# mode: shell-script
+# sh-basic-offset: 4
+# sh-indent-comment: t
+# indent-tabs-mode: nil
+# End:
+# ex: ts=4 sw=4 et filetype=sh
 export FLEX_HOME="/Applications/eclipse/Adobe Flex Builder 3 Plug-in/sdks/3.5/"
-export PATH="/Users/wolever/.vcslog/bin:/Users/wolever/bin:/usr/local/vim73/bin/:/usr/local/bin:/usr/local/sbin:/Developer/usr/bin/:$PATH:$FLEX_HOME/bin:/usr/local/python32/bin/:/usr/local/python26/bin/:/usr/local/google_appengine/:/usr/local/mysql-5.5.19-osx10.6-x86_64/bin/"
+export CLOSURE_HOME="/Users/wolever/code/software/closure-library/closure/"
+export PATH="/Users/wolever/.vcslog/bin:/Users/wolever/bin:/usr/local/vim73/bin/:/usr/local/bin:/usr/local/sbin:/Developer/usr/bin/:$PATH:$FLEX_HOME/bin:/usr/local/python32/bin/:/usr/local/google_appengine/:/usr/local/mysql-5.5.19-osx10.6-x86_64/bin/:$CLOSURE_HOME/bin/:$CLOSURE_HOME/bin/build/"
 export MANPATH=/opt/local/share/man:$MANPATH
 export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.flac=01;35:*.mp3=01;35:*.mpc=01;35:*.ogg=01;35:*.wav=01;35:'
 export CDPATH="$CDPATH:~/EnSi/repos/:~/Verso/repos/"
 export DYLD_LIBRARY_PATH="/usr/local/mysql-5.5.19-osx10.6-x86_64/lib/"
 
 # Load macports bash completion
-. /usr/local/etc/bash_completion
+. ~/.config/bash_completion
 
 # An amusing prompt... For now :)
 # export PS1='C:${PWD//\//\\\}>'
 alias airssh='ssh -vp 4855 localhost'
 alias ut='dtrx'
 
-DJ_BASH_COMP=~/.config/django_bash_completion
-test -r $DJ_BASH_COMP && . $DJ_BASH_COMP
+#DJ_BASH_COMP=~/.config/django_bash_completion
+#test -r $DJ_BASH_COMP && . $DJ_BASH_COMP
 
 #export PYTHONPATH=/Users/wolever/code/software/hg-stable
 
 let g:netrw_dirhistmax  =10
-let g:netrw_dirhist_cnt =1
+let g:netrw_dirhist_cnt =6
 let g:netrw_dirhist_1='/Users/wolever/EnSi/repos/remora/libs/require-1.0.2'
+let g:netrw_dirhist_2='/Users/wolever/EnSi/repos/web/apps/main/fixtures'
+let g:netrw_dirhist_3='/Users/wolever/EnSi/repos/remora/test'
+let g:netrw_dirhist_4='/Users/wolever/codekills/posts'
+let g:netrw_dirhist_5='/Users/wolever/EnSi/repos/remora/src/remora'
+let g:netrw_dirhist_6='/Users/wolever/EnSi/repos/env/ensi/lib/python2.6/site-packages/django'

vim/after/syntax/remora.vim

+/Users/wolever/EnSi/repos/remora/extra/remora.vim
+" -*- vim -*-
+" vim:sts=2:sw=2:ff=unix:
+" FILE: "/home/benji/.vim/plugin/foo.vim"
+" URL:  http://www.vim.org/script.php?script_id=72
+" LAST MODIFICATION: "November 30, 2005"
+" (C) 2000-2005 by Benji Fisher, <benji@member.AMS.org>
+
+" This file contains relatively short functions and a few commands and
+" mappings for vim.  Many of these were written in response to questions
+" posted on the vim mailing list.  As a result (if I do say so myself)
+" there are a lot of clever ideas in this file.
+"
+" The examples are organized chronologically, which means that the ones near
+" the beginning are not necessarily the best ones to start with.  I hope the
+" following table of contents will help.  If you see something that looks
+" interesting, position the cursor on the function name and use the * command.
+" (Most of my examples involve functions; some also involve maps, commands,
+" autocommands, etc.)
+
+" Some of this file was written for vim 5.x, so several things could be
+" simplified with new features of vim 6.0, such as :map <local> and
+" :map <silent>.
+
+" *** Table of Contents ***
+
+" Configuration:  normally closer to the top of the file, but right after the
+" ToC in this file.
+
+" fun! DoSp(str)
+"   Purpose:  interpret special characters, such as <C-U>, in a string.
+"   Techniques:  argument syntax, substitute() function
+" fun! EvalInput(string)
+"   Purpose:  Same as DoSp()
+"   Techniques:  scratch buffer, :normal with control characters, @"
+" fun! HTMLmatch()
+"   Purpose:  Find matching HTML tags (baby version of matchit.vim)
+"   Techniques:  :if ... :endif, character under the cursor
+" fun! ClassHeader(leader)
+"   Purpose:  Insert a fancy comment line whenever a C++ class is started.
+"   Techniques:  :autocmd, :imap, :normal with control characters
+" command! -nargs=* Line
+" command! -nargs=* Range
+"   Purpose:  Use one or two variables to give a line or range to a command.
+"   Techniques:  :command, <q-args>, substitute(), :execute
+" fun! Mark(...)
+" fun! Line(mark)
+" fun! Virtcol(mark)
+"   Purpose:  Use (local) variables to store marks, restore cursor and screen.
+"   Techniques:  variable number of arguments, parsing with =~, substitute()
+" fun! Pippo(...) range
+"   Purpose:  Append words matching a given pattern to a file.
+"   Techniques:  :function with a range, variable number of arguments, :copy
+" fun! LastNonBlank()
+"   Purpose:  Move the cursor to the last non-blank on the line; ^ in reverse.
+"   Techniques:  matchend(), positioning the cursor with :normal
+" fun! StripTag(pattern)
+"   Purpose:  Tag search on "foo" if the current word is "xxxfoo".
+"   Techniques:  expand(), <cword>, =~, :normal with control characters
+" fun! JS_template()
+"   Purpose:  Insert a JavaScript template at the magic string "<scr"
+"   Techniques:  :autocmd, mode switching, :append
+" fun! LineUpLT()
+"   Purpose:  Automatically align C++ << operators.
+"   Techniques:  :autocmd, mode switching, manually adjusting indent
+" fun! Count(pat)
+"   Purpose:  Count the number of lines matching the input pattern.
+"   Techniques:  :g, returning a value, :execute
+" fun! ShowHi()
+"   Purpose:  Show the colors of all highlight groups.
+"	Oops, we reinvented the wheel!  See $VIMRUNTIME/syntax/hitest.vim .
+"   Techniques:  saving and restoring an option, scratch buffer, :redir, etc.
+" fun! EditFun(name)
+"   Purpose:  Edit a vim function in a scratch buffer.
+"   Techniques:  pretty much the same as ShowHi()
+" fun! GetModelines(pat, ...)
+"   Purpose:  Get information stored in comments (modelines) in the buffer.
+"   Techniques:  variable number of arguments, :silent (vim 6.0), complex :g
+" fun! VarTab(c, ...)
+"   Purpose:  Define tab stops at arbitrarily spaced columns.
+"   Techniques:  getting the value of a function without leaving Insert mode,
+"     looping over variable number of arguments
+" fun! SmartBS(pat)
+"   Purpose:  Delete HTML constructs like "&foo;" as a single character.
+"   Techniques:  Insert-mode mapping that works at start, middle, end of line
+" fun! Transform(old, new, ...)
+"   Purpose:  Perform multiple simple substitutions.
+"   Techniques:  :while loop, getline() and setline()
+" fun! Search(pat)
+"   Purpose:  Search for a pattern and select it in Select mode.
+"   Techniques:  :command, :execute, mode switching
+" fun! Capitalize()
+"   Purpose:  Make "_" act like a Caps Lock key in Insert mode.
+"   Techniques:  store a flag as a buffer variable, mode switching
+" inoremap <LeftMouse>
+"   Purpose:  Keep mode (Insert or Normal) attached to a window.
+"   Techniques:  window variables, Command mode inside a mapping
+" command! Echo
+"   Purpose:  Echo a command, then execute it.  Useful for making a log of
+"   your Command-mode session.
+" command! Iabbr
+"   Purpose:  Define an Insert-mode abbreviation that "eats" the space that
+"   triggers it.
+" fun! Getchar()
+"   Purpose:  like getchar() but always return a String.  Used by
+"   Eatchar() and GetMotion().
+"   Techniques:  getchar(), nr2char()
+" fun! Eatchar(pat)
+"   Purpose:  This is a helper function for :Iabbr .
+" fun! Yank()
+"   Purpose:  Example for using GetMotion() to remap an operator.
+" fun! GetMotion(char)
+"   Purpose:  Capture a sequence of characters that define a motion.  This is
+"   useful when redefining operators, such as y (yank).
+"   Techniques:  getchar(), while
+" fun! Common(str1, str2)
+"   Purpose:  Return the common initial part of two strings.
+"   Techniques:  matchend(), strpart(), while
+" fun! TWIN()
+"   Purpose:  Prompt for input, and insert something in the file.
+"   Techniques:  input(), append(), :normal, switching modes.
+" vmap i"   and also i', a", and a'
+"   Purpose:  implement some new text objects.
+"   Techniques:  search offsets and some useful Visual-mode commands.
+" fun! SetPersistentString(name, value)
+" fun! SetPersistentNumber(name, value)
+"   Purpose:  Save script variables in the file, to make them persistent.
+"   Techniques:  expand(), <sfile>, search(), setline(), getline()
+" fun! GCD(a, b)
+"   Techniques:  An example of a recursive algorithm.
+" function! RepeatString(count, ...)
+"   Purpose:  Repeat the optional argument to get a string of length a:count . 
+" function! InvertString(str)
+"   Courtesy of Preben "Peppe" Guldberg
+"   Techniques:  It can be used with :s/.../\= . 
+" function! MyMarks(action)
+"   Purpose:  Store and read marks in a special file.
+"   Techniques:  getline(), setline(), search(), ...
+" function! s:SID()
+" function! FooSID()
+"   Purpose:  implement a hack to expose the script ID.
+
+" *** User Configuration ***
+
+" Normally, a file that (like this one) contains only a few configuration
+" items suggests that the user set them (if (s)he wants to change the
+" defaults) in the vimrc file.  The method illustrated here is appropriate for
+" complicated plugins or packages with a large number of user options.  Note
+" that the use of :runtime! allows for the usual vim rules for overriding
+" options, so the system administrator can set system defaults (overriding the
+" plugin defaults) and the user can override those with an after/ directory.
+" See :help ftplugin-overrule for details.
+"
+" This vim plugin does many amazing and wondrous things, but you may prefer to
+" change some of the defaults.  Copy the following section to a file foo.vimrc
+" in your plugin directory, normally the same directory as this file.  If your
+" system administrator has installed this file, you should install foo.vimrc
+" in your after/plugin/ directory so that your choices override the system
+" defaults.  See
+"   :help ftplugin-overrule
+"   :help 'runtimepath'
+" for details.
+" ==================== file foo.vimrc ====================
+" User Configuration file for foo.vim .
+let g:foo_DefineAutoCommands = 0  " default 0, do not define autocommands.
+let g:foo_DefineCommands = 1  " default 1, define ex commands.
+let g:foo_DefineAllMaps = 0  " default 0, do not define all maps.
+" The following defaults will only be used if g:foo_DefineAllMaps is set.
+" For another way to let the user specify key bindings, see
+"   :help write-plugin
+let g:fooLNBchar = ''	" key mapping for LastNonBlank(), default '<M-4>'.
+let g:fooStripTagChar = ''  " key for StripTag(), default '<C-]>'.
+let g:fooVarTabChar = ''	" key for VarTab(), default '<Tab>'
+let g:fooMapUnderscore = 0  " default 0, do not map _ .
+let g:fooMapMouse = 0  " default 0, do not map <LeftMouse> and <RightMouse> .
+let g:fooTWINChar = ''	" key for TWIN(), default '<F4>' .
+let g:fooTextObjects = 1  " default 1, define new text objects.
+" ==================== end: foo.vimrc ====================
+
+" source the user configuration file(s):
+runtime! plugin/<sfile>:t:r.vimrc
+
+" *** End of User Configuration ***
+
+" Since I experiment a lot with this file, I want to avoid having
+" duplicate autocommands.
+augroup Foo
+  autocmd!
+augroup END
+
+" This is the beginning of a function for taking an input string and
+" returning the value after "special characters" have been evaluated:
+" <C-U> erases all previous input.  One might also want to implement
+" <C-W> and others.
+fun! DoSp(str)
+  let s = substitute(a:str, '.*\<C-U>', "", "")
+  return s
+endfun
+
+" This function evaluates the input string in Input mode.  Special
+" characters, such as <C-U> and <C-N> will be executed in Input mode.
+" Raw <Esc> characters will produce unpredictable results.
+fun! EvalInput(string)
+  new
+  execute "normal a" . a:string . "\<Esc>ggyG"
+  q!
+  return @"
+endfun
+
+" Use with  :nmap % :call HTMLmatch()
+" If the cursor is on a non-alphabetic character then invoke the normal
+" behavior of %.  If the cursor is on an alphabetic character, attempt to
+" jump from <tag> to </tag> and back.  This is just a quick demo; it does
+" not deal with nesting.  For a more complete version, see matchit.vim .
+fun! HTMLmatch()
+  if getline(".")[col(".")-1] !~ "\\a"
+    normal! %
+    return
+  endif
+  execute "normal ?\\A\<CR>"
+  normal lye
+  if getline(".")[col(".")-2] == '/'
+    execute 'normal ?<\s*' . @" . "\<CR>l"
+  else
+    execute 'normal /<\s*\/' . @" . "\<CR>ll"
+  endif
+endfun
+
+" Insert a header every time you begin a new class in C++ .
+if g:foo_DefineAutoCommands
+augroup Foo
+  autocmd BufEnter *.cpp,*.h inoremap { {<Esc>:call ClassHeader("-")<CR>a
+  autocmd BufLeave *.cpp,*.h iunmap {
+  " Keep your braces balanced!}}}
+augroup END
+endif " g:foo_DefineAutoCommands
+fun! ClassHeader(leader)
+  if getline(".") !~ "^\\s*class"
+    return
+  endif
+  normal yyP$x
+  let width = 80
+  if exists("&tw")
+    let width = &tw
+  endif
+  execute "normal " . (width-virtcol(".")-3) . "I" . a:leader . "\<Esc>"
+  execute "normal a \<Esc>"
+  execute "normal I//\<Esc>"
+  " Keep your braces balanced!{
+  execute "normal! jo};\<Esc>"
+  normal k$
+endfun
+
+" This is my first user-defined command.  Unlike a user-defined function,
+" a command can be called from the function Foo() and have access to the
+" local variables of Foo().
+" Usage:  :let foo = 1 | Line foo s/foo/bar
+" Usage:  :let foo = 1 | let bar = 3 | Line foo,bar s/foo/bar
+" You can also do ":Line foo+1 s/foo/bar" or "Line foo-1,bar+1 ..."
+" There must be no spaces in "foo,bar".
+command! -nargs=* Line
+	\ | let Line_range = matchstr(<q-args>, '\S\+')
+	\ | let Line_range = "(" . substitute(Line_range, ",", ").','.(", "") . ")"
+	\ | execute "let Line_range = " . Line_range
+	\ | execute Line_range . substitute(<q-args>, '\S\+', "", "")
+	\ | unlet Line_range
+" Example:  If foo=2 and bar=3 and you do ":Line foo-1,bar+1 s/foo/bar" then
+" 1. Line_range = "foo-1,bar+1"
+" 2. Line_range = "(foo-1).','.(bar+1)"
+" If there is no comma then this step has no effect.
+" 3. Line_range = "1,4"
+" 4. 1,4 s/foo/bar
+
+" Usage:  :let foo = 1 | let bar = 3 | Range foo bar s/foo/bar
+command! -nargs=* Range
+	\ | execute substitute(<q-args>, '\(\S\+\)\s\+\(\S\+\)\(.*\)',
+		\ 'let Range_range=\1.",".\2', "")
+	\ | execute Range_range . substitute(<q-args>, '\S\+\s\+\S\+', "", "")
+	\ | unlet Range_range
+
+" Usage:  :let ma = Mark() ... execute ma
+" has the same effect as  :normal ma ... :normal 'a
+" without affecting global marks.
+" You can also use Mark(17) to refer to the start of line 17 and Mark(17,34)
+" to refer to the 34'th (screen) column of the line 17.  The functions
+" Line() and Virtcol() extract the line or (screen) column from a "mark"
+" constructed from Mark() and default to line() and virtcol() if they do not
+" recognize the pattern.
+" Update:  :execute Mark() now restores screen position as well as the cursor.
+fun! Mark(...)
+  if a:0 == 0
+    let mark = line(".") . "G" . virtcol(".") . "|"
+    normal! H
+    let mark = "normal!" . line(".") . "Gzt" . mark
+    execute mark
+    return mark
+  elseif a:0 == 1
+    return "normal!" . a:1 . "G1|"
+  else
+    return "normal!" . a:1 . "G" . a:2 . "|"
+  endif
+endfun
+
+" See comments above Mark()
+fun! Line(mark)
+  if a:mark =~ '\dG\d\+|$'
+    return substitute(a:mark, '.\{-}\(\d\+\)G\d\+|$', '\1', "")
+  else
+    return line(a:mark)
+  endif
+endfun
+
+" See comments above Mark()
+fun! Virtcol(mark)
+  if a:mark =~ '\d\+G\d\+|$'
+    return substitute(a:mark, '.*G\(\d\+\)|$', '\1', "")
+  else
+    return col(a:mark)
+  endif
+endfun
+
+" Usage:  If the file contains lines like
+" let pippo1 = pippo12
+" I like pippo2
+" then :%call Pippo()<CR> will append lines
+" pippo1
+" pippo12
+" pippo2
+" to the end of the file.
+" I do not know what the original requester had in mind, but this could be
+" useful for generating dictionaries.  For example, for LaTeX, try
+" :%call Pippo('\\\a\+') and then sort the resulting lines.
+fun! Pippo(...) range
+  if a:0
+    let pat = a:1
+  else
+    let pat = '\<pippo\d\+\>'
+  endif
+  let bot = line("$")
+  execute a:firstline . "," . a:lastline . 'g/' . pat . '/copy $'
+  if bot == line("$")
+    return
+  endif
+  execute (bot+1) . ',$s/' . pat . '/&\r/ge'
+  execute (bot+1) . ',$v/' . pat . '/d'
+  execute (bot+1) . ',$s/.\{-}\(' . pat . '\)$/\1/e'
+endfun
+
+" <S-4> or $ takes you to the last character of the line; this takes you
+" to the last non-blank character of the line.
+if strlen(g:fooLNBchar)
+  execute "map" g:fooLNBchar "<Plug>fooLNB"
+elseif g:foo_DefineAllMaps && !hasmapto('<Plug>fooLNB')
+  map <M-4> <Plug>fooLNB
+endif
+map <Plug>fooLNB 0/.*\S/e<CR>:let @/=histget("/", -2)<CR>
+" Here is another way to do it.  I use a function for legibility and for the
+" sake of a local variable.
+map <Plug>fooLNB :call LastNonBlank()<CR>
+fun! LastNonBlank()
+  let i = matchend(getline("."), '.*\S')-1
+  if i > 0
+    execute "normal!0" . i . "l"
+  elseif i == 0
+    execute normal! 0
+  endif
+endfun
+
+" Strip off a pattern from a keyword and jump to the tag.
+if strlen(g:fooStripTagChar)
+  execute "map" g:fooStripTagChar "<Plug>fooStripTag"
+elseif g:foo_DefineAllMaps && !hasmapto('<Plug>fooStripTag')
+  map <C-]> <Plug>fooStripTag
+endif
+nmap <Plug>fooStripTag :call StripTag("xxx")<CR>
+fun! StripTag(pattern)
+  let keyword = expand("<cword>")
+  if keyword =~ '^' . a:pattern
+    execute "tag!" . substitute(keyword, a:pattern, "", "")
+  else
+    execute "normal! \<C-]>"
+  endif
+endfun
+
+" These autocommands and function insert a template every time you
+" type "<scr" at the end of a line in a *.jsp file.
+if g:foo_DefineAutoCommands
+augroup Foo
+  autocmd BufEnter *.jsp imap r r<Esc>:call JS_template()<CR>a
+  autocmd BufLeave *.jsp iunmap r
+augroup END
+endif " g:foo_DefineAutoCommands
+fun! JS_template()
+  if getline(".") !~ '<scr$'
+    return
+  endif
+  s/scr$/script language="JavaScript">/
+  append
+  function foo() {
+      alert("Hello, world.");
+    }
+  </script>
+
+.
+endfun
+
+"The following autocommand and function align C++ style << characters.
+if g:foo_DefineAutoCommands
+augroup Foo
+  autocmd BufEnter *.cpp imap < <<C-O>:call LineUpLT()<CR>
+  autocmd BufLeave *.cpp iunmap <
+augroup END
+endif " g:foo_DefineAutoCommands
+fun! LineUpLT()
+  if line(".") == 1 || getline(".") !~ '^\s*<<$'
+    return
+  endif
+  let newline = getline(line(".")-1)
+  let col = match(newline, "<<")
+  if col != -1
+    let newline = strpart(newline, 0, col)
+    let newline = substitute(newline, '\S', " ", "g") . "<<"
+    call setline(line("."), newline)
+    normal!$
+  endif
+endfun
+
+fun! Count(pat)
+  let num = 0
+  execute 'g/' . a:pat . '/let num = num + 1'
+  return num
+endfun
+
+" A joint effort with Douglas Potts.
+" Show the colors of all highlight groups.