819 lines
23 KiB
Bash
819 lines
23 KiB
Bash
|
#!/usr/bin/env bash
|
||
|
|
||
|
BASH_IT_LOAD_PRIORITY_DEFAULT_ALIAS=${BASH_IT_LOAD_PRIORITY_DEFAULT_ALIAS:-150}
|
||
|
BASH_IT_LOAD_PRIORITY_DEFAULT_PLUGIN=${BASH_IT_LOAD_PRIORITY_DEFAULT_PLUGIN:-250}
|
||
|
BASH_IT_LOAD_PRIORITY_DEFAULT_COMPLETION=${BASH_IT_LOAD_PRIORITY_DEFAULT_COMPLETION:-350}
|
||
|
BASH_IT_LOAD_PRIORITY_SEPARATOR="---"
|
||
|
|
||
|
# Handle the different ways of running `sed` without generating a backup file based on OS
|
||
|
# - GNU sed (Linux) uses `-i`
|
||
|
# - BSD sed (macOS) uses `-i ''`
|
||
|
# To use this in Bash-it for inline replacements with `sed`, use the following syntax:
|
||
|
# sed "${BASH_IT_SED_I_PARAMETERS[@]}" -e "..." file
|
||
|
BASH_IT_SED_I_PARAMETERS=(-i)
|
||
|
case "$(uname)" in
|
||
|
Darwin*) BASH_IT_SED_I_PARAMETERS=(-i "")
|
||
|
esac
|
||
|
|
||
|
function _command_exists ()
|
||
|
{
|
||
|
_about 'checks for existence of a command'
|
||
|
_param '1: command to check'
|
||
|
_param '2: (optional) log message to include when command not found'
|
||
|
_example '$ _command_exists ls && echo exists'
|
||
|
_group 'lib'
|
||
|
local msg="${2:-Command '$1' does not exist!}"
|
||
|
type "$1" &> /dev/null || (_log_warning "$msg" && return 1) ;
|
||
|
}
|
||
|
|
||
|
function _binary_exists ()
|
||
|
{
|
||
|
_about 'checks for existence of a binary'
|
||
|
_param '1: binary to check'
|
||
|
_param '2: (optional) log message to include when binary not found'
|
||
|
_example '$ _binary_exists ls && echo exists'
|
||
|
_group 'lib'
|
||
|
local msg="${2:-Binary '$1' does not exist!}"
|
||
|
type -P "$1" &> /dev/null || (_log_warning "$msg" && return 1) ;
|
||
|
}
|
||
|
|
||
|
function _completion_exists ()
|
||
|
{
|
||
|
_about 'checks for existence of a completion'
|
||
|
_param '1: command to check'
|
||
|
_param '2: (optional) log message to include when completion is found'
|
||
|
_example '$ _completion_exists gh && echo exists'
|
||
|
_group 'lib'
|
||
|
local msg="${2:-Completion for '$1' already exists!}"
|
||
|
complete -p "$1" &> /dev/null && _log_warning "$msg" ;
|
||
|
}
|
||
|
|
||
|
function _make_reload_alias() {
|
||
|
echo "source \${BASH_IT}/scripts/reloader.bash ${1} ${2}"
|
||
|
}
|
||
|
|
||
|
# Alias for reloading aliases
|
||
|
# shellcheck disable=SC2139
|
||
|
alias reload_aliases="$(_make_reload_alias alias aliases)"
|
||
|
|
||
|
# Alias for reloading auto-completion
|
||
|
# shellcheck disable=SC2139
|
||
|
alias reload_completion="$(_make_reload_alias completion completion)"
|
||
|
|
||
|
# Alias for reloading plugins
|
||
|
# shellcheck disable=SC2139
|
||
|
alias reload_plugins="$(_make_reload_alias plugin plugins)"
|
||
|
|
||
|
bash-it ()
|
||
|
{
|
||
|
about 'Bash-it help and maintenance'
|
||
|
param '1: verb [one of: help | show | enable | disable | migrate | update | search | version | reload | restart | doctor ] '
|
||
|
param '2: component type [one of: alias(es) | completion(s) | plugin(s) ] or search term(s)'
|
||
|
param '3: specific component [optional]'
|
||
|
example '$ bash-it show plugins'
|
||
|
example '$ bash-it help aliases'
|
||
|
example '$ bash-it enable plugin git [tmux]...'
|
||
|
example '$ bash-it disable alias hg [tmux]...'
|
||
|
example '$ bash-it migrate'
|
||
|
example '$ bash-it update'
|
||
|
example '$ bash-it search [-|@]term1 [-|@]term2 ... [ -e/--enable ] [ -d/--disable ] [ -r/--refresh ] [ -c/--no-color ]'
|
||
|
example '$ bash-it version'
|
||
|
example '$ bash-it reload'
|
||
|
example '$ bash-it restart'
|
||
|
example '$ bash-it doctor errors|warnings|all'
|
||
|
typeset verb=${1:-}
|
||
|
shift
|
||
|
typeset component=${1:-}
|
||
|
shift
|
||
|
typeset func
|
||
|
|
||
|
case $verb in
|
||
|
show)
|
||
|
func=_bash-it-$component;;
|
||
|
enable)
|
||
|
func=_enable-$component;;
|
||
|
disable)
|
||
|
func=_disable-$component;;
|
||
|
help)
|
||
|
func=_help-$component;;
|
||
|
doctor)
|
||
|
func=_bash-it-doctor-$component;;
|
||
|
search)
|
||
|
_bash-it-search $component "$@"
|
||
|
return;;
|
||
|
update)
|
||
|
func=_bash-it-update-$component;;
|
||
|
migrate)
|
||
|
func=_bash-it-migrate;;
|
||
|
version)
|
||
|
func=_bash-it-version;;
|
||
|
restart)
|
||
|
func=_bash-it-restart;;
|
||
|
reload)
|
||
|
func=_bash-it-reload;;
|
||
|
*)
|
||
|
reference bash-it
|
||
|
return;;
|
||
|
esac
|
||
|
|
||
|
# pluralize component if necessary
|
||
|
if ! _is_function $func; then
|
||
|
if _is_function ${func}s; then
|
||
|
func=${func}s
|
||
|
else
|
||
|
if _is_function ${func}es; then
|
||
|
func=${func}es
|
||
|
else
|
||
|
echo "oops! $component is not a valid option!"
|
||
|
reference bash-it
|
||
|
return
|
||
|
fi
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if [ x"$verb" == x"enable" ] || [ x"$verb" == x"disable" ]; then
|
||
|
# Automatically run a migration if required
|
||
|
_bash-it-migrate
|
||
|
|
||
|
for arg in "$@"
|
||
|
do
|
||
|
$func $arg
|
||
|
done
|
||
|
|
||
|
if [ -n "$BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE" ]; then
|
||
|
_bash-it-reload
|
||
|
fi
|
||
|
else
|
||
|
$func "$@"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
_is_function ()
|
||
|
{
|
||
|
_about 'sets $? to true if parameter is the name of a function'
|
||
|
_param '1: name of alleged function'
|
||
|
_group 'lib'
|
||
|
[ -n "$(LANG=C type -t $1 2>/dev/null | grep 'function')" ]
|
||
|
}
|
||
|
|
||
|
_bash-it-aliases ()
|
||
|
{
|
||
|
_about 'summarizes available bash_it aliases'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-describe "aliases" "an" "alias" "Alias"
|
||
|
}
|
||
|
|
||
|
_bash-it-completions ()
|
||
|
{
|
||
|
_about 'summarizes available bash_it completions'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-describe "completion" "a" "completion" "Completion"
|
||
|
}
|
||
|
|
||
|
_bash-it-plugins ()
|
||
|
{
|
||
|
_about 'summarizes available bash_it plugins'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-describe "plugins" "a" "plugin" "Plugin"
|
||
|
}
|
||
|
|
||
|
_bash-it-update-dev() {
|
||
|
_about 'updates Bash-it to the latest master'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-update- dev "$@"
|
||
|
}
|
||
|
|
||
|
_bash-it-update-stable() {
|
||
|
_about 'updates Bash-it to the latest tag'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-update- stable "$@"
|
||
|
}
|
||
|
|
||
|
_bash-it_pull_and_update_inner() {
|
||
|
git checkout "$1" &> /dev/null
|
||
|
if [[ $? -eq 0 ]]; then
|
||
|
echo "Bash-it successfully updated."
|
||
|
echo ""
|
||
|
echo "Migrating your installation to the latest $2 version now..."
|
||
|
_bash-it-migrate
|
||
|
echo ""
|
||
|
echo "All done, enjoy!"
|
||
|
bash-it restart
|
||
|
else
|
||
|
echo "Error updating Bash-it, please, check if your Bash-it installation folder (${BASH_IT}) is clean."
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
_bash-it-update-() {
|
||
|
_about 'updates Bash-it'
|
||
|
_param '1: What kind of update to do (stable|dev)'
|
||
|
_group 'lib'
|
||
|
|
||
|
declare silent
|
||
|
for word in $@; do
|
||
|
if [[ ${word} == "--silent" || ${word} == "-s" ]]; then
|
||
|
silent=true
|
||
|
fi
|
||
|
done
|
||
|
local old_pwd="${PWD}"
|
||
|
|
||
|
cd "${BASH_IT}" || return
|
||
|
|
||
|
DIFF=$(git diff --name-status)
|
||
|
[ -n "$DIFF" ] && echo -e "Local changes detected in bash-it directory. Clean '$BASH_IT' directory to proceed.\n$DIFF" && return 1
|
||
|
|
||
|
if [ -z "$BASH_IT_REMOTE" ]; then
|
||
|
BASH_IT_REMOTE="origin"
|
||
|
fi
|
||
|
|
||
|
git fetch $BASH_IT_REMOTE --tags &> /dev/null
|
||
|
|
||
|
if [ -z "$BASH_IT_DEVELOPMENT_BRANCH" ]; then
|
||
|
BASH_IT_DEVELOPMENT_BRANCH="master"
|
||
|
fi
|
||
|
# Defaults to stable update
|
||
|
if [ -z "$1" ] || [ "$1" == "stable" ]; then
|
||
|
version="stable"
|
||
|
TARGET=$(git describe --tags "$(git rev-list --tags --max-count=1)" 2> /dev/null)
|
||
|
|
||
|
if [[ -z "$TARGET" ]]; then
|
||
|
echo "Can not find tags, so can not update to latest stable version..."
|
||
|
return
|
||
|
fi
|
||
|
else
|
||
|
version="dev"
|
||
|
TARGET=${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}
|
||
|
fi
|
||
|
|
||
|
declare revision
|
||
|
revision="HEAD..${TARGET}"
|
||
|
declare status
|
||
|
status="$(git rev-list ${revision} 2> /dev/null)"
|
||
|
declare revert
|
||
|
|
||
|
if [[ -z "${status}" && ${version} == "stable" ]]; then
|
||
|
revision="${TARGET}..HEAD"
|
||
|
status="$(git rev-list ${revision} 2> /dev/null)"
|
||
|
revert=true
|
||
|
fi
|
||
|
|
||
|
if [[ -n "${status}" ]]; then
|
||
|
if [[ $revert ]]; then
|
||
|
echo "Your version is a more recent development version ($(git log -1 --format=%h HEAD))"
|
||
|
echo "You can continue in order to revert and update to the latest stable version"
|
||
|
echo ""
|
||
|
log_color="%Cred"
|
||
|
fi
|
||
|
|
||
|
for i in $(git rev-list --merges --first-parent ${revision}); do
|
||
|
num_of_lines=$(git log -1 --format=%B $i | awk 'NF' | wc -l)
|
||
|
if [ $num_of_lines -eq 1 ]; then
|
||
|
description="%s"
|
||
|
else
|
||
|
description="%b"
|
||
|
fi
|
||
|
git log --format="${log_color}%h: $description (%an)" -1 $i
|
||
|
done
|
||
|
echo ""
|
||
|
|
||
|
if [[ $silent ]]; then
|
||
|
echo "Updating to ${TARGET}($(git log -1 --format=%h "${TARGET}"))..."
|
||
|
_bash-it_pull_and_update_inner $TARGET $version
|
||
|
else
|
||
|
read -e -n 1 -p "Would you like to update to ${TARGET}($(git log -1 --format=%h "${TARGET}"))? [Y/n] " RESP
|
||
|
case $RESP in
|
||
|
[yY]|"")
|
||
|
_bash-it_pull_and_update_inner $TARGET $version
|
||
|
;;
|
||
|
[nN])
|
||
|
echo "Not updating…"
|
||
|
;;
|
||
|
*)
|
||
|
echo -e "\033[91mPlease choose y or n.\033[m"
|
||
|
;;
|
||
|
esac
|
||
|
fi
|
||
|
else
|
||
|
if [[ ${version} == "stable" ]]; then
|
||
|
echo "You're on the latest stable version. If you want to check out the latest 'dev' version, please run \"bash-it update dev\""
|
||
|
else
|
||
|
echo "Bash-it is up to date, nothing to do!"
|
||
|
fi
|
||
|
fi
|
||
|
cd "${old_pwd}" &> /dev/null || return
|
||
|
}
|
||
|
|
||
|
_bash-it-migrate() {
|
||
|
_about 'migrates Bash-it configuration from a previous format to the current one'
|
||
|
_group 'lib'
|
||
|
|
||
|
declare migrated_something
|
||
|
migrated_something=false
|
||
|
|
||
|
for file_type in "aliases" "plugins" "completion"
|
||
|
do
|
||
|
for f in `sort <(compgen -G "${BASH_IT}/$file_type/enabled/*.bash")`
|
||
|
do
|
||
|
typeset ff=$(basename $f)
|
||
|
|
||
|
# Get the type of component from the extension
|
||
|
typeset single_type=$(echo $ff | sed -e 's/.*\.\(.*\)\.bash/\1/g' | sed 's/aliases/alias/g')
|
||
|
# Cut off the optional "250---" prefix and the suffix
|
||
|
typeset component_name=$(echo $ff | sed -e 's/[0-9]*[-]*\(.*\)\..*\.bash/\1/g')
|
||
|
|
||
|
migrated_something=true
|
||
|
|
||
|
echo "Migrating $single_type $component_name."
|
||
|
|
||
|
disable_func="_disable-$single_type"
|
||
|
enable_func="_enable-$single_type"
|
||
|
|
||
|
$disable_func $component_name
|
||
|
$enable_func $component_name
|
||
|
done
|
||
|
done
|
||
|
|
||
|
if [ -n "$BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE" ]; then
|
||
|
_bash-it-reload
|
||
|
fi
|
||
|
|
||
|
if [ "$migrated_something" = "true" ]; then
|
||
|
echo ""
|
||
|
echo "If any migration errors were reported, please try the following: reload && bash-it migrate"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
_bash-it-version() {
|
||
|
_about 'shows current Bash-it version'
|
||
|
_group 'lib'
|
||
|
|
||
|
cd "${BASH_IT}" || return
|
||
|
|
||
|
if [ -z $BASH_IT_REMOTE ]; then
|
||
|
BASH_IT_REMOTE="origin"
|
||
|
fi
|
||
|
|
||
|
BASH_IT_GIT_REMOTE=$(git remote get-url $BASH_IT_REMOTE)
|
||
|
BASH_IT_GIT_URL=${BASH_IT_GIT_REMOTE%.git}
|
||
|
if [[ "$BASH_IT_GIT_URL" == *"git@"* ]]; then
|
||
|
# Fix URL in case it is ssh based URL
|
||
|
BASH_IT_GIT_URL=${BASH_IT_GIT_URL/://}
|
||
|
BASH_IT_GIT_URL=${BASH_IT_GIT_URL/git@/https://}
|
||
|
fi
|
||
|
|
||
|
current_tag=$(git describe --exact-match --tags 2> /dev/null)
|
||
|
|
||
|
if [[ -z $current_tag ]]; then
|
||
|
BASH_IT_GIT_VERSION_INFO="$(git log --pretty=format:'%h on %aI' -n 1)"
|
||
|
TARGET=${BASH_IT_GIT_VERSION_INFO%% *}
|
||
|
echo "Version type: dev"
|
||
|
echo "Current git SHA: $BASH_IT_GIT_VERSION_INFO"
|
||
|
echo "Commit info: $BASH_IT_GIT_URL/commit/$TARGET"
|
||
|
else
|
||
|
TARGET=$current_tag
|
||
|
echo "Version type: stable"
|
||
|
echo "Current tag: $current_tag"
|
||
|
echo "Tag information: $BASH_IT_GIT_URL/releases/tag/$current_tag"
|
||
|
fi
|
||
|
|
||
|
echo "Compare to latest: $BASH_IT_GIT_URL/compare/$TARGET...master"
|
||
|
|
||
|
cd - &> /dev/null || return
|
||
|
}
|
||
|
|
||
|
_bash-it-doctor() {
|
||
|
_about 'reloads a profile file with a BASH_IT_LOG_LEVEL set'
|
||
|
_param '1: BASH_IT_LOG_LEVEL argument: "errors" "warnings" "all"'
|
||
|
_group 'lib'
|
||
|
|
||
|
BASH_IT_LOG_LEVEL=$1
|
||
|
_bash-it-reload
|
||
|
unset BASH_IT_LOG_LEVEL
|
||
|
}
|
||
|
|
||
|
_bash-it-doctor-all() {
|
||
|
_about 'reloads a profile file with error, warning and debug logs'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-doctor $BASH_IT_LOG_LEVEL_ALL
|
||
|
}
|
||
|
|
||
|
_bash-it-doctor-warnings() {
|
||
|
_about 'reloads a profile file with error and warning logs'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-doctor $BASH_IT_LOG_LEVEL_WARNING
|
||
|
}
|
||
|
|
||
|
_bash-it-doctor-errors() {
|
||
|
_about 'reloads a profile file with error logs'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-doctor $BASH_IT_LOG_LEVEL_ERROR
|
||
|
}
|
||
|
|
||
|
_bash-it-doctor-() {
|
||
|
_about 'default bash-it doctor behavior, behaves like bash-it doctor all'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-doctor-all
|
||
|
}
|
||
|
|
||
|
_bash-it-restart() {
|
||
|
_about 'restarts the shell in order to fully reload it'
|
||
|
_group 'lib'
|
||
|
|
||
|
saved_pwd=$(pwd)
|
||
|
|
||
|
case $OSTYPE in
|
||
|
darwin*)
|
||
|
init_file=.bash_profile
|
||
|
;;
|
||
|
*)
|
||
|
init_file=.bashrc
|
||
|
;;
|
||
|
esac
|
||
|
exec "${0/-/}" --rcfile <(echo "source \"$HOME/$init_file\"; cd \"$saved_pwd\"")
|
||
|
}
|
||
|
|
||
|
_bash-it-reload() {
|
||
|
_about 'reloads a profile file'
|
||
|
_group 'lib'
|
||
|
|
||
|
pushd "${BASH_IT}" &> /dev/null || return
|
||
|
|
||
|
case $OSTYPE in
|
||
|
darwin*)
|
||
|
source ~/.bash_profile
|
||
|
;;
|
||
|
*)
|
||
|
source ~/.bashrc
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
popd &> /dev/null || return
|
||
|
}
|
||
|
|
||
|
_bash-it-describe ()
|
||
|
{
|
||
|
_about 'summarizes available bash_it components'
|
||
|
_param '1: subdirectory'
|
||
|
_param '2: preposition'
|
||
|
_param '3: file_type'
|
||
|
_param '4: column_header'
|
||
|
_example '$ _bash-it-describe "plugins" "a" "plugin" "Plugin"'
|
||
|
|
||
|
subdirectory="$1"
|
||
|
preposition="$2"
|
||
|
file_type="$3"
|
||
|
column_header="$4"
|
||
|
|
||
|
typeset f
|
||
|
typeset enabled
|
||
|
printf "%-20s%-10s%s\n" "$column_header" 'Enabled?' 'Description'
|
||
|
for f in "${BASH_IT}/$subdirectory/available/"*.bash
|
||
|
do
|
||
|
# Check for both the old format without the load priority, and the extended format with the priority
|
||
|
declare enabled_files enabled_file
|
||
|
enabled_file=$(basename $f)
|
||
|
enabled_files=$(sort <(compgen -G "${BASH_IT}/enabled/*$BASH_IT_LOAD_PRIORITY_SEPARATOR${enabled_file}") <(compgen -G "${BASH_IT}/$subdirectory/enabled/${enabled_file}") <(compgen -G "${BASH_IT}/$subdirectory/enabled/*$BASH_IT_LOAD_PRIORITY_SEPARATOR${enabled_file}") | wc -l)
|
||
|
|
||
|
if [ $enabled_files -gt 0 ]; then
|
||
|
enabled='x'
|
||
|
else
|
||
|
enabled=' '
|
||
|
fi
|
||
|
printf "%-20s%-10s%s\n" "$(basename $f | sed -e 's/\(.*\)\..*\.bash/\1/g')" " [$enabled]" "$(cat $f | metafor about-$file_type)"
|
||
|
done
|
||
|
printf '\n%s\n' "to enable $preposition $file_type, do:"
|
||
|
printf '%s\n' "$ bash-it enable $file_type <$file_type name> [$file_type name]... -or- $ bash-it enable $file_type all"
|
||
|
printf '\n%s\n' "to disable $preposition $file_type, do:"
|
||
|
printf '%s\n' "$ bash-it disable $file_type <$file_type name> [$file_type name]... -or- $ bash-it disable $file_type all"
|
||
|
}
|
||
|
|
||
|
_on-disable-callback()
|
||
|
{
|
||
|
_about 'Calls the disabled plugin destructor, if present'
|
||
|
_param '1: plugin name'
|
||
|
_example '$ _on-disable-callback gitstatus'
|
||
|
_group 'lib'
|
||
|
|
||
|
callback=$1_on_disable
|
||
|
_command_exists $callback && $callback
|
||
|
}
|
||
|
|
||
|
_disable-plugin ()
|
||
|
{
|
||
|
_about 'disables bash_it plugin'
|
||
|
_param '1: plugin name'
|
||
|
_example '$ disable-plugin rvm'
|
||
|
_group 'lib'
|
||
|
|
||
|
_disable-thing "plugins" "plugin" $1
|
||
|
_on-disable-callback $1
|
||
|
}
|
||
|
|
||
|
_disable-alias ()
|
||
|
{
|
||
|
_about 'disables bash_it alias'
|
||
|
_param '1: alias name'
|
||
|
_example '$ disable-alias git'
|
||
|
_group 'lib'
|
||
|
|
||
|
_disable-thing "aliases" "alias" $1
|
||
|
}
|
||
|
|
||
|
_disable-completion ()
|
||
|
{
|
||
|
_about 'disables bash_it completion'
|
||
|
_param '1: completion name'
|
||
|
_example '$ disable-completion git'
|
||
|
_group 'lib'
|
||
|
|
||
|
_disable-thing "completion" "completion" $1
|
||
|
}
|
||
|
|
||
|
_disable-thing ()
|
||
|
{
|
||
|
_about 'disables a bash_it component'
|
||
|
_param '1: subdirectory'
|
||
|
_param '2: file_type'
|
||
|
_param '3: file_entity'
|
||
|
_example '$ _disable-thing "plugins" "plugin" "ssh"'
|
||
|
|
||
|
subdirectory="$1"
|
||
|
file_type="$2"
|
||
|
file_entity="$3"
|
||
|
|
||
|
if [ -z "$file_entity" ]; then
|
||
|
reference "disable-$file_type"
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
typeset f suffix
|
||
|
suffix=$(echo "$subdirectory" | sed -e 's/plugins/plugin/g')
|
||
|
|
||
|
if [ "$file_entity" = "all" ]; then
|
||
|
# Disable everything that's using the old structure
|
||
|
for f in `compgen -G "${BASH_IT}/$subdirectory/enabled/*.${suffix}.bash"`
|
||
|
do
|
||
|
rm "$f"
|
||
|
done
|
||
|
|
||
|
# Disable everything in the global "enabled" directory
|
||
|
for f in `compgen -G "${BASH_IT}/enabled/*.${suffix}.bash"`
|
||
|
do
|
||
|
rm "$f"
|
||
|
done
|
||
|
else
|
||
|
typeset plugin_global=$(command ls $ "${BASH_IT}/enabled/"[0-9]*$BASH_IT_LOAD_PRIORITY_SEPARATOR$file_entity.$suffix.bash 2>/dev/null | head -1)
|
||
|
if [ -z "$plugin_global" ]; then
|
||
|
# Use a glob to search for both possible patterns
|
||
|
# 250---node.plugin.bash
|
||
|
# node.plugin.bash
|
||
|
# Either one will be matched by this glob
|
||
|
typeset plugin=$(command ls $ "${BASH_IT}/$subdirectory/enabled/"{[0-9]*$BASH_IT_LOAD_PRIORITY_SEPARATOR$file_entity.$suffix.bash,$file_entity.$suffix.bash} 2>/dev/null | head -1)
|
||
|
if [ -z "$plugin" ]; then
|
||
|
printf '%s\n' "sorry, $file_entity does not appear to be an enabled $file_type."
|
||
|
return
|
||
|
fi
|
||
|
rm "${BASH_IT}/$subdirectory/enabled/$(basename $plugin)"
|
||
|
else
|
||
|
rm "${BASH_IT}/enabled/$(basename $plugin_global)"
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
_bash-it-clean-component-cache "${file_type}"
|
||
|
|
||
|
printf '%s\n' "$file_entity disabled."
|
||
|
}
|
||
|
|
||
|
_enable-plugin ()
|
||
|
{
|
||
|
_about 'enables bash_it plugin'
|
||
|
_param '1: plugin name'
|
||
|
_example '$ enable-plugin rvm'
|
||
|
_group 'lib'
|
||
|
|
||
|
_enable-thing "plugins" "plugin" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_PLUGIN
|
||
|
}
|
||
|
|
||
|
_enable-alias ()
|
||
|
{
|
||
|
_about 'enables bash_it alias'
|
||
|
_param '1: alias name'
|
||
|
_example '$ enable-alias git'
|
||
|
_group 'lib'
|
||
|
|
||
|
_enable-thing "aliases" "alias" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_ALIAS
|
||
|
}
|
||
|
|
||
|
_enable-completion ()
|
||
|
{
|
||
|
_about 'enables bash_it completion'
|
||
|
_param '1: completion name'
|
||
|
_example '$ enable-completion git'
|
||
|
_group 'lib'
|
||
|
|
||
|
_enable-thing "completion" "completion" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_COMPLETION
|
||
|
}
|
||
|
|
||
|
_enable-thing ()
|
||
|
{
|
||
|
cite _about _param _example
|
||
|
_about 'enables a bash_it component'
|
||
|
_param '1: subdirectory'
|
||
|
_param '2: file_type'
|
||
|
_param '3: file_entity'
|
||
|
_param '4: load priority'
|
||
|
_example '$ _enable-thing "plugins" "plugin" "ssh" "150"'
|
||
|
|
||
|
subdirectory="$1"
|
||
|
file_type="$2"
|
||
|
file_entity="$3"
|
||
|
load_priority="$4"
|
||
|
|
||
|
if [ -z "$file_entity" ]; then
|
||
|
reference "enable-$file_type"
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
if [ "$file_entity" = "all" ]; then
|
||
|
typeset f $file_type
|
||
|
for f in "${BASH_IT}/$subdirectory/available/"*.bash
|
||
|
do
|
||
|
to_enable=$(basename $f .$file_type.bash)
|
||
|
if [ "$file_type" = "alias" ]; then
|
||
|
to_enable=$(basename $f ".aliases.bash")
|
||
|
fi
|
||
|
_enable-thing $subdirectory $file_type $to_enable $load_priority
|
||
|
done
|
||
|
else
|
||
|
typeset to_enable=$(command ls "${BASH_IT}/$subdirectory/available/"$file_entity.*bash 2>/dev/null | head -1)
|
||
|
if [ -z "$to_enable" ]; then
|
||
|
printf '%s\n' "sorry, $file_entity does not appear to be an available $file_type."
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
to_enable=$(basename $to_enable)
|
||
|
# Check for existence of the file using a wildcard, since we don't know which priority might have been used when enabling it.
|
||
|
typeset enabled_plugin=$(command ls "${BASH_IT}/$subdirectory/enabled/"{[0-9][0-9][0-9]$BASH_IT_LOAD_PRIORITY_SEPARATOR$to_enable,$to_enable} 2>/dev/null | head -1)
|
||
|
if [ ! -z "$enabled_plugin" ] ; then
|
||
|
printf '%s\n' "$file_entity is already enabled."
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
typeset enabled_plugin_global=$(command compgen -G "${BASH_IT}/enabled/[0-9][0-9][0-9]$BASH_IT_LOAD_PRIORITY_SEPARATOR$to_enable" 2>/dev/null | head -1)
|
||
|
if [ ! -z "$enabled_plugin_global" ] ; then
|
||
|
printf '%s\n' "$file_entity is already enabled."
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
mkdir -p "${BASH_IT}/enabled"
|
||
|
|
||
|
# Load the priority from the file if it present there
|
||
|
declare local_file_priority use_load_priority
|
||
|
local_file_priority=$(grep -E "^# BASH_IT_LOAD_PRIORITY:" "${BASH_IT}/$subdirectory/available/$to_enable" | awk -F': ' '{ print $2 }')
|
||
|
use_load_priority=${local_file_priority:-$load_priority}
|
||
|
|
||
|
ln -s ../$subdirectory/available/$to_enable "${BASH_IT}/enabled/${use_load_priority}${BASH_IT_LOAD_PRIORITY_SEPARATOR}${to_enable}"
|
||
|
fi
|
||
|
|
||
|
_bash-it-clean-component-cache "${file_type}"
|
||
|
|
||
|
printf '%s\n' "$file_entity enabled with priority $use_load_priority."
|
||
|
}
|
||
|
|
||
|
_help-completions()
|
||
|
{
|
||
|
_about 'summarize all completions available in bash-it'
|
||
|
_group 'lib'
|
||
|
|
||
|
_bash-it-completions
|
||
|
}
|
||
|
|
||
|
_help-aliases()
|
||
|
{
|
||
|
_about 'shows help for all aliases, or a specific alias group'
|
||
|
_param '1: optional alias group'
|
||
|
_example '$ alias-help'
|
||
|
_example '$ alias-help git'
|
||
|
|
||
|
if [ -n "$1" ]; then
|
||
|
case $1 in
|
||
|
custom)
|
||
|
alias_path='custom.aliases.bash'
|
||
|
;;
|
||
|
*)
|
||
|
alias_path="available/$1.aliases.bash"
|
||
|
;;
|
||
|
esac
|
||
|
cat "${BASH_IT}/aliases/$alias_path" | metafor alias | sed "s/$/'/"
|
||
|
else
|
||
|
typeset f
|
||
|
|
||
|
for f in `sort <(compgen -G "${BASH_IT}/aliases/enabled/*") <(compgen -G "${BASH_IT}/enabled/*.aliases.bash")`
|
||
|
do
|
||
|
_help-list-aliases $f
|
||
|
done
|
||
|
|
||
|
if [ -e "${BASH_IT}/aliases/custom.aliases.bash" ]; then
|
||
|
_help-list-aliases "${BASH_IT}/aliases/custom.aliases.bash"
|
||
|
fi
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
_help-list-aliases ()
|
||
|
{
|
||
|
typeset file=$(basename $1 | sed -e 's/[0-9]*[-]*\(.*\)\.aliases\.bash/\1/g')
|
||
|
printf '\n\n%s:\n' "${file}"
|
||
|
# metafor() strips trailing quotes, restore them with sed..
|
||
|
cat $1 | metafor alias | sed "s/$/'/"
|
||
|
}
|
||
|
|
||
|
_help-plugins()
|
||
|
{
|
||
|
_about 'summarize all functions defined by enabled bash-it plugins'
|
||
|
_group 'lib'
|
||
|
|
||
|
# display a brief progress message...
|
||
|
printf '%s' 'please wait, building help...'
|
||
|
typeset grouplist=$(mktemp -t grouplist.XXXXXX)
|
||
|
typeset func
|
||
|
for func in $(_typeset_functions)
|
||
|
do
|
||
|
typeset group="$(typeset -f $func | metafor group)"
|
||
|
if [ -z "$group" ]; then
|
||
|
group='misc'
|
||
|
fi
|
||
|
typeset about="$(typeset -f $func | metafor about)"
|
||
|
_letterpress "$about" $func >> $grouplist.$group
|
||
|
echo $grouplist.$group >> $grouplist
|
||
|
done
|
||
|
# clear progress message
|
||
|
printf '\r%s\n' ' '
|
||
|
typeset group
|
||
|
typeset gfile
|
||
|
for gfile in $(cat $grouplist | sort | uniq)
|
||
|
do
|
||
|
printf '%s\n' "${gfile##*.}:"
|
||
|
cat $gfile
|
||
|
printf '\n'
|
||
|
rm $gfile 2> /dev/null
|
||
|
done | less
|
||
|
rm $grouplist 2> /dev/null
|
||
|
}
|
||
|
|
||
|
_help-update () {
|
||
|
_about 'help message for update command'
|
||
|
_group 'lib'
|
||
|
|
||
|
echo "Check for a new version of Bash-it and update it."
|
||
|
}
|
||
|
|
||
|
_help-migrate () {
|
||
|
_about 'help message for migrate command'
|
||
|
_group 'lib'
|
||
|
|
||
|
echo "Migrates internal Bash-it structure to the latest version in case of changes."
|
||
|
echo "The 'migrate' command is run automatically when calling 'update', 'enable' or 'disable'."
|
||
|
}
|
||
|
|
||
|
all_groups ()
|
||
|
{
|
||
|
about 'displays all unique metadata groups'
|
||
|
group 'lib'
|
||
|
|
||
|
typeset func
|
||
|
typeset file=$(mktemp -t composure.XXXX)
|
||
|
for func in $(_typeset_functions)
|
||
|
do
|
||
|
typeset -f $func | metafor group >> $file
|
||
|
done
|
||
|
cat $file | sort | uniq
|
||
|
rm $file
|
||
|
}
|
||
|
|
||
|
if ! type pathmunge > /dev/null 2>&1
|
||
|
then
|
||
|
function pathmunge () {
|
||
|
about 'prevent duplicate directories in you PATH variable'
|
||
|
group 'helpers'
|
||
|
example 'pathmunge /path/to/dir is equivalent to PATH=/path/to/dir:$PATH'
|
||
|
example 'pathmunge /path/to/dir after is equivalent to PATH=$PATH:/path/to/dir'
|
||
|
|
||
|
if ! [[ $PATH =~ (^|:)$1($|:) ]] ; then
|
||
|
if [ "$2" = "after" ] ; then
|
||
|
export PATH=$PATH:$1
|
||
|
else
|
||
|
export PATH=$1:$PATH
|
||
|
fi
|
||
|
fi
|
||
|
}
|
||
|
fi
|