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 61ee4665..8c8b3fed 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -98,6 +98,7 @@ 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/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/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 "![Alternate Text](/path/to/image/or/url)" + ;; + "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 "![Alternate Text](/path/to/image/or/url)" >> $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/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" +}