bin/warp-dir.bash
#!/usr/bin/env bash
# vim: ft=bash
#
# WarpDir (v1.7.0) shell wrapper, installed by a gem 'warp-dir'
#
# © 2012-2011, Konstantin Gredeskoul
#
# https://github.com/kigster/warp-dir
#
# shellcheck disable=SC2207,SC2206,SC2059
declare -a wd_commands
declare -a wd_short_flags
declare -a wd_long_flags
declare -a wd_default_dotfiles
declare wd_temp
export wd_commands=(add ls remove warp install help list)
export wd_default_dotfiles=(~/.bash_profile ~/.bashrc ~/.bash_login ~/.profile ~/.zshrc)
function _wd::init() {
# shellcheck disable=SC2155
export wd_temp="$(mktemp)"
rm -f "${wd_temp}" && touch "${wd_temp}"
[[ ${#wd_long_flags[@]} -gt 0 ]] && return
command -v warp-dir >/dev/null && {
export wd_long_flags=($(warp-dir --help | awk 'BEGIN{FS="--"}{print "--" $2}' | sed -E '/^--$/d' | grep -E -v ']|help' | grep -E -- "${cur}" | awk '{if ($1 != "") { printf "%s\n", $1} } '))
export wd_short_flags=($(warp-dir --help | grep -E -- '-[a-z], --' | cut -d '-' -f 2 | tr -d ',' | sed 's/^/-/g'))
}
}
function _wd::debug() {
printf "%-20s: %s\n" "long0 flags" "$(echo "${wd_long_flags[*]}" | tr '\n' ' ')"
printf "%-20s: %s\n" "short flags" "$(echo "${wd_short_flags[*]}" | tr '\n' ' ')"
printf "%-20s: %s\n" "commands" "$(echo "${wd_commands[*]}" | tr '\n' ' ')"
printf "%-20s: %s\n" "points" "$(_wd::current-points | tr '\n' ' ')"
}
function _wd::current-points() {
warp-dir list --no-color | awk '{ print $1 }'
}
function _wd::err() {
printf "\n\e[7;31m ERROR ❯❯ \e[0;31m $*\e[0;0m\n" >&2
}
function _wd::info() {
printf "\n\e[7;34m INFO ❯❯ \e[0;35m $*\e[0;0m\n" >&2
}
function _wd::exec() {
export WARP_DIR_SHELL=yes
export RUBYOPT=W0
if type rbenv | grep -q function; then
rbenv exec warp-dir "$@" 2>/dev/null
else
warp-dir "$@" 2>/dev/null
fi
}
function _wd::not-found() {
_wd::err "Can't find 'warp-dir' executable!"
printf "
Is the gem properly installed?
Perhaps try reinstalling the gem as shown: \e[0;34m
gem install warp-dir --no-wrapper
warp-dir install --dotfile ~/.bash_profile
hash -r
wd -h\e[0;0m
"
}
function _wd::gem-install() {
local code
_wd::info "Ruby $(ruby --version) does not have warp-dir gem. Installing the missing gem..."
gem install -N --quiet --force --no-wrapper warp-dir >"${wd_temp}" 2>&1
code=$?
hash -r 2>/dev/null
if [[ ${code} -eq 0 ]]; then
_wd::info "Installation was successful, warp-dir executable is now at:"
_wd::info "\e[1;32m$(which warp-dir)"
_wd::init
else
_wd::err "Install failed, exit code=${code}\n"
[[ -s "${wd_temp}" ]] && {
printf "\e[1;31m"
cat "${wd_temp}"
printf "\e[0;0m"
}
return 1
fi
}
function wd() {
if [[ "$1" == "--comp-debug" ]]; then
_wd::debug
return
fi
_wd::init
command -v warp-dir >/dev/null || {
hash -r 2>/dev/null
if [[ -z $(which warp-dir) ]]; then
_wd::gem-install || return 1
fi
}
command -v warp-dir >/dev/null || {
_wd::err "Can't find warp-dir executable in the PATH" && return 1
}
local previous_ifs=$IFS
IFS="+"
local output
set +e
output="$(_wd::exec "$@")"
local code=$?
((DEBUG)) && printf "DEBUG OUTPUT: [%s]" "${output}"
if [[ $code -eq 127 ]]; then
[[ -n $(command -v rbenv) ]] && {
_wd::gem-install || {
export IFS="${previous_ifs}"
return 1
}
rbenv rehash >/dev/null 2>&1
}
output="$(_wd::exec "$@")"
code=$?
if [[ $code -eq 127 ]]; then
_wd::not-found
export IFS="${previous_ifs}"
return 1
fi
fi
if [[ "${output}" =~ (cd |printf ) ]]; then
eval "${output}"
code=$?
else
printf "%s\n" "${output}"
code=0
fi
export IFS="${previous_ifs}"
return "${code}"
}
# @description Command Completion
#
# COMP_WORDS: an array of all the words typed after the name of the program
# the compspec belongs to
#
# COMP_CWORD: an index of the COMP_WORDS array pointing to the word the current
# cursor is at—in other words, the index of the word the cursor was
# when the tab key was pressed
#
# COMP_LINE: the current command line
#
# suggestions: The contents of the suggestions variable are
# always displayed. The function is now
# responsible for adding or removing entries from
# there. If the suggestions variable had only one
# element, then that word would be automatically
# completed in the command.
#
# Enter compgen: builtin command that generates completions
# supporting most of the options of the complete command
# generator (ex. -W for word list, -d for directories) and
# filtering them based on what the user has already typed.
function _wd_completions() {
_wd::init
if [[ "${#COMP_WORDS[@]}" -lt 2 ]]; then
return
fi
local -a wd_points=($(_wd::current-points))
local -a suggestions=()
local cur="${COMP_WORDS[${COMP_CWORD}]}"
local prev="${COMP_WORDS[$((COMP_CWORD - 1))]}"
if [[ ${cur} == --* ]]; then
suggestions+=(${wd_long_flags[@]})
elif [[ ${cur} == -* ]]; then
suggestions+=(${wd_short_flags[@]})
elif [[ ${COMP_CWORD} -gt 1 ]]; then
suggestions+=(${wd_short_flags[@]})
suggestions+=(${wd_long_flags[@]})
else
suggestions+=(${wd_points[@]})
suggestions+=(${wd_commands[@]})
fi
suggestions=($(compgen -W "${suggestions[*]}" -- "${cur}"))
if [[ "${prev}" == wd ]]; then
suggestions+=($(compgen -d -- "${cur}"))
elif [[ "${prev}" == "--dotfile" ]]; then
local -a inits
for file in "${wd_default_dotfiles[@]}"; do
[[ -s "${file}" ]] && inits+=("${file}")
done
case "${cur}" in
[a-z]*)
cur="${HOME}/.${cur}"
;;
.[a-z]*)
cur="${HOME}/${cur}"
;;
esac
suggestions=($(compgen -W "${inits[*]}" -- "${cur}"))
fi
if [[ "${#suggestions[@]}" -eq 1 ]]; then
COMPREPLY=("${suggestions[0]}")
else
COMPREPLY=(${suggestions[@]})
fi
}
complete -F _wd_completions wd