From 24636b6c5e4a892b8573023d4e92f0a2aef1a261 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Wed, 20 Oct 2021 22:42:10 -0400 Subject: [PATCH] lib/search: code cleanup Improve `_bash-it-erase-term()`, `_bash-it-flash-term()`, `_bash-it-rewind()`, `_bash-it-search-result()`, and `_bash-it-search-component()`. Minor tweaks to `_bash-it-is-partial-match()`, and `_bash-it-search()`. --- lib/search.bash | 98 ++++++++++++++++++++++++-------------------- test/lib/search.bats | 30 +++++++------- 2 files changed, 68 insertions(+), 60 deletions(-) mode change 100644 => 100755 test/lib/search.bats diff --git a/lib/search.bash b/lib/search.bash index 98db13c8a6..2da8f0054d 100644 --- a/lib/search.bash +++ b/lib/search.bash @@ -55,7 +55,7 @@ function _bash-it-search() { local component local BASH_IT_SEARCH_USE_COLOR="${BASH_IT_SEARCH_USE_COLOR:=true}" - local -a BASH_IT_COMPONENTS=(aliases plugins completions) + local -a BASH_IT_COMPONENTS=('aliases' 'plugins' 'completions') if [[ $# -eq 0 ]]; then _bash-it-search-help @@ -168,8 +168,8 @@ ${echo_underline_yellow-}SUMMARY${echo_normal-} } function _bash-it-is-partial-match() { - local component="${1?}" - local term="${2?}" + local component="${1?${FUNCNAME[0]}: component type must be specified}" + local term="${2:-}" _bash-it-component-help "${component}" | _bash-it-egrep -i -q -- "${term}" } @@ -191,12 +191,12 @@ function _bash-it-search-component() { _param '3: [-]term4 [-]term5 ...' _example '$ _bash-it-search-component aliases @git rake bundler -chruby' - local component="$1" + local component="${1?${FUNCNAME[0]}: component type must be specified}" shift # if one of the search terms is --enable or --disable, we will apply # this action to the matches further ` down. - local component_singular= action= action_func= + local component_singular action action_func local -a search_commands=('enable' 'disable') for search_command in "${search_commands[@]}"; do if _bash-it-array-contains-element "--${search_command}" "$@"; then @@ -247,30 +247,34 @@ function _bash-it-search-component() { local -a matches=() for match in "${total_matches[@]}"; do - local include_match=true + local -i include_match=1 if [[ ${#negative_terms[@]} -gt 0 ]]; then - (_bash-it-component-term-matches-negation "${match}" "${negative_terms[@]:-}") && include_match=false + _bash-it-component-term-matches-negation "${match}" "${negative_terms[@]:-}" && include_match=0 fi - (${include_match}) && matches+=("${match}") + ((include_match)) && matches+=("${match}") done - _bash-it-search-result "${component}" "${action}" "${action_func}" "${matches[@]:-}" + _bash-it-search-result "${component}" "${action:-}" "${action_func:-}" "${matches[@]:-}" } function _bash-it-search-result() { - local component="$1" + local component="${1?${FUNCNAME[0]}: component type must be specified}" shift - local action="$1" + local action="${1:-}" shift - local action_func="$1" + local action_func="${1:-}" shift - local -a matches=("$@") local color_component color_enable color_disable color_off + local color_sep=':' line - color_sep=':' + local -a matches=() + # Discard any empty arguments + while IFS='' read -r line; do + [[ -n "${line}" ]] && matches+=("$line") + done < <(_bash-it-array-dedup "${@}") - if ${BASH_IT_SEARCH_USE_COLOR}; then + if [[ "${BASH_IT_SEARCH_USE_COLOR}" == "true" ]]; then color_component='\e[1;34m' color_enable='\e[1;32m' suffix_enable='' @@ -290,37 +294,35 @@ function _bash-it-search-result() { local -i modified=0 if [[ "${#matches[@]}" -gt 0 ]]; then - printf "${color_component}%13s${color_sep} ${color_off}" "${component}" + printf "${color_component}%13s${color_sep}${color_off} " "${component}" for match in "${matches[@]}"; do local -i enabled=0 - (_bash-it-component-item-is-enabled "${component}" "${match}") && enabled=1 + _bash-it-component-item-is-enabled "${component}" "${match}" && enabled=1 local match_color compatible_action suffix opposite_suffix - ((enabled)) && { - match_color=${color_enable} - suffix=${suffix_enable} - opposite_suffix=${suffix_disable} + if ((enabled)); then + match_color="${color_enable}" + suffix="${suffix_enable}" + opposite_suffix="${suffix_disable}" compatible_action="disable" - } - - ((enabled)) || { - match_color=${color_disable} - suffix=${suffix_disable} - opposite_suffix=${suffix_enable} + else + match_color="${color_disable}" + suffix="${suffix_disable}" + opposite_suffix="${suffix_enable}" compatible_action="enable" - } + fi - local m="${match}${suffix}" - local -i len=${#m} + local matched="${match}${suffix}" + local -i len="${#matched}" - printf '%b' " ${match_color}${match}${suffix}" # print current state + printf '%b' "${match_color}${matched}" # print current state if [[ "${action}" == "${compatible_action}" ]]; then - if [[ "${action}" == "enable" && "${BASH_IT_SEARCH_USE_COLOR}" == false ]]; then - _bash-it-flash-term "${len}" "${match}${suffix}" + if [[ "${action}" == "enable" && "${BASH_IT_SEARCH_USE_COLOR}" == "true" ]]; then + _bash-it-flash-term "${len}" "${matched}" else - _bash-it-erase-term "${len}" + _bash-it-erase-term "${len}" "${matched}" fi modified=1 # shellcheck disable=SC2034 # no idea if `$result` is ever used @@ -331,38 +333,44 @@ function _bash-it-search-result() { printf '%b' "${match_color}${match}${opposite_suffix}" fi - printf '%b' "${color_off}" + printf '%b' "${color_off} " done - [[ ${modified} -gt 0 ]] && _bash-it-clean-component-cache "${component}" + ((modified)) && _bash-it-clean-component-cache "${component}" printf "\n" fi } function _bash-it-rewind() { - local -i len="$1" + local -i len="${1:-0}" printf '%b' "\033[${len}D" } function _bash-it-flash-term() { - local -i len="${1:-0}" - local match="${2:-}" + local -i len="${1:-0}" # redundant + local term="${2:-}" + # as currently implemented, `$match` has already been printed to screen the first time local delay=0.1 local color + [[ "${#term}" -gt 0 ]] && len="${#term}" for color in "${echo_black-}" "${echo_bold_blue-}" "${echo_bold_yellow-}" "${echo_bold_red-}" "${echo_bold_green-}" "${echo_normal-}"; do sleep "${delay}" _bash-it-rewind "${len}" - printf '%b' "${color}${match}" + printf '%b' "${color}${term}" done } function _bash-it-erase-term() { - local -i len="${1:-0}" + local -i len="${1:-0}" i + local delay=0.05 + local term="${2:-}" # calculate length ourselves + [[ "${#term}" -gt 0 ]] && len="${#term}" + _bash-it-rewind "${len}" - for a in {0..30}; do - [[ ${a} -gt ${len} ]] && break - printf "%.*s" "$a" " " - sleep 0.05 + # white-out the already-printed term by printing blanks + for ((i = 0; i <= len; i++)); do + printf "%.*s" "$i" " " + sleep "${delay}" done } diff --git a/test/lib/search.bats b/test/lib/search.bats old mode 100644 new mode 100755 index 4d2ed614c9..057951a0a5 --- a/test/lib/search.bats +++ b/test/lib/search.bats @@ -28,42 +28,42 @@ function local_teardown { @test "search: plugin base" { export BASH_IT_SEARCH_USE_COLOR=false run _bash-it-search-component 'plugins' 'base' - assert_line -n 0 ' plugins: base ' + assert_line -n 0 ' plugins: base ' } @test "search: git" { run _bash-it-search 'git' --no-color - assert_line -n 0 ' aliases: git gitsvn ' + assert_line -n 0 ' aliases: git gitsvn ' assert_line -n 1 -p ' plugins:' for plugin in "autojump" "git" "gitstatus" "git-subrepo" "jgitflow" "jump" do echo $plugin assert_line -n 1 -p $plugin done - assert_line -n 2 ' completions: git git_flow git_flow_avh github-cli ' + assert_line -n 2 ' completions: git git_flow git_flow_avh github-cli ' } @test "search: ruby gem bundle rake rails" { run _bash-it-search rails ruby gem bundler rake --no-color - assert_line -n 0 ' aliases: bundler rails ' - assert_line -n 1 ' plugins: chruby chruby-auto rails ruby ' - assert_line -n 2 ' completions: bundler gem rake ' + assert_line -n 0 ' aliases: bundler rails ' + assert_line -n 1 ' plugins: chruby chruby-auto rails ruby ' + assert_line -n 2 ' completions: bundler gem rake ' } @test "search: rails ruby gem bundler rake -chruby" { run _bash-it-search rails ruby gem bundler rake -chruby --no-color - assert_line -n 0 ' aliases: bundler rails ' - assert_line -n 1 ' plugins: rails ruby ' - assert_line -n 2 ' completions: bundler gem rake ' + assert_line -n 0 ' aliases: bundler rails ' + assert_line -n 1 ' plugins: rails ruby ' + assert_line -n 2 ' completions: bundler gem rake ' } @test "search: @git" { run _bash-it-search '@git' --no-color - assert_line -n 0 ' aliases: git ' - assert_line -n 1 ' plugins: git ' - assert_line -n 2 ' completions: git ' + assert_line -n 0 ' aliases: git ' + assert_line -n 1 ' plugins: git ' + assert_line -n 2 ' completions: git ' } @test "search: @git --enable / --disable" { @@ -76,7 +76,7 @@ function local_teardown { run _bash-it-search '@git' --disable --no-color run _bash-it-search '@git' --no-color - assert_line -n 0 ' aliases: git ' - assert_line -n 1 ' plugins: git ' - assert_line -n 2 ' completions: git ' + assert_line -n 0 ' aliases: git ' + assert_line -n 1 ' plugins: git ' + assert_line -n 2 ' completions: git ' }