diff --git a/.gitignore b/.gitignore
index a17b6e82..8e6f12a1 100755
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,8 @@ bats
enabled/*
/enabled
tmp/
+
+# Do not save profiles
+profiles/*
+# apart from the default one
+!profiles/default.bash_it
diff --git a/bash_it.sh b/bash_it.sh
index de655e81..bda3407e 100755
--- a/bash_it.sh
+++ b/bash_it.sh
@@ -137,13 +137,6 @@ elif [ -s /Applications/Preview.app ]; then
PREVIEW="/Applications/Preview.app"
fi
-# Load all the Jekyll stuff
-
-if [ -e "$HOME/.jekyllconfig" ]; then
- # shellcheck disable=SC1090
- . "$HOME/.jekyllconfig"
-fi
-
# BASH_IT_RELOAD_LEGACY is set.
if ! _command_exists reload && [[ -n "${BASH_IT_RELOAD_LEGACY:-}" ]]; then
case $OSTYPE in
diff --git a/clean_files.txt b/clean_files.txt
index 53765a5f..8c8b3fed 100644
--- a/clean_files.txt
+++ b/clean_files.txt
@@ -97,6 +97,8 @@ plugins/available/history-search.plugin.bash
plugins/available/history-substring-search.plugin.bash
plugins/available/history.plugin.bash
plugins/available/hub.plugin.bash
+plugins/available/java.plugin.bash
+plugins/available/jekyll.plugin.bash
plugins/available/jump.plugin.bash
plugins/available/less-pretty-cat.plugin.bash
plugins/available/node.plugin.bash
diff --git a/completion/available/bash-it.completion.bash b/completion/available/bash-it.completion.bash
index 4fdd72d6..18cd241a 100644
--- a/completion/available/bash-it.completion.bash
+++ b/completion/available/bash-it.completion.bash
@@ -57,6 +57,18 @@ _bash-it-comp-list-available()
COMPREPLY=( $(compgen -W "${enabled_things}" -- ${cur}) )
}
+_bash-it-comp-list-profiles()
+{
+ local profiles
+
+ profiles=$(for f in `compgen -G "${BASH_IT}/profiles/*.bash_it" | sort -d`;
+ do
+ basename $f | sed -e 's/.bash_it//g'
+ done)
+
+ COMPREPLY=( $(compgen -W "${profiles}" -- ${cur}) )
+}
+
_bash-it-comp()
{
local cur prev opts
@@ -65,7 +77,7 @@ _bash-it-comp()
prev="${COMP_WORDS[COMP_CWORD-1]}"
chose_opt="${COMP_WORDS[1]}"
file_type="${COMP_WORDS[2]}"
- opts="disable enable help migrate reload restart doctor search show update version"
+ opts="disable enable help migrate reload restart profile doctor search show update version"
case "${chose_opt}" in
show)
local show_args="aliases completions plugins"
@@ -82,6 +94,33 @@ _bash-it-comp()
return 0
fi
;;
+ profile)
+ case "${file_type}" in
+ load)
+ if [[ "load" == "$prev" ]]; then
+ _bash-it-comp-list-profiles
+ fi
+ return 0
+ ;;
+ rm)
+ if [[ "rm" == "$prev" ]]; then
+ _bash-it-comp-list-profiles
+ fi
+ return 0
+ ;;
+ save)
+ return 0
+ ;;
+ list)
+ return 0
+ ;;
+ *)
+ local profile_args="load save list rm"
+ COMPREPLY=( $(compgen -W "${profile_args}" -- ${cur}) )
+ return 0
+ ;;
+ esac
+ ;;
doctor)
local doctor_args="errors warnings all"
COMPREPLY=( $(compgen -W "${doctor_args}" -- ${cur}) )
diff --git a/completion/available/defaults.completion.bash b/completion/available/defaults.completion.bash
index c43c0aae..39d7ea95 100644
--- a/completion/available/defaults.completion.bash
+++ b/completion/available/defaults.completion.bash
@@ -1,175 +1,5 @@
-# defaults
-# Bash command line completion for defaults
-#
-# Created by Jonathon Mah on 2006-11-08.
-# Copyright 2006 Playhaus. All rights reserved.
-#
-# Version 1.0 (2006-11-08)
+# shellcheck shell=bash
-
-_defaults_domains()
-{
- local cur
- COMPREPLY=()
- cur=${COMP_WORDS[COMP_CWORD]}
-
- local domains=$( defaults domains | sed -e 's/, /:/g' | tr : '\n' | sed -e 's/ /\\ /g' | grep "^$cur" )
- local IFS=$'\n'
- COMPREPLY=( $domains )
- if [[ $( echo '-app' | grep "^$cur" ) ]]; then
- COMPREPLY[${#COMPREPLY[@]}]="-app"
- fi
-
- return 0
-}
-
-
-_defaults()
-{
- local cur prev host_opts cmds cmd domain keys key_index
- cur=${COMP_WORDS[COMP_CWORD]}
- prev=${COMP_WORDS[COMP_CWORD-1]}
-
- host_opts='-currentHost -host'
- cmds='read read-type write rename delete domains find help'
-
- if [[ $COMP_CWORD -eq 1 ]]; then
- COMPREPLY=( $( compgen -W "$host_opts $cmds" -- $cur ) )
- return 0
- elif [[ $COMP_CWORD -eq 2 ]]; then
- if [[ "$prev" == "-currentHost" ]]; then
- COMPREPLY=( $( compgen -W "$cmds" -- $cur ) )
- return 0
- elif [[ "$prev" == "-host" ]]; then
- _known_hosts -a
- return 0
- else
- _defaults_domains
- return 0
- fi
- elif [[ $COMP_CWORD -eq 3 ]]; then
- if [[ ${COMP_WORDS[1]} == "-host" ]]; then
- _defaults_domains
- return 0
- fi
- fi
-
- # Both a domain and command have been specified
-
- if [[ ${COMP_WORDS[1]} == [${cmds// /|}] ]]; then
- cmd=${COMP_WORDS[1]}
- domain=${COMP_WORDS[2]}
- key_index=3
- if [[ "$domain" == "-app" ]]; then
- if [[ $COMP_CWORD -eq 3 ]]; then
- # Completing application name. Can't help here, sorry
- return 0
- fi
- domain="-app ${COMP_WORDS[3]}"
- key_index=4
- fi
- elif [[ ${COMP_WORDS[2]} == "-currentHost" ]] && [[ ${COMP_WORDS[2]} == [${cmds// /|}] ]]; then
- cmd=${COMP_WORDS[2]}
- domain=${COMP_WORDS[3]}
- key_index=4
- if [[ "$domain" == "-app" ]]; then
- if [[ $COMP_CWORD -eq 4 ]]; then
- # Completing application name. Can't help here, sorry
- return 0
- fi
- domain="-app ${COMP_WORDS[4]}"
- key_index=5
- fi
- elif [[ ${COMP_WORDS[3]} == "-host" ]] && [[ ${COMP_WORDS[3]} == [${cmds// /|}] ]]; then
- cmd=${COMP_WORDS[3]}
- domain=${COMP_WORDS[4]}
- key_index=5
- if [[ "$domain" == "-app" ]]; then
- if [[ $COMP_CWORD -eq 5 ]]; then
- # Completing application name. Can't help here, sorry
- return 0
- fi
- domain="-app ${COMP_WORDS[5]}"
- key_index=6
- fi
- fi
-
- keys=$( defaults read $domain 2>/dev/null | sed -n -e '/^ [^}) ]/p' | sed -e 's/^ \([^" ]\{1,\}\) = .*$/\1/g' -e 's/^ "\([^"]\{1,\}\)" = .*$/\1/g' | sed -e 's/ /\\ /g' )
-
- case $cmd in
- read|read-type)
- # Complete key
- local IFS=$'\n'
- COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
- ;;
- write)
- if [[ $key_index -eq $COMP_CWORD ]]; then
- # Complete key
- local IFS=$'\n'
- COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
- elif [[ $((key_index+1)) -eq $COMP_CWORD ]]; then
- # Complete value type
- # Unfortunately ${COMP_WORDS[key_index]} fails on keys with spaces
- local value_types='-string -data -integer -float -boolean -date -array -array-add -dict -dict-add'
- local cur_type=$( defaults read-type $domain ${COMP_WORDS[key_index]} 2>/dev/null | sed -e 's/^Type is \(.*\)/-\1/' -e's/dictionary/dict/' | grep "^$cur" )
- if [[ $cur_type ]]; then
- COMPREPLY=( $cur_type )
- else
- COMPREPLY=( $( compgen -W "$value_types" -- $cur ) )
- fi
- elif [[ $((key_index+2)) -eq $COMP_CWORD ]]; then
- # Complete value
- # Unfortunately ${COMP_WORDS[key_index]} fails on keys with spaces
- COMPREPLY=( $( defaults read $domain ${COMP_WORDS[key_index]} 2>/dev/null | grep -i "^${cur//\\/\\\\}" ) )
- fi
- ;;
- rename)
- if [[ $key_index -eq $COMP_CWORD ]] ||
- [[ $((key_index+1)) -eq $COMP_CWORD ]]; then
- # Complete source and destination keys
- local IFS=$'\n'
- COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
- fi
- ;;
- delete)
- if [[ $key_index -eq $COMP_CWORD ]]; then
- # Complete key
- local IFS=$'\n'
- COMPREPLY=( $( echo "$keys" | grep -i "^${cur//\\/\\\\}" ) )
- fi
- ;;
- esac
-
- return 0
-}
-
-complete -F _defaults -o default defaults
-
-
-# This file is licensed under the BSD license, as follows:
-#
-# Copyright (c) 2006, Playhaus
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of the Playhaus nor the names of its contributors may be
-# used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# This software is provided by the copyright holders and contributors "as is"
-# and any express or implied warranties, including, but not limited to, the
-# implied warranties of merchantability and fitness for a particular purpose are
-# disclaimed. In no event shall the copyright owner or contributors be liable
-# for any direct, indirect, incidental, special, exemplary, or consequential
-# damages (including, but not limited to, procurement of substitute goods or
-# services; loss of use, data, or profits; or business interruption) however
-# caused and on any theory of liability, whether in contract, strict liability,
-# or tort (including negligence or otherwise) arising in any way out of the use
-# of this software, even if advised of the possibility of such damage.
+if test -s "${BASH_IT?}/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bash"; then
+ source "$_"
+fi
diff --git a/completion/available/git.completion.bash b/completion/available/git.completion.bash
index d6fd3265..31b77fa3 100644
--- a/completion/available/git.completion.bash
+++ b/completion/available/git.completion.bash
@@ -39,5 +39,4 @@ done
if [[ "${_git_bash_completion_found}" == false ]]; then
_log_warning "no completion files found - please try enabling the 'system' completion instead."
fi
-# shellcheck disable=SC2154 # ignore unknown
unset "${!_git_bash_completion@}"
diff --git a/completion/available/pipenv.completion.bash b/completion/available/pipenv.completion.bash
index 52451b8a..4adfab95 100644
--- a/completion/available/pipenv.completion.bash
+++ b/completion/available/pipenv.completion.bash
@@ -1,4 +1,4 @@
# shellcheck shell=bash
if _command_exists pipenv; then
- eval "$(pipenv --completion)"
+ eval "$(_PIPENV_COMPLETE=bash_source pipenv)"
fi
diff --git a/docs/commands/index.rst b/docs/commands/index.rst
index 3eee3b3a..3890a139 100644
--- a/docs/commands/index.rst
+++ b/docs/commands/index.rst
@@ -13,3 +13,4 @@ You should be familiar with them in order to fully utilize Bash-it.
search
reload
doctor
+ profile
diff --git a/docs/commands/profile.rst b/docs/commands/profile.rst
new file mode 100644
index 00000000..67ca9b5b
--- /dev/null
+++ b/docs/commands/profile.rst
@@ -0,0 +1,31 @@
+.. _profile:
+
+Bash-it Profile
+---------------
+
+Have you ever wanted to port your *Bash-it* configuration into another machine?
+
+If you did, then ``bash-it profile`` is for you!
+
+This command can save and load custom *"profile"* files, that can be later
+used to load and recreate your configuration, in any machine you would like |:smile:|
+
+When porting your configuration into a new machine, you just need to save your current profile, copy the resulting *"profile"* file, and load it in the other machine.
+
+Example
+^^^^^^^
+
+.. code-block:: bash
+
+ # Saves your current profile
+ bash-it profile save my_profile
+ # Load the default profile, which is the one used in the default installation.
+ bash-it profile load default
+
+ # Do whatever you want:
+ # Disable stuff
+ bash-it disable ...
+ # Enable stuff
+ bash-it enable ...
+ # If you want to get back into your original configuration, you can do it easily
+ bash-it profile load my_profile
diff --git a/install.sh b/install.sh
index 5d2f883e..2bb78a3f 100755
--- a/install.sh
+++ b/install.sh
@@ -208,6 +208,8 @@ export BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE=''
source "${BASH_IT}"/vendor/github.com/erichs/composure/composure.sh
# shellcheck source=./lib/utilities.bash
source "$BASH_IT/lib/utilities.bash"
+# shellcheck source=./lib/log.bash
+source "${BASH_IT}/lib/log.bash"
cite _about _param _example _group _author _version
# shellcheck source=./lib/helpers.bash
source "$BASH_IT/lib/helpers.bash"
@@ -219,12 +221,7 @@ if [[ -n $interactive && -z "${silent}" ]]; then
done
else
echo ""
- echo -e "\033[0;32mEnabling reasonable defaults\033[0m"
- _enable-completion bash-it
- _enable-completion system
- _enable-plugin base
- _enable-plugin alias-completion
- _enable-alias general
+ _bash-it-profile-load "default"
fi
echo ""
diff --git a/lib/helpers.bash b/lib/helpers.bash
index f11df4be..01211079 100755
--- a/lib/helpers.bash
+++ b/lib/helpers.bash
@@ -108,6 +108,7 @@ bash-it ()
example '$ bash-it version'
example '$ bash-it reload'
example '$ bash-it restart'
+ example '$ bash-it profile list|save|load|rm [profile_name]'
example '$ bash-it doctor errors|warnings|all'
typeset verb=${1:-}
shift
@@ -126,6 +127,8 @@ bash-it ()
func=_help-$component;;
doctor)
func=_bash-it-doctor-$component;;
+ profile)
+ func=_bash-it-profile-$component;;
search)
_bash-it-search $component "$@"
return;;
@@ -457,6 +460,172 @@ _bash-it-doctor-() {
_bash-it-doctor-all
}
+_bash-it-profile-save() {
+ _about 'saves the current configuration to the "profile" directory'
+ _group 'lib'
+
+ local name=$1
+ while [ -z "$1" ]; do
+ read -r -e -p "Please enter the name of the profile to save: " name
+ case $name in
+ "")
+ echo -e "\033[91mPlease choose a name.\033[m"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+
+ local profile_path="${BASH_IT}/profiles/${name}.bash_it"
+ if [ -f "$profile_path" ]; then
+ echo -e "\033[0;33mProfile \"$name\" already exists.\033[m"
+ while true; do
+ read -r -e -n 1 -p "Would you like to overwrite existing profile? [y/N] " RESP
+ case $RESP in
+ [yY])
+ echo -e "\033[0;32mOverwriting profile \"$name\"...\033[m"
+ rm "$profile_path"
+ break
+ ;;
+ [nN] | "")
+ echo -e "\033[91mAborting profile save...\033[m"
+ return 1
+ ;;
+ *)
+ echo -e "\033[91mPlease choose y or n.\033[m"
+ ;;
+ esac
+ done
+ fi
+
+ local something_exists
+ echo "# This file is auto generated by Bash-it. Do not edit manually!" > "$profile_path"
+ for subdirectory in "plugins" "completion" "aliases"; do
+ local component_exists=""
+ echo "Saving $subdirectory configuration..."
+ for f in "${BASH_IT}/$subdirectory/available/"*.bash; do
+ _bash-it-determine-component-status-from-path "$f"
+ if [ "$enabled" == "x" ]; then
+ if [ -z "$component_exists" ]; then
+ # This is the first component of this type, print the header
+ component_exists="yes"
+ something_exists="yes"
+ echo "" >> "$profile_path"
+ echo "# $subdirectory" >> "$profile_path"
+ fi
+ echo "$subdirectory $enabled_file_clean" >> "$profile_path"
+ fi
+ done
+ done
+ if [ -z "$something_exists" ]; then
+ echo "It seems like no configuration was enabled.."
+ echo "Make sure to double check that this is the wanted behavior."
+ fi
+
+ echo "All done!"
+ echo ""
+ echo "Profile location: $profile_path"
+ echo "Load the profile by invoking \"bash-it profile load $name\""
+}
+
+_bash-it-profile-load-parse-profile() {
+ _about 'Internal function used to parse the profile file'
+ _param '1: path to the profile file'
+ _param '2: dry run- only check integrity of the profile file'
+ _example '$ _bash-it-profile-load-parse-profile "profile.bash_it" "dry"'
+
+ local num=0
+ while read -r -a line; do
+ num=$((num + 1))
+ # Ignore comments and empty lines
+ [[ -z "${line[*]}" || "${line[*]}" =~ ^#.* ]] && continue
+ local enable_func="_enable-${line[0]}"
+ local subdirectory=${line[0]}
+ local component=${line[1]}
+
+ typeset to_enable=$(command ls "${BASH_IT}/$subdirectory/available/$component".*bash 2>/dev/null | head -1)
+ # Ignore botched lines
+ if [[ -z "$to_enable" ]]; then
+ echo -e "\033[91mBad line(#$num) in profile, aborting load...\033[m"
+ local bad="bad line"
+ break
+ fi
+ # Do not actually modify config on dry run
+ [[ -z $2 ]] || continue
+ # Actually enable the component
+ $enable_func "$component"
+ done < "$1"
+
+ # Make sure to propagate the error
+ [[ -z $bad ]]
+}
+
+_bash-it-profile-list() {
+ about 'lists all profiles from the "profiles" directory'
+ _group 'lib'
+
+ echo "Available profiles:"
+ for profile in "${BASH_IT}/profiles"/*.bash_it; do
+ profile="${profile##*/}"
+ echo "${profile/.bash_it/}"
+ done
+}
+
+_bash-it-profile-rm() {
+ about 'Removes a profile from the "profiles" directory'
+ _group 'lib'
+ local name="$1"
+ if [[ -z $name ]]; then
+ echo -e "\033[91mPlease specify profile name to remove...\033[m"
+ return 1
+ fi
+
+ # Users should not be allowed to delete the default profile
+ if [[ $name == "default" ]]; then
+ echo -e "\033[91mCan not remove the default profile...\033[m"
+ return 1
+ fi
+
+ local profile_path="${BASH_IT}/profiles/$name.bash_it"
+ if [[ ! -f "$profile_path" ]]; then
+ echo -e "\033[91mCould not find profile \"$name\"...\033[m"
+ return 1
+ fi
+
+ command rm "$profile_path"
+ echo "Removed profile \"$name\" successfully!"
+}
+
+_bash-it-profile-load() {
+ _about 'loads a configuration from the "profiles" directory'
+ _group 'lib'
+
+ local name="$1"
+ if [[ -z $name ]]; then
+ echo -e "\033[91mPlease specify profile name to load, not changing configuration...\033[m"
+ return 1
+ fi
+
+ local profile_path="${BASH_IT}/profiles/$name.bash_it"
+ if [[ ! -f "$profile_path" ]]; then
+ echo -e "\033[91mCould not find profile \"$name\", not changing configuration...\033[m"
+ return 1
+ fi
+
+ echo "Trying to parse profile \"$name\"..."
+ if _bash-it-profile-load-parse-profile "$profile_path" "dry"; then
+ echo "Profile \"$name\" parsed successfully!"
+ echo "Disabling current configuration..."
+ _disable-all
+ echo ""
+ echo "Enabling configuration based on profile..."
+ _bash-it-profile-load-parse-profile "$profile_path"
+ echo ""
+ echo "Profile \"$name\" enabled!"
+ fi
+}
+
_bash-it-restart() {
_about 'restarts the shell in order to fully reload it'
_group 'lib'
@@ -492,6 +661,25 @@ _bash-it-reload() {
popd &> /dev/null || return
}
+_bash-it-determine-component-status-from-path ()
+{
+ _about 'internal function used to process component name and check if its enabled'
+ _param '1: full path to available component file'
+ _example '$ _bash-it-determine-component-status-from-path "${BASH_IT}/plugins/available/git.plugin.bash'
+
+ # Check for both the old format without the load priority, and the extended format with the priority
+ declare enabled_files enabled_file
+ enabled_file="${f##*/}"
+ enabled_file_clean=$(echo "$enabled_file" | sed -e 's/\(.*\)\..*\.bash/\1/g')
+ 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
+}
+
_bash-it-describe ()
{
_about 'summarizes available bash_it components'
@@ -511,17 +699,8 @@ _bash-it-describe ()
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="${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)"
+ _bash-it-determine-component-status-from-path "$f"
+ printf "%-20s%-10s%s\n" "$enabled_file_clean" " [$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"
@@ -540,6 +719,17 @@ _on-disable-callback()
_command_exists $callback && $callback
}
+_disable-all ()
+{
+ _about 'disables all bash_it components'
+ _example '$ _disable-all'
+ _group 'lib'
+
+ _disable-plugin "all"
+ _disable-alias "all"
+ _disable-completion "all"
+}
+
_disable-plugin ()
{
_about 'disables bash_it plugin'
@@ -623,7 +813,11 @@ _disable-thing ()
_bash-it-clean-component-cache "${file_type}"
- printf '%s\n' "$file_entity disabled."
+ if [ "$file_entity" = "all" ]; then
+ printf '%s\n' "$file_entity $(_bash-it-pluralize-component "$file_type") disabled."
+ else
+ printf '%s\n' "$file_entity disabled."
+ fi
}
_enable-plugin ()
@@ -636,6 +830,12 @@ _enable-plugin ()
_enable-thing "plugins" "plugin" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_PLUGIN
}
+_enable-plugins ()
+{
+ _about 'alias of _enable-plugin'
+ _enable-plugin "$@"
+}
+
_enable-alias ()
{
_about 'enables bash_it alias'
@@ -646,6 +846,12 @@ _enable-alias ()
_enable-thing "aliases" "alias" $1 $BASH_IT_LOAD_PRIORITY_DEFAULT_ALIAS
}
+_enable-aliases ()
+{
+ _about 'alias of _enable-alias'
+ _enable-alias "$@"
+}
+
_enable-completion ()
{
_about 'enables bash_it completion'
@@ -802,6 +1008,17 @@ _help-plugins()
rm $grouplist 2> /dev/null
}
+_help-profile () {
+ _about 'help message for profile command'
+ _group 'lib'
+
+ echo "Manages profiles of bash it."
+ echo "Use 'bash-it profile list' to see all available profiles."
+ echo "Use 'bash-it profile save foo' to save the current configuration into a profile named 'foo'."
+ echo "Use 'bash-it profile load foo' to load an existing profile named 'foo'."
+ echo "Use 'bash-it profile rm foo' to remove an existing profile named 'foo'."
+}
+
_help-update () {
_about 'help message for update command'
_group 'lib'
diff --git a/plugins/available/autojump.plugin.bash b/plugins/available/autojump.plugin.bash
index 89694100..3dfa0bca 100644
--- a/plugins/available/autojump.plugin.bash
+++ b/plugins/available/autojump.plugin.bash
@@ -4,13 +4,11 @@ about-plugin 'Autojump configuration, see https://github.com/wting/autojump for
# Only supports the Homebrew variant, Debian and Arch at the moment.
# Feel free to provide a PR to support other install locations
-# shellcheck disable=1090
+# shellcheck disable=SC1090
if _bash_it_homebrew_check && [[ -s "${BASH_IT_HOMEBREW_PREFIX}/etc/profile.d/autojump.sh" ]]; then
source "${BASH_IT_HOMEBREW_PREFIX}/etc/profile.d/autojump.sh"
elif _command_exists dpkg && dpkg -s autojump &> /dev/null; then
- # shellcheck disable=SC1090
source "$(dpkg-query -S autojump.sh | cut -d' ' -f2)"
elif _command_exists pacman && pacman -Q autojump &> /dev/null; then
- # shellcheck disable=SC1090
source "$(pacman -Ql autojump | grep autojump.sh | cut -d' ' -f2)"
fi
diff --git a/plugins/available/dirs.plugin.bash b/plugins/available/dirs.plugin.bash
index 2c1adf7a..a455ff95 100644
--- a/plugins/available/dirs.plugin.bash
+++ b/plugins/available/dirs.plugin.bash
@@ -103,5 +103,3 @@ R () {
}
alias U='source ~/.dirs' # Update bookmark stack
-# Set the Bash option so that no '$' is required when using the above facility
-shopt -s cdable_vars
diff --git a/plugins/available/fzf.plugin.bash b/plugins/available/fzf.plugin.bash
index c4f5ea84..21182ac2 100644
--- a/plugins/available/fzf.plugin.bash
+++ b/plugins/available/fzf.plugin.bash
@@ -4,14 +4,15 @@
cite about-plugin
about-plugin 'load fzf, if you are using it'
-_command_exists fzf || return
-
if [ -r ~/.fzf.bash ] ; then
source ~/.fzf.bash
elif [ -r "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.bash ] ; then
source "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.bash
fi
+# No need to continue if the command is not present
+_command_exists fzf || return
+
if [ -z ${FZF_DEFAULT_COMMAND+x} ] && _command_exists fd ; then
export FZF_DEFAULT_COMMAND='fd --type f'
fi
diff --git a/plugins/available/java.plugin.bash b/plugins/available/java.plugin.bash
index 98e46247..2a80a99a 100644
--- a/plugins/available/java.plugin.bash
+++ b/plugins/available/java.plugin.bash
@@ -1,11 +1,11 @@
-cite about-plugin
+# shellcheck shell=bash
about-plugin 'Java and JAR helper functions'
function jar_manifest {
- about "extracts the specified JAR file's MANIFEST file and prints it to stdout"
- group 'java'
- param '1: JAR file to extract the MANIFEST from'
- example 'jar_manifest lib/foo.jar'
+ about "extracts the specified JAR file's MANIFEST file and prints it to stdout"
+ group 'java'
+ param '1: JAR file to extract the MANIFEST from'
+ example 'jar_manifest lib/foo.jar'
- unzip -c $1 META-INF/MANIFEST.MF
+ unzip -c "${1:?${FUNCNAME[0]}: JAR file must be specified}" META-INF/MANIFEST.MF
}
diff --git a/plugins/available/jekyll.plugin.bash b/plugins/available/jekyll.plugin.bash
index c340c432..d818b076 100644
--- a/plugins/available/jekyll.plugin.bash
+++ b/plugins/available/jekyll.plugin.bash
@@ -1,367 +1,288 @@
+# shellcheck shell=bash
cite about-plugin
about-plugin 'manage your jekyll site'
-editpost() {
- about 'edit a post'
- param '1: site directory'
- group 'jekyll'
+function editpost() {
+ about 'edit a post'
+ param '1: site directory'
+ group 'jekyll'
- unset SITE
- if [ -z "$1" ]
- then
- echo "Error: no site specified."
- echo "The site is the name of the directory your project is in."
- return 1
- fi
+ local SITE site POST DATE TITLE POSTS
+ local -i COUNTER=1 POST_TO_EDIT ret
+ if [[ -z "${1:-}" ]]; then
+ echo "Error: no site specified."
+ echo "The site is the name of the directory your project is in."
+ return 1
+ fi
- for site in ${SITES[@]}
- do
- if [ "${site##*/}" = "$1" ]
- then
- SITE=$site
- break
- fi
- done
+ for site in "${SITES[@]:-}"; do
+ if [[ "${site##*/}" == "$1" ]]; then
+ SITE="${site}"
+ break
+ fi
+ done
- if [ -z "$SITE" ]
- then
- echo "No such site."
- return 1
- fi
+ if [[ -z "${SITE:-}" ]]; then
+ echo "No such site."
+ return 1
+ fi
- builtin cd "$SITE/_posts"
+ pushd "${SITE}/_posts" > /dev/null || return
- COUNTER=1
- NUMBER="$RANDOM"
- TMPFILE="/tmp/editpost-$NUMBER"
-
- for POST in *
- do
- DATE=`echo $POST | grep -oE "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}"`
- TITLE=`cat $POST | grep -oE "title: (.+)"`
- TITLE=`echo $TITLE | sed 's/title: //'`
- echo "$COUNTER) $DATE $TITLE" >> "$TMPFILE"
- POSTS[$COUNTER]=$POST
- COUNTER=`expr $COUNTER + 1`
- done
- less $TMPFILE
- read -p "Number of post to edit: " POST_TO_EDIT
- if [ -z "$JEKYLL_EDITOR" ]
- then
- nano "${POSTS[$POST_TO_EDIT]}"
- else
- "$JEKYLL_EDITOR" "${POSTS[$POST_TO_EDIT]}"
- fi
+ for POST in *; do
+ DATE="$(echo "${POST}" | grep -oE "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}")"
+ TITLE="$(grep -oE "title: (.+)" < "${POST}")"
+ TITLE="${TITLE/title: /}"
+ echo "${COUNTER}) ${DATE} ${TITLE}"
+ POSTS[COUNTER]="$POST"
+ COUNTER="$((COUNTER + 1))"
+ done > >(less)
+ read -rp "Number of post to edit: " POST_TO_EDIT
+ "${JEKYLL_EDITOR:-${VISUAL:-${EDITOR:-${ALTERNATE_EDITOR:-nano}}}}" "${POSTS[POST_TO_EDIT]}"
+ ret="$?"
+ popd > /dev/null || return "$ret"
+ return "$ret"
}
-newpost() {
- about 'create a new post'
- param '1: site directory'
- group 'jekyll'
+function newpost() {
+ about 'create a new post'
+ param '1: site directory'
+ group 'jekyll'
- unset SITE
- if [ -z "$1" ]
- then
- echo "Error: no site specified."
- echo "The site is the name of the directory your project is in."
- return 1
- fi
+ local SITE site FNAME_POST_TITLE FNAME YAML_DATE
+ local JEKYLL_FORMATTING FNAME_DATE OPTIONS OPTION POST_TYPE POST_TITLE
+ local -i loc=0 ret
+ if [[ -z "${1:-}" ]]; then
+ echo "Error: no site specified."
+ echo "The site is the name of the directory your project is in."
+ return 1
+ fi
- if [ -z "$SITE" ]
- then
- echo "No such site."
- return 1
- fi
+ if [[ -z "${SITE}" ]]; then
+ echo "No such site."
+ return 1
+ fi
- loc=0
+ for site in "${SITES[@]}"; do
+ if [[ "${site##*/}" == "$1" ]]; then
+ SITE="$site"
+ JEKYLL_FORMATTING="${MARKUPS[loc]}"
+ break
+ fi
+ loc=$((loc + 1))
+ done
- for site in ${SITES[@]}
- do
- if [ "${site##*/}" = "$1" ]
- then
- SITE=$site
- JEKYLL_FORMATTING=${MARKUPS[$loc]}
- break
- fi
- loc=$(($loc+1))
- done
+ # Change directory into the local jekyll root
+ pushd "${SITE}/_posts" > /dev/null || return
- # 'builtin cd' into the local jekyll root
+ # Get the date for the new post's filename
+ FNAME_DATE="$(date "+%Y-%m-%d")"
- builtin cd "$SITE/_posts"
+ # If the user is using markdown or textile formatting, let them choose what type of post they want. Sort of like Tumblr.
+ OPTIONS=('Text' 'Quote' 'Image' 'Audio' 'Video' 'Link')
- # Get the date for the new post's filename
+ if [[ $JEKYLL_FORMATTING == "markdown" || $JEKYLL_FORMATTING == "textile" ]]; then
+ select OPTION in "${OPTIONS[@]}"; do
+ POST_TYPE="${OPTION}"
+ break
+ done
+ fi
- FNAME_DATE=$(date "+%Y-%m-%d")
+ # Get the title for the new post
+ read -rp "Enter title of the new post: " POST_TITLE
- # If the user is using markdown or textile formatting, let them choose what type of post they want. Sort of like Tumblr.
+ # Convert the spaces in the title to hyphens for use in the filename
+ FNAME_POST_TITLE="${POST_TITLE/ /-}"
- OPTIONS="Text Quote Image Audio Video Link"
+ # Now, put it all together for the full filename
+ FNAME="$FNAME_DATE-$FNAME_POST_TITLE.$JEKYLL_FORMATTING"
- if [ $JEKYLL_FORMATTING = "markdown" -o $JEKYLL_FORMATTING = "textile" ]
- then
- select OPTION in $OPTIONS
- do
- if [[ $OPTION = "Text" ]]
- then
- POST_TYPE="Text"
- break
- fi
+ # And, finally, create the actual post file. But we're not done yet...
+ {
+ # Write a little stuff to the file for the YAML Front Matter
+ echo "---"
- if [[ $OPTION = "Quote" ]]
- then
- POST_TYPE="Quote"
- break
- fi
+ # Now we have to get the date, again. But this time for in the header (YAML Front Matter) of the file
+ YAML_DATE="$(date "+%B %d %Y %X")"
- if [[ $OPTION = "Image" ]]
- then
- POST_TYPE="Image"
- break
- fi
+ # Echo the YAML Formatted date to the post file
+ echo "date: $YAML_DATE"
- if [[ $OPTION = "Audio" ]]
- then
- POST_TYPE="Audio"
- break
- fi
+ # Echo the original post title to the YAML Front Matter header
+ echo "title: $POST_TITLE"
- if [[ $OPTION = "Video" ]]
- then
- POST_TYPE="Video"
- break
- fi
+ # And, now, echo the "post" layout to the YAML Front Matter header
+ echo "layout: post"
- if [[ $OPTION = "Link" ]]
- then
- POST_TYPE="Link"
- break
- fi
- done
- fi
+ # Close the YAML Front Matter Header
+ echo "---"
- # Get the title for the new post
+ echo
+ } > "${FNAME}"
- read -p "Enter title of the new post: " POST_TITLE
+ # Generate template text based on the post type
+ if [[ $JEKYLL_FORMATTING == "markdown" ]]; then
+ case $POST_TYPE in
+ "Text")
+ true
+ ;;
+ "Quote")
+ echo "> Quote"
+ echo
+ echo "— Author"
+ ;;
+ "Image")
+ echo ""
+ ;;
+ "Audio")
+ echo ""
+ ;;
+ "Video")
+ echo ""
+ ;;
+ "Link")
+ echo "[link][1]"
+ echo
+ echo "> Quote"
+ echo
+ echo "[1]: url"
+ ;;
+ esac
+ elif [[ $JEKYLL_FORMATTING == "textile" ]]; then
+ case $POST_TYPE in
+ "Text")
+ true
+ ;;
+ "Quote")
+ echo "bq. Quote"
+ echo
+ echo "— Author"
+ ;;
+ "Image")
+ echo "!url(alt text)"
+ ;;
+ "Audio")
+ echo ""
+ ;;
+ "Video")
+ echo ""
+ ;;
+ "Link")
+ echo "\"Site\":url"
+ echo
+ echo "bq. Quote"
+ ;;
+ esac
+ fi >> "${FNAME}"
- # Convert the spaces in the title to hyphens for use in the filename
-
- FNAME_POST_TITLE=`echo $POST_TITLE | tr ' ' "-"`
-
- # Now, put it all together for the full filename
-
- FNAME="$FNAME_DATE-$FNAME_POST_TITLE.$JEKYLL_FORMATTING"
-
- # And, finally, create the actual post file. But we're not done yet...
-
- touch "$FNAME"
-
- # Write a little stuff to the file for the YAML Front Matter
-
- echo "---" >> $FNAME
-
- # Now we have to get the date, again. But this time for in the header (YAML Front Matter) of
- # the file
-
- YAML_DATE=$(date "+%B %d %Y %X")
-
- # Echo the YAML Formatted date to the post file
-
- echo "date: $YAML_DATE" >> $FNAME
-
- # Echo the original post title to the YAML Front Matter header
-
- echo "title: $POST_TITLE" >> $FNAME
-
- # And, now, echo the "post" layout to the YAML Front Matter header
-
- echo "layout: post" >> $FNAME
-
- # Close the YAML Front Matter Header
-
- echo "---" >> $FNAME
- echo >> $FNAME
-
- # Generate template text based on the post type
-
- if [[ $JEKYLL_FORMATTING = "markdown" ]]
- then
- if [[ $POST_TYPE = "Text" ]]
- then
- true
- fi
-
- if [[ $POST_TYPE = "Quote" ]]
- then
- echo "> Quote" >> $FNAME
- echo >> $FNAME
- echo "— Author" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Image" ]]
- then
- echo "" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Audio" ]]
- then
- echo "" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Video" ]]
- then
- echo "" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Link" ]]
- then
- echo "[link][1]" >> $FNAME
- echo >> $FNAME
- echo "> Quote" >> $FNAME
- echo >> $FNAME
- echo "[1]: url" >> $FNAME
- fi
- fi
-
- if [[ $JEKYLL_FORMATTING = "textile" ]]
- then
- if [[ $POST_TYPE = "Text" ]]
- then
- true
- fi
-
- if [[ $POST_TYPE = "Quote" ]]
- then
- echo "bq. Quote" >> $FNAME
- echo >> $FNAME
- echo "— Author" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Image" ]]
- then
- echo "!url(alt text)" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Audio" ]]
- then
- echo "" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Video" ]]
- then
- echo "" >> $FNAME
- fi
-
- if [[ $POST_TYPE = "Link" ]]
- then
- echo "\"Site\":url" >> $FNAME
- echo >> $FNAME
- echo "bq. Quote" >> $FNAME
- fi
- fi
-
- # Open the file in your favorite editor
-
- "$JEKYLL_EDITOR" $FNAME
+ # Open the file in your favorite editor
+ "${JEKYLL_EDITOR:-${VISUAL:-${EDITOR:-${ALTERNATE_EDITOR:-nano}}}}" "${FNAME}"
+ ret="$?"
+ popd > /dev/null || return "$ret"
+ return "$ret"
}
function testsite() {
- about 'launches local jekyll server'
- param '1: site directory'
- group 'jekyll'
+ about 'launches local jekyll server'
+ param '1: site directory'
+ group 'jekyll'
- unset SITE
- if [ -z "$1" ]
- then
- echo "Error: no site specified."
- echo "The site is the name of the directory your project is in."
- return 1
- fi
+ local SITE site
+ local -i ret
+ if [[ -z "${1:-}" ]]; then
+ echo "Error: no site specified."
+ echo "The site is the name of the directory your project is in."
+ return 1
+ fi
- for site in ${SITES[@]}
- do
- if [ "${site##*/}" = "$1" ]
- then
- SITE=$site
- break
- fi
- done
+ for site in "${SITES[@]}"; do
+ if [[ "${site##*/}" == "$1" ]]; then
+ SITE="$site"
+ break
+ fi
+ done
- if [ -z "$SITE" ]
- then
- echo "No such site."
- return 1
- fi
+ if [[ -z "${SITE}" ]]; then
+ echo "No such site."
+ return 1
+ fi
- builtin cd $SITE
- jekyll --server --auto
+ pushd "${SITE}" > /dev/null || return
+ jekyll --server --auto
+ ret="$?"
+ popd > /dev/null || return "$ret"
+ return "$ret"
}
function buildsite() {
- about 'builds site'
- param '1: site directory'
- group 'jekyll'
+ about 'builds site'
+ param '1: site directory'
+ group 'jekyll'
- unset SITE
- if [ -z "$1" ]
- then
- echo "Error: no site specified."
- echo "The site is the name of the directory your project is in."
- return 1
- fi
+ local SITE site
+ local -i ret
+ if [[ -z "${1:-}" ]]; then
+ echo "Error: no site specified."
+ echo "The site is the name of the directory your project is in."
+ return 1
+ fi
- for site in ${SITES[@]}
- do
- if [ "${site##*/}" = "$1" ]
- then
- SITE=$site
- break
- fi
- done
+ for site in "${SITES[@]}"; do
+ if [[ "${site##*/}" == "$1" ]]; then
+ SITE="$site"
+ break
+ fi
+ done
- if [ -z "$SITE" ]
- then
- echo "No such site."
- return 1
- fi
+ if [[ -z "${SITE}" ]]; then
+ echo "No such site."
+ return 1
+ fi
- builtin cd $SITE
- rm -rf _site
- jekyll --no-server
+ pushd "${SITE}" > /dev/null || return
+ rm -rf _site
+ jekyll --no-server
+ ret="$?"
+ popd > /dev/null || return "$ret"
+ return "$ret"
}
function deploysite() {
- about 'rsyncs site to remote host'
- param '1: site directory'
- group 'jekyll'
+ about 'rsyncs site to remote host'
+ param '1: site directory'
+ group 'jekyll'
- unset SITE
- if [ -z "$1" ]
- then
- echo "Error: no site specified."
- echo "The site is the name of the directory your project is in."
- return 1
- fi
+ local SITE site REMOTE
+ local -i loc=0 ret
+ if [[ -z "${1:-}" ]]; then
+ echo "Error: no site specified."
+ echo "The site is the name of the directory your project is in."
+ return 1
+ fi
- loc=0
+ for site in "${SITES[@]}"; do
+ if [[ "${site##*/}" == "$1" ]]; then
+ SITE="$site"
+ # shellcheck disable=SC2153 # who knows
+ REMOTE="${REMOTES[loc]}"
+ break
+ fi
+ loc=$((loc + 1))
+ done
- for site in ${SITES[@]}
- do
- if [ "${site##*/}" = "$1" ]
- then
- SITE=$site
- REMOTE=${REMOTES[$loc]}
- break
- fi
- loc=$(($loc+1))
- done
+ if [[ -z "${SITE}" ]]; then
+ echo "No such site."
+ return 1
+ fi
- if [ -z "$SITE" ]
- then
- echo "No such site."
- return 1
- fi
-
- builtin cd $SITE
- rsync -rz $REMOTE
+ pushd "${SITE}" > /dev/null || return
+ rsync -rz "${REMOTE?}"
+ ret="$?"
+ popd > /dev/null || return "$ret"
+ return "$ret"
}
+
+# Load the Jekyll config
+if [[ -s "$HOME/.jekyllconfig" ]]; then
+ source "$HOME/.jekyllconfig"
+fi
diff --git a/profiles/default.bash_it b/profiles/default.bash_it
new file mode 100644
index 00000000..5e4f4631
--- /dev/null
+++ b/profiles/default.bash_it
@@ -0,0 +1,12 @@
+# This is the default profile of Bash-it
+
+# plugins
+plugins alias-completion
+plugins base
+
+# completion
+completion bash-it
+completion system
+
+# aliases
+aliases general
diff --git a/test/completion/bash-it.completion.bats b/test/completion/bash-it.completion.bats
index eaa4423d..fbf0a3fa 100644
--- a/test/completion/bash-it.completion.bats
+++ b/test/completion/bash-it.completion.bats
@@ -80,32 +80,42 @@ function __check_completion () {
@test "completion bash-it: show options" {
run __check_completion 'bash-it '
- assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
+ assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version"
}
@test "completion bash-it: bash-ti - show options" {
run __check_completion 'bash-ti '
- assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
+ assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version"
}
@test "completion bash-it: shit - show options" {
run __check_completion 'shit '
- assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
+ assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version"
}
@test "completion bash-it: bashit - show options" {
run __check_completion 'bashit '
- assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
+ assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version"
}
@test "completion bash-it: batshit - show options" {
run __check_completion 'batshit '
- assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
+ assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version"
}
@test "completion bash-it: bash_it - show options" {
run __check_completion 'bash_it '
- assert_line -n 0 "disable enable help migrate reload restart doctor search show update version"
+ assert_line -n 0 "disable enable help migrate reload restart profile doctor search show update version"
+}
+
+@test "completion bash-it: profile - show options" {
+ run __check_completion 'bash-it profile '
+ assert_line -n 0 "load save list rm"
+}
+
+@test "completion bash-it: profile load - show options" {
+ run __check_completion 'bash-it profile load '
+ assert_line -n 0 "default"
}
@test "completion bash-it: show - show options" {
diff --git a/test/fixtures/bash_it/profiles/test-bad-component.bash_it b/test/fixtures/bash_it/profiles/test-bad-component.bash_it
new file mode 100644
index 00000000..8640265c
--- /dev/null
+++ b/test/fixtures/bash_it/profiles/test-bad-component.bash_it
@@ -0,0 +1,12 @@
+# plugins
+plugins alias-completion
+plugins base
+
+# completion
+completion bash-it
+completion system
+
+# aliases
+aliases general
+# Bad component
+aliases bla
diff --git a/test/fixtures/bash_it/profiles/test-bad-type.bash_it b/test/fixtures/bash_it/profiles/test-bad-type.bash_it
new file mode 100644
index 00000000..ed2d2373
--- /dev/null
+++ b/test/fixtures/bash_it/profiles/test-bad-type.bash_it
@@ -0,0 +1,12 @@
+# plugins
+plugins alias-completion
+plugins base
+# Bad type
+pluugins alias-completion
+
+# completion
+completion bash-it
+completion system
+
+# aliases
+aliases general
diff --git a/test/lib/helpers.bats b/test/lib/helpers.bats
index 7f6664e0..d876d882 100644
--- a/test/lib/helpers.bats
+++ b/test/lib/helpers.bats
@@ -13,11 +13,24 @@ load ../../plugins/available/base.plugin
function local_setup {
setup_test_fixture
+
+ # Copy the test fixture to the Bash-it folder
+ if command -v rsync &> /dev/null; then
+ rsync -a "$BASH_IT/test/fixtures/bash_it/" "$BASH_IT/"
+ else
+ find "$BASH_IT/test/fixtures/bash_it" \
+ -mindepth 1 -maxdepth 1 \
+ -exec cp -r {} "$BASH_IT/" \;
+ fi
}
# TODO Create global __is_enabled function
# TODO Create global __get_base_name function
# TODO Create global __get_enabled_name function
+@test "bash-it: verify that the test fixture is available" {
+ assert_file_exist "$BASH_IT/profiles/test-bad-component.bash_it"
+ assert_file_exist "$BASH_IT/profiles/test-bad-type.bash_it"
+}
@test "helpers: _command_exists function exists" {
run type -a _command_exists &> /dev/null
@@ -283,6 +296,149 @@ function local_setup {
assert_link_exist "$BASH_IT/enabled/225---nvm.plugin.bash"
}
+@test "helper: profile load command sanity" {
+ run _bash-it-profile-load "default"
+
+ assert_link_exist "$BASH_IT/enabled/150---general.aliases.bash"
+ assert_link_exist "$BASH_IT/enabled/250---base.plugin.bash"
+ assert_link_exist "$BASH_IT/enabled/365---alias-completion.plugin.bash"
+ assert_link_exist "$BASH_IT/enabled/350---bash-it.completion.bash"
+ assert_link_exist "$BASH_IT/enabled/350---system.completion.bash"
+}
+
+@test "helper: profile save command sanity" {
+ run _enable-plugin "nvm"
+
+ run _bash-it-profile-save "test"
+ assert_line -n 0 "Saving plugins configuration..."
+ assert_line -n 1 "Saving completion configuration..."
+ assert_line -n 2 "Saving aliases configuration..."
+ assert_line -n 3 "All done!"
+ assert_file_exist "$BASH_IT/profiles/test.bash_it"
+}
+
+@test "helper: profile save creates valid file with only plugin enabled" {
+ run _enable-plugin "nvm"
+
+ run _bash-it-profile-save "test"
+ run cat "$BASH_IT/profiles/test.bash_it"
+ assert_line -n 0 "# This file is auto generated by Bash-it. Do not edit manually!"
+ assert_line -n 1 "# plugins"
+ assert_line -n 2 "plugins nvm"
+}
+
+@test "helper: profile save creates valid file with only completion enabled" {
+ run _enable-completion "bash-it"
+
+ run _bash-it-profile-save "test"
+ run cat "$BASH_IT/profiles/test.bash_it"
+ assert_line -n 0 "# This file is auto generated by Bash-it. Do not edit manually!"
+ assert_line -n 1 "# completion"
+ assert_line -n 2 "completion bash-it"
+}
+
+@test "helper: profile save creates valid file with only aliases enabled" {
+ run _enable-alias "general"
+
+ run _bash-it-profile-save "test"
+ run cat "$BASH_IT/profiles/test.bash_it"
+ assert_line -n 0 "# This file is auto generated by Bash-it. Do not edit manually!"
+ assert_line -n 1 "# aliases"
+ assert_line -n 2 "aliases general"
+}
+
+@test "helper: profile edge case, empty configuration" {
+ run _bash-it-profile-save "test"
+ assert_line -n 3 "It seems like no configuration was enabled.."
+ assert_line -n 4 "Make sure to double check that this is the wanted behavior."
+
+ run _enable-alias "general"
+ run _enable-plugin "base"
+ run _enable-plugin "alias-completion"
+ run _enable-completion "bash-it"
+ run _enable-completion "system"
+
+ run _bash-it-profile-load "test"
+ assert_link_not_exist "$BASH_IT/enabled/150---general.aliases.bash"
+ assert_link_not_exist "$BASH_IT/enabled/250---base.plugin.bash"
+ assert_link_not_exist "$BASH_IT/enabled/365---alias-completion.plugin.bash"
+ assert_link_not_exist "$BASH_IT/enabled/350---bash-it.completion.bash"
+ assert_link_not_exist "$BASH_IT/enabled/350---system.completion.bash"
+}
+
+@test "helper: profile save and load" {
+ run _enable-alias "general"
+ run _enable-plugin "base"
+ run _enable-plugin "alias-completion"
+ run _enable-completion "bash-it"
+ run _enable-completion "system"
+
+ run _bash-it-profile-save "test"
+ assert_success
+
+ run _disable-alias "general"
+ assert_link_not_exist "$BASH_IT/enabled/150---general.aliases.bash"
+ run _bash-it-profile-load "test"
+ assert_link_exist "$BASH_IT/enabled/150---general.aliases.bash"
+}
+
+@test "helper: profile load corrupted profile file: bad component" {
+ run _bash-it-profile-load "test-bad-component"
+ assert_line -n 1 -p "Bad line(#12) in profile, aborting load..."
+}
+
+@test "helper: profile load corrupted profile file: bad subdirectory" {
+ run _bash-it-profile-load "test-bad-type"
+ assert_line -n 1 -p "Bad line(#5) in profile, aborting load..."
+}
+
+@test "helper: profile rm sanity" {
+ run _bash-it-profile-save "test"
+ assert_file_exist "$BASH_IT/profiles/test.bash_it"
+ run _bash-it-profile-rm "test"
+ assert_line -n 0 "Removed profile \"test\" successfully!"
+ assert_file_not_exist "$BASH_IT/profiles/test.bash_it"
+}
+
+@test "helper: profile rm no params" {
+ run _bash-it-profile-rm ""
+ assert_line -n 0 -p "Please specify profile name to remove..."
+}
+
+@test "helper: profile load no params" {
+ run _bash-it-profile-load ""
+ assert_line -n 0 -p "Please specify profile name to load, not changing configuration..."
+}
+
+@test "helper: profile rm default" {
+ run _bash-it-profile-rm "default"
+ assert_line -n 0 -p "Can not remove the default profile..."
+ assert_file_exist "$BASH_IT/profiles/default.bash_it"
+}
+
+@test "helper: profile rm bad profile name" {
+ run _bash-it-profile-rm "notexisting"
+ assert_line -n 0 -p "Could not find profile \"notexisting\"..."
+}
+
+@test "helper: profile list sanity" {
+ run _bash-it-profile-list
+ assert_line -n 0 "Available profiles:"
+ assert_line -n 1 "default"
+}
+
+@test "helper: profile list more profiles" {
+ run _bash-it-profile-save "cactus"
+ run _bash-it-profile-save "another"
+ run _bash-it-profile-save "brother"
+ run _bash-it-profile-list
+ assert_line -n 0 "Available profiles:"
+ assert_line -n 4 "default"
+ assert_line -n 3 "cactus"
+ assert_line -n 1 "another"
+ assert_line -n 2 "brother"
+}
+
@test "helpers: migrate plugins and completions that share the same name" {
ln -s $BASH_IT/completion/available/dirs.completion.bash $BASH_IT/completion/enabled/350---dirs.completion.bash
assert_link_exist "$BASH_IT/completion/enabled/350---dirs.completion.bash"
diff --git a/themes/90210/90210.theme.bash b/themes/90210/90210.theme.bash
index 3db3f17b..6b94427a 100644
--- a/themes/90210/90210.theme.bash
+++ b/themes/90210/90210.theme.bash
@@ -1,20 +1,21 @@
# shellcheck shell=bash
# shellcheck disable=SC2034 # Expected behavior for themes.
-# shellcheck disable=SC2154 #TODO: fix these all.
-SCM_THEME_PROMPT_DIRTY=" ${red}✗"
-SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓"
+SCM_THEME_PROMPT_DIRTY=" ${red?}✗"
+SCM_THEME_PROMPT_CLEAN=" ${bold_green?}✓"
SCM_THEME_PROMPT_PREFIX=" |"
-SCM_THEME_PROMPT_SUFFIX="${green}|"
+SCM_THEME_PROMPT_SUFFIX="${green?}|"
-GIT_THEME_PROMPT_DIRTY=" ${red}✗"
-GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓"
-GIT_THEME_PROMPT_PREFIX=" ${green}|"
-GIT_THEME_PROMPT_SUFFIX="${green}|"
+GIT_THEME_PROMPT_DIRTY=" ${red?}✗"
+GIT_THEME_PROMPT_CLEAN=" ${bold_green?}✓"
+GIT_THEME_PROMPT_PREFIX=" ${green?}|"
+GIT_THEME_PROMPT_SUFFIX="${green?}|"
# Nicely formatted terminal prompt
function prompt_command() {
- PS1="\n${bold_black}[${blue}\@${bold_black}]-${bold_black}[${green}\u${yellow}@${green}\h${bold_black}]-${bold_black}[${purple}\w${bold_black}]-$(scm_prompt_info)\n${reset_color}\$ "
+ local scm_prompt_info
+ scm_prompt_info="$(scm_prompt_info)"
+ PS1="\n${bold_black?}[${blue?}\@${bold_black?}]-${bold_black?}[${green?}\u${yellow?}@${green?}\h${bold_black?}]-${bold_black?}[${purple?}\w${bold_black?}]-${scm_prompt_info?}\n${reset_color?}\$ "
}
safe_append_prompt_command prompt_command
diff --git a/themes/bakke/bakke.theme.bash b/themes/bakke/bakke.theme.bash
index d7bfbbe8..a3670b07 100644
--- a/themes/bakke/bakke.theme.bash
+++ b/themes/bakke/bakke.theme.bash
@@ -1,16 +1,15 @@
# shellcheck shell=bash
# shellcheck disable=SC2034 # Expected behavior for themes.
-# shellcheck disable=SC2154 #TODO: fix these all.
-SCM_THEME_PROMPT_DIRTY=" ${red}✗"
-SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓"
+SCM_THEME_PROMPT_DIRTY=" ${red?}✗"
+SCM_THEME_PROMPT_CLEAN=" ${bold_green?}✓"
SCM_THEME_PROMPT_PREFIX=" |"
-SCM_THEME_PROMPT_SUFFIX="${green}|"
+SCM_THEME_PROMPT_SUFFIX="${green?}|"
-GIT_THEME_PROMPT_DIRTY=" ${red}✗"
-GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓"
-GIT_THEME_PROMPT_PREFIX=" ${green}|"
-GIT_THEME_PROMPT_SUFFIX="${green}|"
+GIT_THEME_PROMPT_DIRTY=" ${red?}✗"
+GIT_THEME_PROMPT_CLEAN=" ${bold_green?}✓"
+GIT_THEME_PROMPT_PREFIX=" ${green?}|"
+GIT_THEME_PROMPT_SUFFIX="${green?}|"
RVM_THEME_PROMPT_PREFIX="|"
RVM_THEME_PROMPT_SUFFIX="|"
@@ -19,7 +18,10 @@ function prompt_command() {
#PS1="${bold_cyan}$(scm_char)${green}$(scm_prompt_info)${purple}$(ruby_version_prompt) ${yellow}\h ${reset_color}in ${green}\w ${reset_color}\n${green}→${reset_color} "
#PS1="\n${purple}\h: ${reset_color} ${green}\w\n${bold_cyan}$(scm_char)${green}$(scm_prompt_info) ${green}→${reset_color} "
#PS1="\n${cyan}\h: ${reset_color} ${yellow}\w\n${red}$(scm_char)${red}$(scm_prompt_info) ${green}→${reset_color} "
- PS1="\n${cyan}\h:$(virtualenv_prompt) ${reset_color} ${yellow}\w ${green}$(scm_prompt_info)\n${reset_color}→ "
+ local virtualenv_prompt scm_prompt_info
+ virtualenv_prompt="$(virtualenv_prompt)"
+ scm_prompt_info="$(scm_prompt_info)"
+ PS1="\n${cyan?}\h:${virtualenv_prompt} ${reset_color?} ${yellow?}\w ${green?}${scm_prompt_info}\n${reset_color?}→ "
}
safe_append_prompt_command prompt_command
diff --git a/themes/bira/bira.theme.bash b/themes/bira/bira.theme.bash
index 7db03000..f30d8d5d 100644
--- a/themes/bira/bira.theme.bash
+++ b/themes/bira/bira.theme.bash
@@ -1,24 +1,26 @@
# shellcheck shell=bash
# shellcheck disable=SC2034 # Expected behavior for themes.
-# shellcheck disable=SC2154 #TODO: fix these all.
-SCM_THEME_PROMPT_PREFIX=" ${yellow}‹"
-SCM_THEME_PROMPT_SUFFIX="›${reset_color}"
+SCM_THEME_PROMPT_PREFIX=" ${yellow?}‹"
+SCM_THEME_PROMPT_SUFFIX="›${reset_color?}"
-VIRTUALENV_THEME_PROMPT_PREFIX=" ${cyan}‹"
-VIRTUALENV_THEME_PROMPT_SUFFIX="›${reset_color}"
+VIRTUALENV_THEME_PROMPT_PREFIX=" ${cyan?}‹"
+VIRTUALENV_THEME_PROMPT_SUFFIX="›${reset_color?}"
bold="\[\e[1m\]"
-if [ ${UID} -eq 0 ]; then
- user_host="${bold_red}\u@\h${normal}${reset_color}"
+if [[ ${UID} -eq 0 ]]; then
+ user_host="${bold_red?}\u@\h${normal?}${reset_color?}"
else
- user_host="${bold_green}\u@\h${normal}${reset_color}"
+ user_host="${bold_green?}\u@\h${normal?}${reset_color?}"
fi
function prompt_command() {
- local current_dir=" ${bold_blue}\w${normal}${reset_color}"
- PS1="╭─${user_host}${current_dir}$(virtualenv_prompt)$(scm_prompt_info)\n╰─${bold}\\$ ${normal}"
+ local current_dir=" ${bold_blue?}\w${normal?}${reset_color?}"
+ local virtualenv_prompt scm_prompt_info
+ virtualenv_prompt="$(virtualenv_prompt)"
+ scm_prompt_info="$(scm_prompt_info)"
+ PS1="╭─${user_host?}${current_dir}${virtualenv_prompt}${scm_prompt_info}\n╰─${bold?}\\$ ${normal?}"
}
safe_append_prompt_command prompt_command
diff --git a/themes/codeword/codeword.theme.bash b/themes/codeword/codeword.theme.bash
index beab6a4a..d52403c1 100644
--- a/themes/codeword/codeword.theme.bash
+++ b/themes/codeword/codeword.theme.bash
@@ -1,23 +1,23 @@
# shellcheck shell=bash
-SCM_THEME_PROMPT_PREFIX=${SCM_THEME_PROMPT_SUFFIX}
-SCM_THEME_PROMPT_DIRTY="${bold_red} ✗${normal}"
-SCM_THEME_PROMPT_CLEAN="${bold_green} ✓${normal}"
-SCM_GIT_CHAR="${green}±${normal}"
+SCM_THEME_PROMPT_PREFIX="${SCM_THEME_PROMPT_SUFFIX:-}"
+SCM_THEME_PROMPT_DIRTY="${bold_red?} ✗${normal?}"
+SCM_THEME_PROMPT_CLEAN="${bold_green?} ✓${normal?}"
+SCM_GIT_CHAR="${green?}±${normal?}"
-mark_prompt() {
- echo "${green}\$${normal}"
+function mark_prompt() {
+ echo "${green?}\$${normal?}"
}
-user_host_path_prompt() {
- ps_user="${green}\u${normal}";
- ps_host="${blue}\H${normal}";
- ps_path="${yellow}\w${normal}";
- echo "$ps_user@$ps_host:$ps_path"
+function user_host_path_prompt() {
+ ps_user="${green?}\u${normal?}";
+ ps_host="${blue?}\H${normal?}";
+ ps_path="${yellow?}\w${normal?}";
+ echo "${ps_user?}@${ps_host?}:${ps_path?}"
}
-prompt() {
- SCM_PROMPT_FORMAT=' [%s%s]'
+function prompt() {
+ local SCM_PROMPT_FORMAT=' [%s%s]'
PS1="$(user_host_path_prompt)$(virtualenv_prompt)$(scm_prompt) $(mark_prompt) "
}
diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash
index 7da15cfd..7067dfb8 100644
--- a/themes/powerline/powerline.base.bash
+++ b/themes/powerline/powerline.base.bash
@@ -1,16 +1,15 @@
# shellcheck shell=bash
# shellcheck disable=SC2034 # Expected behavior for themes.
-# shellcheck disable=SC2154 #TODO: fix these all.
# Define this here so it can be used by all of the Powerline themes
THEME_CHECK_SUDO=${THEME_CHECK_SUDO:=true}
function set_color() {
- set +u
- if [[ "${1}" != "-" ]]; then
+ local fg='' bg=''
+ if [[ "${1:-}" != "-" ]]; then
fg="38;5;${1}"
fi
- if [[ "${2}" != "-" ]]; then
+ if [[ "${2:-}" != "-" ]]; then
bg="48;5;${2}"
[[ -n "${fg}" ]] && bg=";${bg}"
fi
@@ -99,14 +98,13 @@ function __powerline_k8s_namespace_prompt() {
}
function __powerline_python_venv_prompt() {
- set +u
local python_venv=""
- if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then
+ if [[ -n "${CONDA_DEFAULT_ENV:-}" ]]; then
python_venv="${CONDA_DEFAULT_ENV}"
PYTHON_VENV_CHAR=${CONDA_PYTHON_VENV_CHAR}
- elif [[ -n "${VIRTUAL_ENV}" ]]; then
- python_venv=$(basename "${VIRTUAL_ENV}")
+ elif [[ -n "${VIRTUAL_ENV:-}" ]]; then
+ python_venv="${VIRTUAL_ENV##*/}"
fi
[[ -n "${python_venv}" ]] && echo "${PYTHON_VENV_CHAR}${python_venv}|${PYTHON_VENV_THEME_PROMPT_COLOR}"
@@ -137,7 +135,7 @@ function __powerline_scm_prompt() {
elif [[ "${SCM_SVN_CHAR}" == "${SCM_CHAR}" ]]; then
scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}"
fi
- echo "$(eval "echo ${scm_prompt}")${scm}|${color}"
+ echo "${scm_prompt?}${scm?}|${color}"
fi
}
@@ -243,12 +241,12 @@ function __powerline_left_segment() {
# Since the previous segment wasn't the last segment, add padding, if needed
#
if [[ "${POWERLINE_COMPACT_BEFORE_SEPARATOR}" -eq 0 ]]; then
- LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}") ${normal}"
+ LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}") ${normal?}"
fi
if [[ "${LAST_SEGMENT_COLOR}" -eq "${params[1]}" ]]; then
- LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}")${POWERLINE_LEFT_SEPARATOR_SOFT}${normal}"
+ LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}")${POWERLINE_LEFT_SEPARATOR_SOFT}${normal?}"
else
- LEFT_PROMPT+="$(set_color "${LAST_SEGMENT_COLOR}" "${params[1]}")${POWERLINE_LEFT_SEPARATOR}${normal}"
+ LEFT_PROMPT+="$(set_color "${LAST_SEGMENT_COLOR}" "${params[1]}")${POWERLINE_LEFT_SEPARATOR}${normal?}"
fi
fi
@@ -258,7 +256,7 @@ function __powerline_left_segment() {
}
function __powerline_left_last_segment_padding() {
- LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}") ${normal}"
+ LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}") ${normal?}"
}
function __powerline_last_status_prompt() {
@@ -285,9 +283,9 @@ function __powerline_prompt_command() {
[[ -n "${info}" ]] && __powerline_left_segment "${info}"
done
- [[ "${last_status}" -ne 0 ]] && __powerline_left_segment "$(__powerline_last_status_prompt ${last_status})"
+ [[ "${last_status}" -ne 0 ]] && __powerline_left_segment "$(__powerline_last_status_prompt "${last_status}")"
- if [[ -n "${LEFT_PROMPT}" ]] && [[ "${POWERLINE_COMPACT_AFTER_LAST_SEGMENT}" -eq 0 ]]; then
+ if [[ -n "${LEFT_PROMPT}" ]] && [[ "${POWERLINE_COMPACT_AFTER_LAST_SEGMENT:-}" -eq 0 ]]; then
__powerline_left_last_segment_padding
fi
@@ -296,11 +294,11 @@ function __powerline_prompt_command() {
prompt_color="$(set_color "${LAST_SEGMENT_COLOR}" -)"
if [[ -n "${LEFT_PROMPT}" ]] && [[ -n "${POWERLINE_LEFT_LAST_SEGMENT_PROMPT_CHAR}" ]]; then
LEFT_PROMPT+="$(set_color - "${LAST_SEGMENT_COLOR}")${POWERLINE_LEFT_LAST_SEGMENT_PROMPT_CHAR}"
- prompt_color="${normal}"
+ prompt_color="${normal?}"
fi
- [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="${prompt_color}${separator_char}${normal}"
+ [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="${prompt_color}${separator_char}${normal?}"
- if [[ "${POWERLINE_COMPACT_PROMPT}" -eq 0 ]]; then
+ if [[ "${POWERLINE_COMPACT_PROMPT:-}" -eq 0 ]]; then
LEFT_PROMPT+=" "
fi
diff --git a/themes/pure/pure.theme.bash b/themes/pure/pure.theme.bash
index 99476f4a..ba83a232 100644
--- a/themes/pure/pure.theme.bash
+++ b/themes/pure/pure.theme.bash
@@ -1,16 +1,15 @@
# shellcheck shell=bash
# shellcheck disable=SC2034 # Expected behavior for themes.
-# shellcheck disable=SC2154 #TODO: fix these all.
# scm theming
SCM_THEME_PROMPT_PREFIX="|"
SCM_THEME_PROMPT_SUFFIX=""
-SCM_THEME_PROMPT_DIRTY=" ${bold_red}✗${normal}"
-SCM_THEME_PROMPT_CLEAN=" ${green}✓${normal}"
-SCM_GIT_CHAR="${green}±${normal}"
-SCM_SVN_CHAR="${bold_cyan}⑆${normal}"
-SCM_HG_CHAR="${bold_red}☿${normal}"
+SCM_THEME_PROMPT_DIRTY=" ${bold_red?}✗${normal?}"
+SCM_THEME_PROMPT_CLEAN=" ${green?}✓${normal?}"
+SCM_GIT_CHAR="${green?}±${normal?}"
+SCM_SVN_CHAR="${bold_cyan?}⑆${normal?}"
+SCM_HG_CHAR="${bold_red?}☿${normal?}"
VIRTUALENV_THEME_PROMPT_PREFIX="("
VIRTUALENV_THEME_PROMPT_SUFFIX=")"
@@ -20,20 +19,23 @@ VIRTUALENV_THEME_PROMPT_SUFFIX=")"
# export LSCOLORS="Gxfxcxdxbxegedabagacad"
# export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'
-pure_prompt() {
- ps_host="${bold_blue}\h${normal}"
- ps_user="${green}\u${normal}"
- ps_user_mark="${green} $ ${normal}"
- ps_root="${red}\u${red}"
- ps_root_mark="${red} # ${normal}"
- ps_path="${yellow}\w${normal}"
+function pure_prompt() {
+ local ps_host="${bold_blue?}\h${normal?}"
+ local ps_user="${green?}\u${normal?}"
+ local ps_user_mark="${green?} $ ${normal?}"
+ local ps_root="${red?}\u${red?}"
+ local ps_root_mark="${red?} # ${normal?}"
+ local ps_path="${yellow?}\w${normal?}"
+ local virtualenv_prompt scm_prompt
+ virtualenv_prompt="$(virtualenv_prompt)"
+ scm_prompt="$(scm_prompt)"
# make it work
- case $(id -u) in
+ case "${EUID:-$UID}" in
0)
- PS1="$(virtualenv_prompt)$ps_root@$ps_host$(scm_prompt):$ps_path$ps_root_mark"
+ PS1="${virtualenv_prompt}${ps_root}@${ps_host}${scm_prompt}:${ps_path}${ps_root_mark}"
;;
*)
- PS1="$(virtualenv_prompt)$ps_user@$ps_host$(scm_prompt):$ps_path$ps_user_mark"
+ PS1="${virtualenv_prompt}${ps_user}@${ps_host}${scm_prompt}:${ps_path}${ps_user_mark}"
;;
esac
}
diff --git a/themes/purity/purity.theme.bash b/themes/purity/purity.theme.bash
index 22a3fbfb..0fc6c4cf 100644
--- a/themes/purity/purity.theme.bash
+++ b/themes/purity/purity.theme.bash
@@ -1,36 +1,44 @@
# shellcheck shell=bash
# shellcheck disable=SC2034 # Expected behavior for themes.
-# shellcheck disable=SC2154 #TODO: fix these all.
-SCM_THEME_PROMPT_DIRTY=" ${bold_red}⊘${normal}"
-SCM_THEME_PROMPT_CLEAN=" ${bold_green}✓${normal}"
-SCM_THEME_PROMPT_PREFIX="${reset_color}( "
-SCM_THEME_PROMPT_SUFFIX=" ${reset_color})"
+SCM_THEME_PROMPT_DIRTY=" ${bold_red?}⊘${normal?}"
+SCM_THEME_PROMPT_CLEAN=" ${bold_green?}✓${normal?}"
+SCM_THEME_PROMPT_PREFIX="${reset_color?}( "
+SCM_THEME_PROMPT_SUFFIX=" ${reset_color?})"
-GIT_THEME_PROMPT_DIRTY=" ${bold_red}⊘${normal}"
-GIT_THEME_PROMPT_CLEAN=" ${bold_green}✓${normal}"
-GIT_THEME_PROMPT_PREFIX="${reset_color}( "
-GIT_THEME_PROMPT_SUFFIX=" ${reset_color})"
+GIT_THEME_PROMPT_DIRTY=" ${bold_red?}⊘${normal?}"
+GIT_THEME_PROMPT_CLEAN=" ${bold_green?}✓${normal?}"
+GIT_THEME_PROMPT_PREFIX="${reset_color?}( "
+GIT_THEME_PROMPT_SUFFIX=" ${reset_color?})"
-STATUS_THEME_PROMPT_BAD="${bold_red}❯${reset_color}${normal} "
-STATUS_THEME_PROMPT_OK="${bold_green}❯${reset_color}${normal} "
-PURITY_THEME_PROMPT_COLOR="${PURITY_THEME_PROMPT_COLOR:=$blue}"
+STATUS_THEME_PROMPT_BAD="${bold_red?}❯${reset_color?}${normal?} "
+STATUS_THEME_PROMPT_OK="${bold_green?}❯${reset_color?}${normal?} "
+: "${PURITY_THEME_PROMPT_COLOR:=$blue}"
-venv_prompt() {
+function venv_prompt() {
python_venv=""
# Detect python venv
- if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then
- python_venv="($PYTHON_VENV_CHAR${CONDA_DEFAULT_ENV}) "
+ if [[ -n "${CONDA_DEFAULT_ENV:-}" ]]; then
+ python_venv="(${PYTHON_VENV_CHAR}${CONDA_DEFAULT_ENV}) "
elif [[ -n "${VIRTUAL_ENV}" ]]; then
- python_venv="($PYTHON_VENV_CHAR$(basename "${VIRTUAL_ENV}")) "
+ python_venv="(${PYTHON_VENV_CHAR}${VIRTUAL_ENV##*/}) "
fi
[[ -n "${python_venv}" ]] && echo "${python_venv}"
}
function prompt_command() {
- local retval=$? ret_status
- ret_status="$([ $retval -eq 0 ] && echo -e "$STATUS_THEME_PROMPT_OK" || echo -e "$STATUS_THEME_PROMPT_BAD")"
- PS1="\n${PURITY_THEME_PROMPT_COLOR}\w $(scm_prompt_info)\n${ret_status}$(venv_prompt)"
+ local retval="$?" ret_status python_venv scm_prompt_info venv_prompt
+ case "${retval}" in
+ 0)
+ ret_status="$STATUS_THEME_PROMPT_OK"
+ ;;
+ *)
+ ret_status="$STATUS_THEME_PROMPT_BAD"
+ ;;
+ esac
+ scm_prompt_info="$(scm_prompt_info)"
+ venv_prompt="$(venv_prompt)"
+ PS1="\n${PURITY_THEME_PROMPT_COLOR}\w ${scm_prompt_info}\n${ret_status}${venv_prompt}"
}
safe_append_prompt_command prompt_command
diff --git a/vendor/github.com/gaelicWizard/bash-progcomp/.editorconfig b/vendor/github.com/gaelicWizard/bash-progcomp/.editorconfig
new file mode 100644
index 00000000..e1eba2cf
--- /dev/null
+++ b/vendor/github.com/gaelicWizard/bash-progcomp/.editorconfig
@@ -0,0 +1,40 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[**.md]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = false
+
+[.git*]
+indent_style = tab
+
+[**.*sh]
+indent_style = tab
+indent_size = tab
+
+shell_variant = bash
+binary_next_line = true # like -bn
+switch_case_indent = false # like -ci
+space_redirects = true # like -sr
+keep_padding = false # like -kp
+function_next_line = true # like -fn
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[**.bats]
+indent_style = tab
+indent_size = tab
+
+shell_variant = bash
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/vendor/github.com/gaelicWizard/bash-progcomp/LICENSE b/vendor/github.com/gaelicWizard/bash-progcomp/LICENSE
new file mode 100644
index 00000000..cd48959a
--- /dev/null
+++ b/vendor/github.com/gaelicWizard/bash-progcomp/LICENSE
@@ -0,0 +1,30 @@
+BSD 3-Clause License
+
+Copyright (c) 2006, Playhaus
+Copyright (c) 2021, gaelicWizard.LLC
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bash b/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bash
new file mode 100644
index 00000000..67cb4fe5
--- /dev/null
+++ b/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bash
@@ -0,0 +1,286 @@
+# shellcheck shell=bash
+# shellcheck disable=SC2207
+#
+# Bash command line completion for defaults
+#
+# Version 1.0 created by Jonathon Mah on 2006-11-08.
+# Version 2.0 written by John Pell on 2021-09-11.
+#
+
+function matchpattern()
+{
+ local PATTERN=${2:?$FUNCNAME: a pattern is required}
+ local SEP=${3:-|}
+ [[ -z "${PATTERN##*${SEP}${1}${SEP}*}" ]]
+}
+
+function _defaults_verbs()
+{
+ local IFS=$'\n' # Treat only newlines as delimiters in string operations.
+ local LC_CTYPE='C' # Do not consider character set in string operations.
+ local LC_COLLATE='C' # Do not consider character set in pattern matching.
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ local prev="${COMP_WORDS[COMP_CWORD - 1]}"
+ COMPREPLY=()
+
+ case $COMP_CWORD in
+ 1)
+ candidates=("${cmds// /$IFS}" "${host_opts[@]}")
+ ;;
+ 2 | 3)
+ candidates=("${cmds// /$IFS}")
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+
+ COMPREPLY=($(compgen -W "${candidates[*]}" | grep -i "^${cur}"))
+ return 0
+}
+
+function _defaults_domains()
+{
+ local IFS=$'\n' # Treat only newlines as delimiters in string operations.
+ local LC_CTYPE='C' # Do not consider character set in string operations.
+ local LC_COLLATE='C' # Do not consider character set in pattern matching.
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ local prev="${COMP_WORDS[COMP_CWORD - 1]}"
+ COMPREPLY=()
+
+ if [[ "$BASH_VERSINFO" -ge 4 ]]
+ then # Exponential performance issue on strings greater than about 10k.
+ local domains="$(defaults domains)"
+ local candidates=($(compgen -W "${domains//, /$IFS}" | grep -i "^${cur}"))
+ else
+ local domains="$(defaults domains | sed -e 's/, /^/g' | tr '^' '\n')"
+ local candidates=($(compgen -W "${domains}" | grep -i "^${cur}"))
+ fi
+ COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
+ if grep -q "^$cur" <<< '-app'
+ then
+ COMPREPLY[${#COMPREPLY[@]}]="-app"
+ elif grep -q "^$cur" <<< '-g'
+ then
+ COMPREPLY[${#COMPREPLY[@]}]="-g"
+ fi
+
+ return 0
+}
+
+function _defaults()
+{
+ local IFS=$'\n' # Treat only newlines as delimiters in string operations.
+ local LC_CTYPE='C' # Do not consider character set in string operations.
+ local LC_COLLATE='C' # Do not consider character set in pattern matching.
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ local prev="${COMP_WORDS[COMP_CWORD - 1]}"
+ COMPREPLY=()
+
+ local host_opts cmds cmd domain keys key_index candidates verbs value_types
+
+ host_opts=('-currentHost' '-host')
+ cmds=' delete domains export find help import read read-type rename write '
+ value_types=('-string' '-data' '-integer' '-float' '-boolean' '-date' '-array' '-array-add' '-dict' '-dict-add')
+
+ case $COMP_CWORD in
+ 1)
+ _defaults_verbs
+ return "$?"
+ ;;
+ 2)
+ case $prev in
+ "-currentHost")
+ _defaults_verbs
+ ;;
+ "-host")
+ _known_hosts -a
+ ;;
+ *)
+ if matchpattern "$prev" "${cmds// /|}"
+ then
+ # TODO: not correct for verbs: domains, find, help
+ _defaults_domains
+ else
+ return 1 # verb is not recognized
+ fi
+ ;;
+ esac
+ return "$?"
+ ;;
+ 3)
+ case ${COMP_WORDS[1]} in
+ "-currentHost")
+ _defaults_domains
+ return "$?"
+ ;;
+ "-host")
+ _defaults_verbs
+ return "$?"
+ ;;
+ esac
+ ;;
+ 4)
+ case ${COMP_WORDS[1]} in
+ "-host")
+ if matchpattern "$prev" "${cmds// /|}"
+ then
+ # TODO: not correct for verbs: domains, find, help
+ _defaults_domains
+ else
+ return 1 # verb is not recognized
+ fi
+ ;;
+ esac
+ ;;
+ esac
+
+ # Both a domain and command have been specified
+
+ case ${COMP_WORDS[1]} in
+ "-currentHost")
+ if matchpattern "${COMP_WORDS[2]}" "${cmds// /|}"
+ then
+ cmd="${COMP_WORDS[2]}"
+ domain="${COMP_WORDS[3]}"
+ key_index=4
+ if [[ "$domain" == "-app" ]]
+ then
+ if [[ $COMP_CWORD -eq 4 ]]
+ then
+ # Completing application name. Can't help here, sorry
+ return 0
+ fi
+ domain="-app ${COMP_WORDS[4]}"
+ key_index=5
+ fi
+ fi
+ ;;
+ "-host")
+ if matchpattern "${COMP_WORDS[3]}" "${cmds// /|}"
+ then
+ cmd="${COMP_WORDS[3]}"
+ domain="${COMP_WORDS[4]}"
+ key_index=5
+ if [[ "$domain" == "-app" ]]
+ then
+ if [[ $COMP_CWORD -eq 5 ]]
+ then
+ # Completing application name. Can't help here, sorry
+ return 0
+ fi
+ domain="-app ${COMP_WORDS[5]}"
+ key_index=6
+ fi
+ fi
+ ;;
+ *)
+ if matchpattern "${COMP_WORDS[1]}" "${cmds// /|}"
+ then
+ cmd="${COMP_WORDS[1]}"
+ domain="${COMP_WORDS[2]}"
+ key_index=3
+ if [[ "$domain" == "-app" ]]
+ then
+ if [[ $COMP_CWORD -eq 3 ]]
+ then
+ # Completing application name. Can't help here, sorry
+ return 0
+ fi
+ domain="-app ${COMP_WORDS[3]}"
+ key_index=4
+ fi
+ fi
+ ;;
+
+ esac
+
+ keys=($(defaults read "$domain" 2> /dev/null | sed -n -e '/^ [^}) ]/p' | sed -e 's/^ \([^" ]\{1,\}\) = .*$/\1/g' -e 's/^ "\([^"]\{1,\}\)" = .*$/\1/g'))
+
+ case $cmd in
+ read | read-type)
+ # Complete key
+ if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
+ then
+ COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
+ fi
+ ;;
+ write)
+ if [[ $key_index -eq $COMP_CWORD ]]
+ then
+ # Complete key
+ if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
+ then
+ COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
+ fi
+ elif [[ $((key_index + 1)) -eq $COMP_CWORD ]]
+ then
+ # Complete value type
+ local cur_type="$(defaults read-type "$domain" "${COMP_WORDS[key_index]}" 2> /dev/null | sed -e 's/^Type is \(.*\)/-\1/' -e's/dictionary/dict/' | grep "^$cur")"
+ if [[ $cur_type ]]
+ then
+ COMPREPLY=("$cur_type")
+ else
+ COMPREPLY=($(compgen -W "${value_types[*]}" -- "$cur"))
+ fi
+ elif [[ $((key_index + 2)) -eq $COMP_CWORD ]]
+ then
+ # Complete value
+ COMPREPLY=($(defaults read "$domain" "${COMP_WORDS[key_index]}" 2> /dev/null | grep -i "^${cur//\\/\\\\}"))
+ fi
+ ;;
+ rename)
+ if [[ $key_index -eq $COMP_CWORD || $((key_index + 1)) -eq $COMP_CWORD ]]
+ then
+ # Complete source and destination keys
+ if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
+ then
+ COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
+ fi
+ fi
+ ;;
+ delete)
+ if [[ $key_index -eq $COMP_CWORD ]]
+ then
+ # Complete key
+ if candidates=($(compgen -W "${keys[*]:-}" | grep -i "^${cur}"))
+ then
+ COMPREPLY=($(printf '%q\n' "${candidates[@]}"))
+ fi
+ fi
+ ;;
+ esac
+
+ return 0
+}
+
+complete -F _defaults -o default defaults
+
+# This file is licensed under the BSD license, as follows:
+#
+# Copyright (c) 2006, Playhaus
+# Copyright (c) 2021, gaelicWizard.LLC
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the names of the authors nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# This software is provided by the copyright holders and contributors "as is"
+# and any express or implied warranties, including, but not limited to, the
+# implied warranties of merchantability and fitness for a particular purpose are
+# disclaimed. In no event shall the copyright owner or contributors be liable
+# for any direct, indirect, incidental, special, exemplary, or consequential
+# damages (including, but not limited to, procurement of substitute goods or
+# services; loss of use, data, or profits; or business interruption) however
+# caused and on any theory of liability, whether in contract, strict liability,
+# or tort (including negligence or otherwise) arising in any way out of the use
+# of this software, even if advised of the possibility of such damage.
diff --git a/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bats b/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bats
new file mode 100755
index 00000000..65b32dad
--- /dev/null
+++ b/vendor/github.com/gaelicWizard/bash-progcomp/defaults.completion.bats
@@ -0,0 +1,184 @@
+#!/usr/bin/env bats
+
+load ../test_helper
+
+function local_setup() {
+ load ../../completion/available/defaults.completion
+ function _known_hosts() { :; }
+ function defaults() { echo 'NSGlobalDomain, Bash It'; }
+}
+
+function __check_completion() {
+ # Get the parameters as a single value
+ COMP_LINE=$*
+
+ # Get the parameters as an array
+ eval set -- "$@"
+ COMP_WORDS=("$@")
+
+ # Index of the cursor in the line
+ COMP_POINT=${#COMP_LINE}
+
+ # Get the last character of the line that was entered
+ COMP_LAST=$((${COMP_POINT} - 1))
+
+ # If the last character was a space...
+ if [[ ${COMP_LINE:$COMP_LAST} = ' ' ]]; then
+ # ...then add an empty array item
+ COMP_WORDS+=('')
+ fi
+
+ # Word index of the last word
+ COMP_CWORD=$(( ${#COMP_WORDS[@]} - 1 ))
+
+ # Run the Bash-it completion function
+ _defaults
+
+ # Return the completion output
+ echo "${COMPREPLY[@]}"
+}
+
+@test "completion defaults: ensure that the _defaults function is available" {
+ type -a _defaults &> /dev/null
+ assert_success
+}
+
+@test "completion defaults: - show verbs and options" {
+ run __check_completion 'defaults '
+ assert_line -n 0 'delete domains export find help import read read-type rename write -currentHost -host'
+}
+
+@test "completion defaults: r* - show matching verbs" {
+ run __check_completion 'defaults r'
+ assert_line -n 0 'read read-type rename'
+}
+
+@test "completion defaults: R* - show matching verbs" {
+ run __check_completion 'defaults R'
+ assert_line -n 0 'read read-type rename'
+}
+
+@test "completion defaults: -* - show matching flags" {
+ run __check_completion 'defaults -'
+ assert_line -n 0 '-currentHost -host'
+}
+
+@test "completion defaults: -currentHost - show verbs" {
+ run __check_completion 'defaults -currentHost '
+ assert_line -n 0 'delete domains export find help import read read-type rename write'
+}
+
+@test "completion defaults: -host - show nothing" {
+ run __check_completion 'defaults -host '
+ assert_line -n 0 "$(_known_hosts -a)"
+}
+
+@test "completion defaults: -host some_computer_name - show verbs" {
+ run __check_completion 'defaults -host some_computer_name '
+ assert_line -n 0 'delete domains export find help import read read-type rename write'
+}
+
+@test "completion defaults: read - show all domains" {
+ run __check_completion 'defaults read '
+ assert_line -n 0 "NSGlobalDomain Bash\ It -app"
+}
+
+@test "completion defaults: read nsg* - show matching domains" {
+ run __check_completion 'defaults read nsg'
+ assert_line -n 0 "NSGlobalDomain"
+}
+
+@test "completion defaults: read NSG* - show matching domains" {
+ run __check_completion 'defaults read NSG'
+ assert_line -n 0 "NSGlobalDomain"
+}
+
+@test "completion defaults: read bash* - show matching domains" {
+ run __check_completion 'defaults read bash'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: read BASH* - show matching domains" {
+ run __check_completion 'defaults read BASH'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: read bash* - show matching domains (with spaces)" {
+ run __check_completion 'defaults read bash\ i'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: read BASH* - show matching domains (with spaces)" {
+ run __check_completion 'defaults read BASH\ I'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -currentHost read - show all domains" {
+ run __check_completion 'defaults -currentHost read '
+ assert_line -n 0 "NSGlobalDomain Bash\ It -app"
+}
+
+@test "completion defaults: -currentHost read nsg* - show matching domains" {
+ run __check_completion 'defaults -currentHost read nsg'
+ assert_line -n 0 "NSGlobalDomain"
+}
+
+@test "completion defaults: -currentHost read NSG* - show matching domains" {
+ run __check_completion 'defaults -currentHost read NSG'
+ assert_line -n 0 "NSGlobalDomain"
+}
+
+@test "completion defaults: -currentHost read bash* - show matching domains" {
+ run __check_completion 'defaults -currentHost read bash'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -currentHost read BASH* - show matching domains" {
+ run __check_completion 'defaults -currentHost read BASH'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -currentHost read bash* - show matching domains (with spaces)" {
+ run __check_completion 'defaults -currentHost read bash\ i'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -currentHost read BASH* - show matching domains (with spaces)" {
+ run __check_completion 'defaults -currentHost read BASH\ I'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -host some.computer.name read - show all domains" {
+ run __check_completion 'defaults -host some.computer.name read '
+ assert_line -n 0 "NSGlobalDomain Bash\ It -app"
+}
+
+@test "completion defaults: -host some.computer.name read nsg* - show matching domains" {
+ run __check_completion 'defaults -host some.computer.name read nsg'
+ assert_line -n 0 "NSGlobalDomain"
+}
+
+@test "completion defaults: -host some.computer.name read NSG* - show matching domains" {
+ run __check_completion 'defaults -host some.computer.name read NSG'
+ assert_line -n 0 "NSGlobalDomain"
+}
+
+@test "completion defaults: -host some.computer.name read bash* - show matching domains" {
+ run __check_completion 'defaults -host some.computer.name read bash'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -host some.computer.name read BASH* - show matching domains" {
+ run __check_completion 'defaults -host some.computer.name read BASH'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -host some.computer.name read bash* - show matching domains (with spaces)" {
+ run __check_completion 'defaults -host some.computer.name read bash\ i'
+ assert_line -n 0 "Bash\ It"
+}
+
+@test "completion defaults: -host some.computer.name read BASH* - show matching domains (with spaces)" {
+ run __check_completion 'defaults -host some.computer.name read BASH\ I'
+ assert_line -n 0 "Bash\ It"
+}
diff --git a/vendor/init.d/preexec.bash b/vendor/init.d/preexec.bash
index 25596dd6..6cfa7b0a 100644
--- a/vendor/init.d/preexec.bash
+++ b/vendor/init.d/preexec.bash
@@ -8,7 +8,7 @@
# Disable immediate `$PROMPT_COMMAND` modification
__bp_delay_install="delayed"
-# shellcheck source=SCRIPTDIR/../github.com/rcaloras/bash-preexec
+# shellcheck source-path=SCRIPTDIR/../github.com/rcaloras/bash-preexec
source "${BASH_IT?}/vendor/github.com/rcaloras/bash-preexec/bash-preexec.sh"
# Block damanaging user's `$HISTCONTROL`