Enable/Disable with negated search feature

pull/715/head
Konstantin Gredeskoul 2016-05-07 06:26:30 -07:00
parent fb6a6c80c0
commit 9bb2d377a8
3 changed files with 112 additions and 32 deletions

View File

@ -40,7 +40,7 @@ bash-it ()
example '$ bash-it enable plugin git [tmux]...' example '$ bash-it enable plugin git [tmux]...'
example '$ bash-it disable alias hg [tmux]...' example '$ bash-it disable alias hg [tmux]...'
example '$ bash-it update' example '$ bash-it update'
example '$ bash-it search ruby [rake]...' example '$ bash-it search ruby [[-]rake]... [--enable | --disable]'
typeset verb=${1:-} typeset verb=${1:-}
shift shift
typeset component=${1:-} typeset component=${1:-}

View File

@ -1,13 +1,27 @@
#
# Search by Konstantin Gredeskoul «github.com/kigster»
#———————————————————————————————————————————————————————————————————————————————
# This function returns list of aliases, plugins and completions in bash-it, # This function returns list of aliases, plugins and completions in bash-it,
# whose name or description matches one of the search terms provided as arguments. # whose name or description matches one of the search terms provided as arguments.
# #
# Usage: # Usage:
# bash-it search term1 [term2]... # bash-it search term1 [[-]term2] ... [[-]termN] [ --enable | --disable ]
#
# Exmplanation:
# Single dash, as in "-chruby", indicates a negative search term.
# Double dash indicates a command that is to be applied to the search result.
# At the moment only --enable and --disable are supported.
#
# Example: # Example:
# bash-it search ruby rbenv rvm gem rake # bash-it search ruby rbenv rvm gem rake
# aliases: bundler # aliases : bundler
# plugins: chruby chruby-auto rbenv ruby rvm # plugins : chruby chruby-auto rbenv ruby rvm
# completions: gem rake # completions : gem rake
# bash-it search ruby rbenv rvm gem rake -chruby
# aliases : bundler
# plugins : rbenv ruby rvm
# completions : gem rake
# #
_bash-it-search() { _bash-it-search() {
@ -23,7 +37,7 @@ _bash-it-search() {
done done
} }
# #———————————————————————————————————————————————————————————————————————————————
# array=("something to search for" "a string" "test2000") # array=("something to search for" "a string" "test2000")
# _bash-it-array-contains-element "a string" "${array[@]}" # _bash-it-array-contains-element "a string" "${array[@]}"
# ( prints "true" or "false" ) # ( prints "true" or "false" )
@ -37,9 +51,9 @@ _bash-it-array-contains-element () {
_bash-it-search-component() { _bash-it-search-component() {
_about 'searches for given terms amongst a given component' _about 'searches for given terms amongst a given component'
_param '1: component type, one of: [ aliases | plugins | completions ]' _param '1: component type, one of: [ aliases | plugins | completions ]'
_param '2: term1' _param '2: term1 '
_param '3: [ term2 ]...' _param '3: [-]term2 [-]term3 ...'
_example '$ _bash-it-search-component aliases rake bundler' _example '$ _bash-it-search-component aliases rake bundler -chruby'
_component=$1 _component=$1
@ -48,63 +62,120 @@ _bash-it-search-component() {
shift shift
# if one of the search terms is --enable or --disable, we will apply # if one of the search terms is --enable or --disable, we will apply
# this action to the result set interactively. # this action to the matches further down.
local cmd action component_singular local action action_func component_singular
declare -a _search_commands=(enable disable) declare -a _search_commands=(enable disable)
for _search_command in "${_search_commands[@]}"; do for _search_command in "${_search_commands[@]}"; do
if [[ $(_bash-it-array-contains-element "--${_search_command}" "$@") == "true" ]]; then if [[ $(_bash-it-array-contains-element "--${_search_command}" "$@") == "true" ]]; then
cmd=$_search_command action=$_search_command
component_singular=${_component} component_singular=${_component}
component_singular=${component_singular/es/} # aliases -> alias component_singular=${component_singular/es/} # aliases -> alias
component_singular=${component_singular/ns/n} # plugins -> plugin component_singular=${component_singular/ns/n} # plugins -> plugin
action="_${cmd}-${component_singular}" action_func="_${action}-${component_singular}"
break break
fi fi
done done
declare -a terms=($@)
declare -a matches=()
local _grep=$(which egrep || which grep) local _grep=$(which egrep || which grep)
declare -a terms=($@) # passed on the command line
declare -a matches=() # results that we found
declare -a negative_terms=() # terms that began with a dash
for term in "${terms[@]}"; do for term in "${terms[@]}"; do
if [[ "${term}" =~ "--" ]]; then # -- can only be used for the actions: enable/disable
continue [[ "${term:0:2}" == "--" ]] && continue
fi [[ "${term:0:1}" == "-" ]] && negative_terms=(${negative_terms[@]} ${term:1}) && continue
# print asterisk next to each command that is already enabled
# print asterisk next to each result that is already enabled by the user
local term_match=($(echo "${help}"| ${_grep} -i -- ${term} | cut -b -30 | sed 's/ *\[ \]//g;s/ *\[x\]/*/g;' )) local term_match=($(echo "${help}"| ${_grep} -i -- ${term} | cut -b -30 | sed 's/ *\[ \]//g;s/ *\[x\]/*/g;' ))
[[ "${#term_match[@]}" -gt 0 ]] && { [[ "${#term_match[@]}" -gt 0 ]] && {
matches=(${matches[@]} ${term_match[@]}) matches=(${matches[@]} ${term_match[@]}) # append to the list of results
} }
done done
_bash-it-search-result $action # "${matches[@]}"
unset matches # now check if we found any negative terms, and subtract them
[[ ${#negative_terms} -gt 0 ]] && {
declare -a filtered_matches=()
for match in "${matches[@]}"; do
local negations=0
for nt in "${negative_terms[@]}"; do
[[ "${match}" =~ "${nt}" ]] && negations=$(($negations+1))
done
[[ $negations -eq 0 ]] && filtered_matches=(${filtered_matches[@]} ${match})
done
matches=(${filtered_matches[@]})
}
_bash-it-search-result $action $action_func
unset matches filtered_matches terms
} }
_bash-it-search-result() { _bash-it-search-result() {
local action=shift local action=$1; shift
local action_func=$1; shift
local color_component color_enable color_disable color_off local color_component color_enable color_disable color_off
[[ -z "$NO_COLOR" ]] && { [[ -z "$NO_COLOR" ]] && {
color_component='\e[0;33m' color_component='\e[1;34m'
color_enable='\e[1;32m' color_enable='\e[1;32m'
color_disable='\e[0;0m' color_disable='\e[0;0m'
color_off='\e[0;0m' color_off='\e[0;0m'
color_sep=':'
} }
[[ -n "$NO_COLOR" ]] && { [[ -n "$NO_COLOR" ]] && {
color_enable='*' color_component=''
color_sep=' => '
color_enable='✓'
color_disable=''
color_off=''
} }
if [[ "${#matches[*]}" -gt 0 ]] ; then if [[ "${#matches[*]}" -gt 0 ]] ; then
printf "${color_component}%-12s:${color_off} " "${_component}" printf "${color_component}%13s${color_sep} ${color_off}" "${_component}"
sorted_matches=($(echo "${matches[*]}" | tr ' ' '\n' | sort | uniq)) sorted_matches=($(echo "${matches[*]}" | tr ' ' '\n' | sort | uniq))
for match in "${sorted_matches[@]}"; do for match in "${sorted_matches[@]}"; do
local match_color local match_color compatible_action
if [[ $match =~ "*" ]]; then if [[ $match =~ "*" ]]; then
match_color=$color_enable match_color=$color_enable
compatible_action="disable"
else else
match_color=$color_disable match_color=$color_disable
compatible_action="enable"
fi fi
printf " ${match_color}${match/\*/}${color_off}"
match_value=${match/\*/} # remove asterisk
len=${#match_value}
if [[ -n $NO_COLOR ]]; then
local m="${match_color}${match_value}"
len=${#m}
fi
printf " ${match_color}${match_value}" # print current state
if [[ "${action}" == "${compatible_action}" ]]; then
# oh, i see we need to either disable enabled, or enable disabled
# component. Let's start with the most important part: redrawing
# the search result backwards. Because style.
printf "\033[${len}D"
for a in {0..30}; do
[[ $a -gt $len ]] && break
printf "%.*s" $a " "
sleep 0.07 # who knew you could sleep for fraction of the cost :)
done
printf "\033[${len}D"
result=$(${action_func} ${match_value})
local temp="color_${compatible_action}"
match_color=${!temp}
printf "${match_color}${match_value}"
fi
printf "${color_off}"
done done
printf "\n" printf "\n"

View File

@ -17,7 +17,16 @@ NO_COLOR=true
@test "helpers search all ruby et al" { @test "helpers search all ruby et al" {
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails' run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails'
[[ "${lines[0]/\*/}" == 'aliases : bundler rails' ]] [[ "${lines[0]/✓/}" == ' aliases => bundler rails' ]]
[[ "${lines[1]/\*/}" == 'plugins : chruby chruby-auto ruby' ]] [[ "${lines[1]/✓/}" == ' plugins => chruby chruby-auto ruby' ]]
[[ "${lines[2]/\*/}" == 'completions : bundler gem rake' ]] [[ "${lines[2]/✓/}" == ' completions => bundler gem rake' ]]
}
@test "search enable and disable" {
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails' '--disable'
run _enable-alias 'rails'
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails'
[[ "${lines[0]}" == ' aliases => bundler ✓rails' ]]
[[ "${lines[1]}" == ' plugins => chruby chruby-auto ruby' ]]
[[ "${lines[2]}" == ' completions => bundler gem rake' ]]
} }