Merge pull request #715 from kigster/search-then-enable-disable

Feature: add negations to search, as well as --enable or --disable all of the search results
pull/721/head
Nils Winkler 2016-05-15 16:44:04 +02:00
commit 13b643e93e
6 changed files with 297 additions and 80 deletions

View File

@ -56,25 +56,61 @@ bash-it help plugins # shows help for installed plugins
## Search
If you need to quickly find out which of the plugins, aliases or completions
are available for a specific task or an environment, you can search for
multiple terms related to the commands you use frequently. Search will
find and output modules with the name or description matching the terms
are available for a specific framework, programming language, or an environment, you can _search_ for
multiple terms related to the commands you use frequently. Search will
find and print out modules with the name or description matching the terms
provided.
```
bash-it search term1 [term2] [term3]....
#### Syntax
```bash
bash-it search term1 [[-]term2] [[-]term3]....
```
For example, if you are a ruby developer, you might want to enable everything
related to the commands such as `ruby`, `rake`, `gem`, `bundler` and `rails`.
Search command helps you find related modules, so that you can decide which
As an example, a ruby developer might want to enable everything
related to the commands such as `ruby`, `rake`, `gem`, `bundler` and `rails`.
Search command helps you find related modules, so that you can decide which
of them you'd like to use:
```bash
bash-it search ruby rake gem bundle irb rails
aliases: bundler rails
plugins: chruby chruby-auto ruby
completions: bundler gem rake
```
> bash-it search ruby rake gem bundle irb rails
aliases : bundler rails
plugins : chruby chruby-auto ruby
completions : bundler gem rake
Currently enabled modules will be shown in green.
#### Search with Negations
You can prefix a search term with a "-" to exclude it from the results. In the above
example, if we wanted to hide `chruby` and `chruby-auto`, we could change the command as
follows:
```bash
bash-it search ruby rake gem bundle irb rails -chruby
aliases: bundler rails
plugins: ruby
completions: bundler gem rake
```
#### Using Search to Enable or Disable Components
By adding a `--enable` or `--disable` to the search command, you can automatically
enable all modules that come up as a result of a search query. This could be quite
handy if you like to enable a bunch of components related to the same topic.
#### Disabling ASCII Color
To remove non-printing non-ASCII characters responsible for the coloring of the
search output, you can set environment variable `NO_COLOR`. Enabled components will
then be shown with a checkmark:
```bash
NO_COLOR=1 bash-it search ruby rake gem bundle irb rails -chruby
aliases => ✓bundler ✓rails
plugins => ✓ruby
completions => bundler gem rake
```
## Your Custom scripts, aliases, themes, and functions

56
lib/helpers.bash 100755 → 100644
View File

@ -40,7 +40,7 @@ bash-it ()
example '$ bash-it enable plugin git [tmux]...'
example '$ bash-it disable alias hg [tmux]...'
example '$ bash-it update'
example '$ bash-it search ruby [rake]...'
example '$ bash-it search ruby [[-]rake]... [--enable | --disable]'
typeset verb=${1:-}
shift
typeset component=${1:-}
@ -146,60 +146,6 @@ _bash-it_update() {
cd - &> /dev/null
}
# 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.
#
# Usage:
# bash-it search term1 [term2]...
# Example:
# bash-it search ruby rbenv rvm gem rake
# aliases: bundler
# plugins: chruby chruby-auto rbenv ruby rvm
# completions: gem rake
#
_bash-it-search() {
_about 'searches for given terms amongst bash-it plugins, aliases and completions'
_param '1: term1'
_param '2: [ term2 ]...'
_example '$ _bash-it-search ruby rvm rake bundler'
declare -a _components=(aliases plugins completions)
for _component in "${_components[@]}" ; do
_bash-it-search-component "${_component}" "$*"
done
}
_bash-it-search-component() {
_about 'searches for given terms amongst a given component'
_param '1: component type, one of: [ aliases | plugins | completions ]'
_param '2: term1'
_param '3: [ term2 ]...'
_example '$ _bash-it-search-component aliases rake bundler'
_component=$1
local func=_bash-it-${_component}
local help=$($func)
shift
declare -a terms=($@)
declare -a matches=()
local _grep=$(which egrep || which grep)
for term in "${terms[@]}"; do
local term_match=($(echo "${help}"| ${_grep} -i -- ${term} | cut -d ' ' -f 1 | tr '\n' ' '))
[[ "${#term_match[@]}" -gt 0 ]] && {
matches=(${matches[@]} ${term_match[@]})
}
done
[[ -n "$NO_COLOR" && color_on="" ]] || color_on="\e[1;32m"
[[ -n "$NO_COLOR" && color_off="" ]] || color_off="\e[0;0m"
if [[ "${#matches[*]}" -gt 0 ]] ; then
printf "%-12s: ${color_on}%s${color_off}\n" "${_component}" "$(echo -n ${matches[*]} | tr ' ' '\n' | sort | uniq | tr '\n' ' ' | sed 's/ $//g')"
fi
unset matches
}
_bash-it-describe ()
{
_about 'summarizes available bash_it components'

0
lib/history.bash 100755 → 100644
View File

194
lib/search.bash 100644
View File

@ -0,0 +1,194 @@
#
# Search by Konstantin Gredeskoul «github.com/kigster»
#———————————————————————————————————————————————————————————————————————————————
# 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.
#
# Usage:
# 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.
#
# Examples:
# bash-it search ruby rbenv rvm gem rake
# aliases : bundler
# plugins : chruby chruby-auto rbenv ruby rvm
# completions : gem rake
# bash-it search ruby rbenv rvm gem rake -chruby
# aliases : bundler
# plugins : rbenv ruby rvm
# completions : gem rake
#
# Examples of enabling or disabling results of the search:
#
# bash-it search ruby
# aliases => bundler
# plugins => chruby chruby-auto ruby
#
# bash-it search ruby -chruby --enable
# aliases => ✓bundler
# plugins => ✓ruby
#
#
_bash-it-search() {
_about 'searches for given terms amongst bash-it plugins, aliases and completions'
_param '1: term1'
_param '2: [ term2 ]...'
_example '$ _bash-it-search ruby rvm rake bundler'
declare -a _components=(aliases plugins completions)
for _component in "${_components[@]}" ; do
_bash-it-search-component "${_component}" "$@"
done
}
#———————————————————————————————————————————————————————————————————————————————
# array=("something to search for" "a string" "test2000")
# _bash-it-array-contains-element "a string" "${array[@]}"
# ( prints "true" or "false" )
_bash-it-array-contains-element () {
local e
local r=false
for e in "${@:2}"; do [[ "$e" == "$1" ]] && r=true; done
echo -n $r
}
_bash-it-search-component() {
_about 'searches for given terms amongst a given component'
_param '1: component type, one of: [ aliases | plugins | completions ]'
_param '2: term1 '
_param '3: [-]term2 [-]term3 ...'
_example '$ _bash-it-search-component aliases rake bundler -chruby'
_component=$1
local func=_bash-it-${_component}
local help=$($func)
shift
# if one of the search terms is --enable or --disable, we will apply
# this action to the matches further down.
local action action_func component_singular
declare -a _search_commands=(enable disable)
for _search_command in "${_search_commands[@]}"; do
if [[ $(_bash-it-array-contains-element "--${_search_command}" "$@") == "true" ]]; then
action=$_search_command
component_singular=${_component}
component_singular=${component_singular/es/} # aliases -> alias
component_singular=${component_singular/ns/n} # plugins -> plugin
action_func="_${action}-${component_singular}"
break
fi
done
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
# -- can only be used for the actions: enable/disable
[[ "${term:0:2}" == "--" ]] && continue
[[ "${term:0:1}" == "-" ]] && negative_terms=(${negative_terms[@]} ${term:1}) && continue
# print asterisk next to each result that is already enabled by the user
local term_match=($(echo "${help}"| ${_grep} -i -- ${term} | egrep '\[( |x)\]' | cut -b -30 | sed 's/ *\[ \]//g;s/ *\[x\]/*/g;' ))
[[ "${#term_match[@]}" -gt 0 ]] && {
matches=(${matches[@]} ${term_match[@]}) # append to the list of results
}
done
# 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() {
local action=$1; shift
local action_func=$1; shift
local color_component color_enable color_disable color_off
[[ -z "$NO_COLOR" ]] && {
color_component='\e[1;34m'
color_enable='\e[1;32m'
color_disable='\e[0;0m'
color_off='\e[0;0m'
color_sep=':'
}
[[ -n "$NO_COLOR" ]] && {
color_component=''
color_sep=' => '
color_enable='✓'
color_disable=''
color_off=''
}
if [[ "${#matches[*]}" -gt 0 ]] ; then
printf "${color_component}%13s${color_sep} ${color_off}" "${_component}"
sorted_matches=($(echo "${matches[*]}" | tr ' ' '\n' | sort | uniq))
for match in "${sorted_matches[@]}"; do
local match_color compatible_action
if [[ $match =~ "*" ]]; then
match_color=$color_enable
compatible_action="disable"
else
match_color=$color_disable
compatible_action="enable"
fi
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
printf "\n"
fi
}

View File

@ -7,16 +7,4 @@ cite _about _param _example _group _author _version
load ../../lib/helpers
NO_COLOR=true
@test "helpers search aliases" {
run _bash-it-search-component 'plugins' 'base'
[[ "${lines[0]}" =~ 'plugins' && "${lines[0]}" =~ 'base' ]]
}
@test "helpers search all ruby et al" {
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' ]]
}
## TODO: write some tests.

View File

@ -0,0 +1,53 @@
#!/usr/bin/env bats
load ../../lib/composure
load ../../plugins/available/base.plugin
cite _about _param _example _group _author _version
load ../../lib/helpers
load ../../lib/search
NO_COLOR=true
@test "helpers search aliases" {
run _bash-it-search-component 'plugins' 'base'
[[ "${lines[0]}" =~ 'plugins' && "${lines[0]}" =~ 'base' ]]
}
@test "helpers search ruby gem bundle rake rails" {
# first disable them all, so that the output does not appear with a checkbox
# and we can compoare the result
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails' '--disable'
# Now perform the search
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails'
# And verify
[[ "${lines[0]/✓/}" == ' aliases => bundler rails' ]] && \
[[ "${lines[1]/✓/}" == ' plugins => chruby chruby-auto ruby' ]] && \
[[ "${lines[2]/✓/}" == ' completions => bundler gem rake' ]]
}
@test "search ruby gem bundle -chruby rake rails" {
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' 'rails' '--disable'
run _bash-it-search 'ruby' 'gem' 'bundle' '-chruby' 'rake' 'rails'
[[ "${lines[0]/✓/}" == ' aliases => bundler rails' ]] && \
[[ "${lines[1]/✓/}" == ' plugins => ruby' ]] && \
[[ "${lines[2]/✓/}" == ' completions => bundler gem rake' ]]
}
@test "search (rails enabled) ruby gem bundle rake rails" {
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' ]]
}
@test "search (all enabled) ruby gem bundle rake rails" {
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' '-chruby' 'rails' '--enable'
run _bash-it-search 'ruby' 'gem' 'bundle' 'rake' '-chruby' 'rails'
[[ "${lines[0]}" == ' aliases => ✓bundler ✓rails' ]] && \
[[ "${lines[1]}" == ' plugins => ✓ruby' ]] && \
[[ "${lines[2]}" == ' completions => ✓bundler ✓gem ✓rake' ]]
}