From dbf42ec56d82abc6e99a295326bc2d6c312360e9 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 00:25:20 -0400 Subject: [PATCH 01/23] Changed bash completions for nested commands --- completions/sub.bash | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/completions/sub.bash b/completions/sub.bash index 40eac81..6189577 100644 --- a/completions/sub.bash +++ b/completions/sub.bash @@ -4,10 +4,8 @@ _sub() { if [ "$COMP_CWORD" -eq 1 ]; then COMPREPLY=( $(compgen -W "$(sub commands)" -- "$word") ) - else - local command="${COMP_WORDS[1]}" - local completions="$(sub completions "$command")" - COMPREPLY=( $(compgen -W "$completions" -- "$word") ) + elif [ "$COMP_CWORD" -gt 1 ]; then + COMPREPLY=( $(compgen -W "$(sub commands ${COMP_WORDS[@]})" -- "$word") ) fi } From 24c5845f28f7d0e4a06969b8fa0819f9853109ca Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 00:26:28 -0400 Subject: [PATCH 02/23] Combined sub commands and completions --- libexec/sub-commands | 49 +++++++++++++++++++++++++++++------------ libexec/sub-completions | 14 ------------ 2 files changed, 35 insertions(+), 28 deletions(-) delete mode 100755 libexec/sub-completions diff --git a/libexec/sub-commands b/libexec/sub-commands index 3a88f33..5544981 100755 --- a/libexec/sub-commands +++ b/libexec/sub-commands @@ -23,20 +23,41 @@ fi shopt -s nullglob -{ for path in ${PATH//:/$'\n'}; do - for command in "${path}/sub-"*; do - command="${command##*sub-}" - if [ -n "$sh" ]; then - if [ ${command:0:3} = "sh-" ]; then - echo ${command##sh-} +if [ "$_SUB_COMMAND_IS" == "true" ] && [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [ "$_SUB_COMMAND_FILE" != "commands" ] && [ "$_SUB_COMMAND_FILE" != "help" ]; then + if grep -i "^# provide sub completions" "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" >/dev/null; then + exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@" + fi +else + { for path in ${PATH//:/$'\n'}; do + for command in "${path}/sub-"*; do + if [ ! "$command" == "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" ] || [ "$_SUB_COMMAND_FILE" == "commands" ]; then + if [ -d "$_SUB_COMMAND_ROOT" ] && [ "$_SUB_COMMAND_ROOT" == "$path" ]; then + do_commands="true" + elif [ ! -d "$_SUB_COMMAND_ROOT" ] || [ "$_SUB_COMMAND_ROOT" == "$_SUB_ROOT/libexec" ]; then + do_commands="true" + else + do_commands="false" + fi + elif [ "$command" == "commands" ] && [ "$command" == "$_SUB_COMMAND_FILE" ]; then + do_commands="true" + else + do_commands="false" fi - elif [ -n "$nosh" ]; then - if [ ${command:0:3} != "sh-" ]; then - echo ${command##sh-} + if [ "$do_commands" == "true" ]; then + command="${command##*sub-}" + if [ -n "$sh" ]; then + if [ ${command:0:3} = "sh-" ]; then + echo ${command##sh-} + fi + elif [ -n "$nosh" ]; then + if [ ${command:0:3} != "sh-" ]; then + echo ${command##sh-} + fi + else + echo ${command##sh-} + fi fi - else - echo ${command##sh-} - fi + done done - done -} | sort | uniq + } | sort | uniq +fi diff --git a/libexec/sub-completions b/libexec/sub-completions deleted file mode 100755 index 6771b0e..0000000 --- a/libexec/sub-completions +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -set -e - -COMMAND="$1" -if [ -z "$COMMAND" ]; then - echo "usage: sub completions COMMAND [arg1 arg2...]" >&2 - exit 1 -fi - -COMMAND_PATH="$(command -v "sub-$COMMAND")" -if grep -i "^# provide sub completions" "$COMMAND_PATH" >/dev/null; then - shift - exec "$COMMAND_PATH" --complete "$@" -fi From d64d43a35a5e9dda0dc7adbf4d8390e69d7a6614 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 00:27:00 -0400 Subject: [PATCH 03/23] Modified sub-help for nested commands --- libexec/sub-help | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/libexec/sub-help b/libexec/sub-help index a82d9ae..2fd1bab 100755 --- a/libexec/sub-help +++ b/libexec/sub-help @@ -2,21 +2,36 @@ set -e print_summaries() { + local sub_commands="$(sub commands)" local commands=() local summaries=() local longest_command=0 local command - for command in $(sub-commands); do + if [[ "$0" == *help ]]; then + sub_commands="$(sub commands $_SUB_COMMAND_VARS)" + if [ -f "$sub_commands" ]; then + print_help $sub_commands + exit + fi + fi + + for command in ${sub_commands[@]}; do local file="$(command_path "$command")" - if [ ! -h "$file" ]; then + if [ ! -h "$file" ] && [ -f "$file" ]; then local summary="$(summary "$file")" if [ -n "$summary" ]; then - commands["${#commands[@]}"]="$command" + + if [ -d "$_SUB_COMMAND_ROOT/sub-$command" ]; then + commands["${#commands[@]}"]="-> $command" + else + commands["${#commands[@]}"]="$command" + fi + summaries["${#summaries[@]}"]="$summary" if [ "${#command}" -gt "$longest_command" ]; then - longest_command="${#command}" + longest_command=`expr ${#command} + 3` fi fi fi @@ -47,7 +62,12 @@ print_help() { } command_path() { - command -v "sub-$command" || command -v "sub-sh-$command" || true + sub_path="$(command -v "sub-$command" || command -v "sub-sh-$command" || true)" + if [ "$sub_path" == "" ] && [ -f "$_SUB_COMMAND_ROOT/sub-$command/sub-$command" ]; then + echo "$_SUB_COMMAND_ROOT/sub-$command/sub-$command" + else + echo "$sub_path" + fi } summary() { @@ -80,16 +100,15 @@ if [ "$1" = "--complete" ]; then exit fi -command="$1" -case "$command" in -"") echo "Usage: sub [] +command="$_SUB_COMMAND_FILE" +if [ "$command" == "" ] || [ "$command" == "help" ] || [[ "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]]; then +echo "Usage: sub [] Some useful sub commands are: $(print_summaries) See 'sub help ' for information on a specific command." -;; -*) +else file="$(command_path "$command")" if [ -n "$file" ]; then @@ -98,4 +117,4 @@ See 'sub help ' for information on a specific command." echo "sub: no such command \`$command'" >&2 exit 1 fi -esac +fi From 560c636aa5181773b3bd9c7563480260c7e91ce3 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 00:29:43 -0400 Subject: [PATCH 04/23] Modified sub for nested commands --- libexec/sub | 79 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/libexec/sub b/libexec/sub index 75b757e..7c3bfaf 100755 --- a/libexec/sub +++ b/libexec/sub @@ -19,23 +19,78 @@ abs_dirname() { cd "$cwd" } + libexec_path="$(abs_dirname "$0")" export _SUB_ROOT="$(abs_dirname "$libexec_path")" -export PATH="${libexec_path}:$PATH" + +commands=($@) + +path_builder="$_SUB_ROOT/libexec" +command_builder="" +_SUB_COMMAND_IS="false" +prev_command="" + +for i in $(seq 0 ${#commands[@]}) +do + if [ "${commands[$i]}" != "" ] && [[ "${commands[$i]}" != -* ]]; then + if [ -d "$path_builder/sub-${commands[$i]}" ]; then + path_builder="$path_builder/sub-${commands[$i]}" + fi + if [ -f "$path_builder/sub-${commands[$i]}" ]; then + prev_command=$command_builder + command_builder="${commands[$i]}" + _SUB_COMMAND_IS="true" + else + _SUB_COMMAND_IS="false" + fi + fi + + if [[ "${commands[$i]}" == -* ]]; then + break + fi +done + +flags="" +flags_on="false" +for i in $(seq 0 ${#commands[@]}) +do + if [[ "${commands[$i]}" == -* ]] || [ "$flags_on" == "true" ]; then + flags="$flags${commands[$i]} " + flags_on="true" + fi +done + +export _SUB_COMMAND_ROOT="$path_builder" +export _SUB_COMMAND_FILE="$command_builder" +export _SUB_COMMAND_VARS="$@" +export _SUB_COMMAND_IS="$_SUB_COMMAND_IS" + +if [ -d "$_SUB_COMMAND_ROOT" ]; then + export PATH="${libexec_path}:$_SUB_COMMAND_ROOT:$PATH" +else + export PATH="${libexec_path}:$PATH" +fi command="$1" -case "$command" in -"" | "-h" | "--help" ) +if [ "$command" == "" ] || [ "$command" == "-h" ] || [ "$command" == "-help" ]; then exec sub-help - ;; -* ) + exit +elif [ "$command" == "help" ] || [ "$command" == "commands" ]; then command_path="$(command -v "sub-$command" || true)" - if [ ! -x "$command_path" ]; then - echo "sub: no such command \`$command'" >&2 - exit 1 - fi +else + command_path="$(command -v "sub-$command_builder" || true)" +fi + +if [ ! -x "$command_path" ]; then + echo "sub: no such command \`$command'" >&2 + exit 1 +fi - shift +shift +if [ "$flags" == "" ]; then exec "$command_path" "$@" - ;; -esac +elif [[ "$flags" == *- ]]; then + exec "$command_path" "--complete" $@ +else + exec "$command_path" $flags +fi \ No newline at end of file From b7b7a6a7c81216fe31cccf90e4f1099dd26322be Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 00:32:23 -0400 Subject: [PATCH 05/23] Modified prepare script for sub sub commands --- prepare.sh | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/prepare.sh b/prepare.sh index 4b6301e..aff0450 100755 --- a/prepare.sh +++ b/prepare.sh @@ -1,6 +1,36 @@ #!/usr/bin/env bash set -e +create_sub() { + file="$1" + SUBNAME="$2" + ENVNAME="$3" + sed "s/sub/$SUBNAME/g;s/SUB_ROOT/$ENVNAME/g" "$file" > $(echo $file | sed "s/sub/$SUBNAME/g") + rm $file +} + +chmod_files() { + for file in $1/*; do + chmod a+x $file + done +} + +prepare_sub() { + SUBNAME="$2" + mkdir -p $(echo $1 | sed "s/sub/$SUBNAME/g") + + for file in $1/sub*; do + if [ -d "$file" ]; then + prepare_sub $file $SUBNAME + elif [ -f "$file" ]; then + create_sub $file $SUBNAME $ENVNAME + fi + done + + chmod_files $(echo $1 | sed "s/sub/$SUBNAME/g") + rm -rf $1 +} + NAME="$1" if [ -z "$NAME" ]; then echo "usage: prepare.sh NAME_OF_YOUR_SUB" >&2 @@ -17,13 +47,14 @@ if [ "$NAME" != "sub" ]; then mv share/sub share/$SUBNAME for file in **/sub*; do - sed "s/sub/$SUBNAME/g;s/SUB_ROOT/$ENVNAME/g" "$file" > $(echo $file | sed "s/sub/$SUBNAME/") - rm $file + if [ -d "$file" ]; then + prepare_sub $file $SUBNAME + elif [ -f "$file" ]; then + create_sub $file $SUBNAME $ENVNAME + fi done - for file in libexec/*; do - chmod a+x $file - done + chmod_files "libexec" ln -s ../libexec/$SUBNAME bin/$SUBNAME fi @@ -45,3 +76,4 @@ echo " git add ." echo " git checkout -f" echo echo "Thanks for making a sub!" + From fd5792d5844d74ad8300e9db309966343fc6b551 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 00:44:09 -0400 Subject: [PATCH 06/23] Adding sub-sub-command examples --- libexec/sub-example/sub-advanced/sub-advanced | 8 +++ .../sub-advanced/sub-expert/sub-case-select | 54 +++++++++++++++++++ .../sub-advanced/sub-expert/sub-expert | 6 +++ libexec/sub-example/sub-basic/sub-basic | 8 +++ libexec/sub-example/sub-basic/sub-foreach | 39 ++++++++++++++ libexec/sub-example/sub-example | 8 +++ 6 files changed, 123 insertions(+) create mode 100755 libexec/sub-example/sub-advanced/sub-advanced create mode 100755 libexec/sub-example/sub-advanced/sub-expert/sub-case-select create mode 100755 libexec/sub-example/sub-advanced/sub-expert/sub-expert create mode 100755 libexec/sub-example/sub-basic/sub-basic create mode 100755 libexec/sub-example/sub-basic/sub-foreach create mode 100755 libexec/sub-example/sub-example diff --git a/libexec/sub-example/sub-advanced/sub-advanced b/libexec/sub-example/sub-advanced/sub-advanced new file mode 100755 index 0000000..071ef2b --- /dev/null +++ b/libexec/sub-example/sub-advanced/sub-advanced @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Usage: sub example advanced +# Summary: List all Advanced sub Example Scripts +# Help: This command lists all of the Advanced sub Example Scripts + +set -e + +sub help example bash advanced diff --git a/libexec/sub-example/sub-advanced/sub-expert/sub-case-select b/libexec/sub-example/sub-advanced/sub-expert/sub-case-select new file mode 100755 index 0000000..164d811 --- /dev/null +++ b/libexec/sub-example/sub-advanced/sub-expert/sub-case-select @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Usage: sub example advanced expert case-select +# Summary: BASH Case Select Example +# Help: This is an example of a BASH Case Select + +set -e + +# Provide sub completions +if [ "$1" = "--complete" ]; then + echo --what + echo --break + exit +fi + +what="counter" +break_on=6 +while [ ! "$1" == "" ]; do + case "$1" in + --what) + if [[ ! "$2" == -* ]]; then + what=$2 + shift + else + what="default" + fi + ;; + --break) + if [[ ! "$2" == -* ]]; then + break_on=$2 + shift + else + break_on=3 + fi + ;; + esac + + shift +done + +echo "-=> Executing Case Select Example" +echo "----> Breaking on $break_on" +echo "----> Counter is called $what" + +COUNTER=0 +while [ $COUNTER -lt 5 ]; do + echo "------> The $what is $COUNTER" + COUNTER=`expr $COUNTER + 1` + + if [ "$break_on" == "$COUNTER" ]; then + break + fi +done + +echo "- Finished..." \ No newline at end of file diff --git a/libexec/sub-example/sub-advanced/sub-expert/sub-expert b/libexec/sub-example/sub-advanced/sub-expert/sub-expert new file mode 100755 index 0000000..c62f295 --- /dev/null +++ b/libexec/sub-example/sub-advanced/sub-expert/sub-expert @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# Usage: sub example advanced expert +# Summary: Collection of expert scripts +# Help: Collection of advanced expert sub scripts + +sub help example advanced expert \ No newline at end of file diff --git a/libexec/sub-example/sub-basic/sub-basic b/libexec/sub-example/sub-basic/sub-basic new file mode 100755 index 0000000..f294b55 --- /dev/null +++ b/libexec/sub-example/sub-basic/sub-basic @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Usage: sub example bash basic +# Summary: List all basic sub Example Scripts +# Help: This command lists all of the basic sub Example Scripts + +set -e + +sub help example bash basic diff --git a/libexec/sub-example/sub-basic/sub-foreach b/libexec/sub-example/sub-basic/sub-foreach new file mode 100755 index 0000000..8808e47 --- /dev/null +++ b/libexec/sub-example/sub-basic/sub-foreach @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Usage: sub example basic foreach [--break] +# Summary: BASH For Each Example w/ break loop option +# Help: This command is an example of a BASH For Each Loop with an example of how to break the loop based on an argument parameter + +set -e + +# Provide sub completions +if [ "$1" = "--complete" ]; then + echo --break + exit +fi + +if [ "$1" = "--break" ] && [ ! "$2" == "" ] && [[ ! "$2" == -* ]]; then + break_on=$2 + shift + shift +elif [ "$1" = "--break" ] && [ "$2" == "" ]; then + echo "Defaulting Break On Three" + break_on=3 + shift +else + break_on=6 +fi + +foreach_array=("one" "two" "three" "four" "five") +count=0 + +for array_value in ${foreach_array[@]} +do + if [ "$break_on" == "$count" ]; then + break + else + echo $array_value + fi + count=`expr $count + 1` +done + +echo "done" \ No newline at end of file diff --git a/libexec/sub-example/sub-example b/libexec/sub-example/sub-example new file mode 100755 index 0000000..528f1e7 --- /dev/null +++ b/libexec/sub-example/sub-example @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Usage: sub example +# Summary: Collection of BASH Sub Example Scripts +# Help: These commands are mostly used as examples and for testing sub modifications + +set -e + +sub help example \ No newline at end of file From fbc39c12618ba4d2802db7ad195ca75fa598fb9c Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 02:55:19 -0400 Subject: [PATCH 07/23] Quick change to sub-help --- libexec/sub-help | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/sub-help b/libexec/sub-help index 2fd1bab..f4cf385 100755 --- a/libexec/sub-help +++ b/libexec/sub-help @@ -96,7 +96,7 @@ truncate() { # Provide sub completions if [ "$1" = "--complete" ]; then - exec "sub-commands" + echo "$(sub commands)" exit fi From 019c1ac221a75db77ae646cf297e94c8d178ce8e Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 02:55:35 -0400 Subject: [PATCH 08/23] Got sub-commands auto-complete working --- libexec/sub-commands | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libexec/sub-commands b/libexec/sub-commands index 5544981..6b8cccc 100755 --- a/libexec/sub-commands +++ b/libexec/sub-commands @@ -7,7 +7,7 @@ set -e # Provide sub completions -if [ "$1" = "--complete" ]; then +if [ "$1" == "--complete" ]; then echo --sh echo --no-sh exit @@ -23,7 +23,7 @@ fi shopt -s nullglob -if [ "$_SUB_COMMAND_IS" == "true" ] && [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [ "$_SUB_COMMAND_FILE" != "commands" ] && [ "$_SUB_COMMAND_FILE" != "help" ]; then +if [ "$_SUB_COMMAND_IS" == "true" ] && [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [[ "$_SUB_COMMAND_FILE" == "commands" && ! "$1" == "" && "$3" == "" ]]; then if grep -i "^# provide sub completions" "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" >/dev/null; then exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@" fi From 4278c6fa6734fd8b207fc601820d6c3effefe96e Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 03:57:32 -0400 Subject: [PATCH 09/23] Sub commands working with both bash and zsh --- libexec/sub-commands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/sub-commands b/libexec/sub-commands index 6b8cccc..deb504e 100755 --- a/libexec/sub-commands +++ b/libexec/sub-commands @@ -23,7 +23,7 @@ fi shopt -s nullglob -if [ "$_SUB_COMMAND_IS" == "true" ] && [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [[ "$_SUB_COMMAND_FILE" == "commands" && ! "$1" == "" && "$3" == "" ]]; then +if [[ "$_SUB_COMMAND_IS" == "true" && ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [[ "$2" != "" || "$1" != "" ]]; then if grep -i "^# provide sub completions" "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" >/dev/null; then exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@" fi From 72b8d87ee75f696f1a4effc29f2c4ade20ede70b Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 03:57:55 -0400 Subject: [PATCH 10/23] Added zsh completions for nested sub sub commands --- completions/sub.zsh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/completions/sub.zsh b/completions/sub.zsh index e482490..fd4ea67 100644 --- a/completions/sub.zsh +++ b/completions/sub.zsh @@ -7,12 +7,11 @@ compctl -K _sub sub _sub() { local word words completions read -cA words - word="${words[2]}" if [ "${#words}" -eq 2 ]; then completions="$(sub commands)" - else - completions="$(sub completions "${word}")" + elif [ "${#words}" -gt 2 ]; then + completions="$(sub commands "$words")" fi reply=("${(ps:\n:)completions}") From dd458b1ded687771015571d16fb25373e2e8a402 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 22:49:45 -0400 Subject: [PATCH 11/23] Replaced seq with triple expression --- libexec/sub | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libexec/sub b/libexec/sub index 7c3bfaf..9802e2f 100755 --- a/libexec/sub +++ b/libexec/sub @@ -30,7 +30,7 @@ command_builder="" _SUB_COMMAND_IS="false" prev_command="" -for i in $(seq 0 ${#commands[@]}) +for (( i=0; i<=${#commands[@]}; i++ )) do if [ "${commands[$i]}" != "" ] && [[ "${commands[$i]}" != -* ]]; then if [ -d "$path_builder/sub-${commands[$i]}" ]; then @@ -52,7 +52,7 @@ done flags="" flags_on="false" -for i in $(seq 0 ${#commands[@]}) +for (( i=0; i<=${#commands[@]}; i++ )) do if [[ "${commands[$i]}" == -* ]] || [ "$flags_on" == "true" ]; then flags="$flags${commands[$i]} " From 79a12abc76e54242a72103b0afd3f9102d6f17b1 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Mon, 22 Apr 2013 23:33:55 -0400 Subject: [PATCH 12/23] Renamed example variable --- .../sub-advanced/sub-expert/sub-case-select | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libexec/sub-example/sub-advanced/sub-expert/sub-case-select b/libexec/sub-example/sub-advanced/sub-expert/sub-case-select index 164d811..5c743cc 100755 --- a/libexec/sub-example/sub-advanced/sub-expert/sub-case-select +++ b/libexec/sub-example/sub-advanced/sub-expert/sub-case-select @@ -7,7 +7,7 @@ set -e # Provide sub completions if [ "$1" = "--complete" ]; then - echo --what + echo --name echo --break exit fi @@ -16,12 +16,12 @@ what="counter" break_on=6 while [ ! "$1" == "" ]; do case "$1" in - --what) + --name) if [[ ! "$2" == -* ]]; then - what=$2 + name=$2 shift else - what="default" + name="default" fi ;; --break) @@ -39,11 +39,11 @@ done echo "-=> Executing Case Select Example" echo "----> Breaking on $break_on" -echo "----> Counter is called $what" +echo "----> Counter is called $name" COUNTER=0 while [ $COUNTER -lt 5 ]; do - echo "------> The $what is $COUNTER" + echo "------> The $name is $COUNTER" COUNTER=`expr $COUNTER + 1` if [ "$break_on" == "$COUNTER" ]; then From dc4ee37356b60eb6df5194311c6a900e24772d4e Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Tue, 23 Apr 2013 01:48:27 -0400 Subject: [PATCH 13/23] Added example for auto file completions --- libexec/sub-example/sub-basic/sub-files | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 libexec/sub-example/sub-basic/sub-files diff --git a/libexec/sub-example/sub-basic/sub-files b/libexec/sub-example/sub-basic/sub-files new file mode 100755 index 0000000..cd2684b --- /dev/null +++ b/libexec/sub-example/sub-basic/sub-files @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +# Usage: sub example basic filecomplete +# Summary: Example of auto completion for files +# Help: This is an example of auto completion for files \ No newline at end of file From e134574565d84005f12734a212647ee9dc0a4fc4 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Tue, 23 Apr 2013 01:48:48 -0400 Subject: [PATCH 14/23] Fixes #7 - Example script --- libexec/sub-example/sub-advanced/sub-fix-7 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 libexec/sub-example/sub-advanced/sub-fix-7 diff --git a/libexec/sub-example/sub-advanced/sub-fix-7 b/libexec/sub-example/sub-advanced/sub-fix-7 new file mode 100755 index 0000000..e812ee1 --- /dev/null +++ b/libexec/sub-example/sub-advanced/sub-fix-7 @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Usage: sub example advanced fix-7 +# Summary: Fixes Issue #7 +# Help: Fixes Issue #7: https://github.com/37signals/sub/issues/7 + +set -e + +# Provide sub completions +if [ "$1" = "--complete" ]; then + while [ ! "$1" == "" ]; do + if [ "$1" = "foo" ] || [ "$1" = "bar" ]; then + { echo baz; echo bla; } | sort | uniq + exit + fi + + shift + done + + { echo foo; echo bar; } | sort | uniq + exit; +fi From 254a7f74a39e269470db6befe3557b2b350a9203 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Tue, 23 Apr 2013 01:49:31 -0400 Subject: [PATCH 15/23] Refactoring --- libexec/sub-commands | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libexec/sub-commands b/libexec/sub-commands index deb504e..d3e2a09 100755 --- a/libexec/sub-commands +++ b/libexec/sub-commands @@ -23,10 +23,14 @@ fi shopt -s nullglob -if [[ "$_SUB_COMMAND_IS" == "true" && ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [[ "$2" != "" || "$1" != "" ]]; then +if [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [[ "$2" != "" || "$1" != "" ]]; then if grep -i "^# provide sub completions" "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" >/dev/null; then - exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@" + completions=`exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@"` + if [ "$completions" ]; then + echo $completions + fi fi + exit else { for path in ${PATH//:/$'\n'}; do for command in "${path}/sub-"*; do From 34a4bb9a945340c41f423bc8007902d47c9b4d9c Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Tue, 23 Apr 2013 01:49:42 -0400 Subject: [PATCH 16/23] Refactoring --- libexec/sub | 3 --- 1 file changed, 3 deletions(-) diff --git a/libexec/sub b/libexec/sub index 9802e2f..148c634 100755 --- a/libexec/sub +++ b/libexec/sub @@ -19,7 +19,6 @@ abs_dirname() { cd "$cwd" } - libexec_path="$(abs_dirname "$0")" export _SUB_ROOT="$(abs_dirname "$libexec_path")" @@ -89,8 +88,6 @@ fi shift if [ "$flags" == "" ]; then exec "$command_path" "$@" -elif [[ "$flags" == *- ]]; then - exec "$command_path" "--complete" $@ else exec "$command_path" $flags fi \ No newline at end of file From 1da72dac1cd1fc2f5b2fe03d0e9aba80e22a10de Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Tue, 23 Apr 2013 01:50:11 -0400 Subject: [PATCH 17/23] Fixes Auto File Completion --- completions/sub.bash | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/completions/sub.bash b/completions/sub.bash index 6189577..95a7b3f 100644 --- a/completions/sub.bash +++ b/completions/sub.bash @@ -5,8 +5,13 @@ _sub() { if [ "$COMP_CWORD" -eq 1 ]; then COMPREPLY=( $(compgen -W "$(sub commands)" -- "$word") ) elif [ "$COMP_CWORD" -gt 1 ]; then - COMPREPLY=( $(compgen -W "$(sub commands ${COMP_WORDS[@]})" -- "$word") ) + $commands="$(sub commands ${COMP_WORDS[@]})" + if [ "$commands" ]; then + COMPREPLY=( $(compgen -W "$commands" -- "$word") ) + else + return 1 + fi fi } -complete -F _sub sub +complete -o default -F _sub sub From 8764cfc1d84c244abec650c3103821ad19df4499 Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Tue, 23 Apr 2013 23:58:33 -0400 Subject: [PATCH 18/23] Minor README.md update --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 74d40d6..21eca28 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Sub is a model for setting up shell programs that use subcommands, like `git` or A sub program is run at the command line using this style: $ [name of program] [subcommand] [(args)] + $ [name of program] [subcommand] [subcommand] [(args)] Here's some quick examples: @@ -15,10 +16,13 @@ Here's some quick examples: Each subcommand maps to a separate, standalone executable program. Sub programs are laid out like so: . - ├── bin # contains the main executable for your program - ├── completions # (optional) bash/zsh completions - ├── libexec # where the subcommand executables are - └── share # static data storage + ├── bin # contains the main executable for your program + ├── completions # (optional) bash/zsh completions + ├── libexec # where the subcommand executables are + ├───> sub-command # sub command (Displays summary for b & c) + | ├────∎ sub-command-b # sub command command-b + | └────∎ sub-command-c # sub command command-c + └── share # static data storage ## Subcommands @@ -49,8 +53,7 @@ You can run *any* executable in the `libexec` directly, as long as it follows th You get a few commands that come with your sub: -* `commands`: Prints out every subcommand available -* `completions`: Helps kick off subcommand autocompletion. +* `commands`: Prints out every subcommand available and kicks off autocompletion * `help`: Document how to use each subcommand * `init`: Shows how to load your sub with autocompletions, based on your shell. * `shell`: Helps with calling subcommands that might be named the same as builtin/executables. From 2bf26a95d313558d966949b3bebe74d0acd24f3e Mon Sep 17 00:00:00 2001 From: Jeffrey Roberts Date: Wed, 24 Apr 2013 20:27:32 -0400 Subject: [PATCH 19/23] small typo in bash completions --- completions/sub.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions/sub.bash b/completions/sub.bash index 95a7b3f..ee54b8d 100644 --- a/completions/sub.bash +++ b/completions/sub.bash @@ -5,7 +5,7 @@ _sub() { if [ "$COMP_CWORD" -eq 1 ]; then COMPREPLY=( $(compgen -W "$(sub commands)" -- "$word") ) elif [ "$COMP_CWORD" -gt 1 ]; then - $commands="$(sub commands ${COMP_WORDS[@]})" + commands="$(sub commands ${COMP_WORDS[@]})" if [ "$commands" ]; then COMPREPLY=( $(compgen -W "$commands" -- "$word") ) else From 95a123e2f929d4a326a4e77667d0154622de4b0a Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Sun, 28 Apr 2013 10:34:25 -0400 Subject: [PATCH 20/23] Added ability to have help on root sub-sub-command --- libexec/sub-help | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/libexec/sub-help b/libexec/sub-help index f4cf385..a17632a 100755 --- a/libexec/sub-help +++ b/libexec/sub-help @@ -94,6 +94,31 @@ truncate() { fi } +print_command_help() { + local file="$1" + local usage="$(usage "$file")" + + if [ -n "$usage" ]; then + echo "$usage" + + local help="$(help "$file")" + [ -n "$help" ] && echo && echo "$help" + + local _SUB_SUMMARY="$(print_summaries)" + + if [ ! "$_SUB_SUMMARY" == "" ]; then + echo " +Some useful sub $command commands are: + +$(print_summaries) + +See 'sub help $command' for information on a specific command." + fi + else + echo "Sorry, this command isn't documented yet." + fi +} + # Provide sub completions if [ "$1" = "--complete" ]; then echo "$(sub commands)" @@ -101,18 +126,23 @@ if [ "$1" = "--complete" ]; then fi command="$_SUB_COMMAND_FILE" -if [ "$command" == "" ] || [ "$command" == "help" ] || [[ "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]]; then -echo "Usage: sub [] +if [[ "$command" == "" || "$command" == "help" ]] && [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]]; then +echo "Usage: sub $command [] -Some useful sub commands are: +Some useful sub $command commands are: $(print_summaries) -See 'sub help ' for information on a specific command." +See 'sub help $command' for information on a specific command." + else file="$(command_path "$command")" if [ -n "$file" ]; then - print_help "$file" + if [[ "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]]; then + print_command_help "$file" + else + print_help "$file" + fi else echo "sub: no such command \`$command'" >&2 exit 1 From 13797c3f535505ebe68e953c4e2d8791af19244b Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Sun, 28 Apr 2013 10:34:49 -0400 Subject: [PATCH 21/23] Removed auto complete from sub commands, it was breaking help --- libexec/sub-commands | 69 +++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/libexec/sub-commands b/libexec/sub-commands index d3e2a09..8ca75cb 100755 --- a/libexec/sub-commands +++ b/libexec/sub-commands @@ -6,13 +6,6 @@ set -e -# Provide sub completions -if [ "$1" == "--complete" ]; then - echo --sh - echo --no-sh - exit -fi - if [ "$1" = "--sh" ]; then sh=1 shift @@ -23,45 +16,43 @@ fi shopt -s nullglob -if [[ ! "$_SUB_COMMAND_ROOT" == *sub-$_SUB_COMMAND_FILE ]] && [[ "$2" != "" || "$1" != "" ]]; then - if grep -i "^# provide sub completions" "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" >/dev/null; then - completions=`exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@"` - if [ "$completions" ]; then - echo $completions - fi +if grep -i "^# provide sub completions" "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" >/dev/null; then + completions=`exec "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" --complete "$@"` + if [ "$completions" ]; then + echo $completions fi exit -else - { for path in ${PATH//:/$'\n'}; do - for command in "${path}/sub-"*; do - if [ ! "$command" == "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" ] || [ "$_SUB_COMMAND_FILE" == "commands" ]; then - if [ -d "$_SUB_COMMAND_ROOT" ] && [ "$_SUB_COMMAND_ROOT" == "$path" ]; then - do_commands="true" - elif [ ! -d "$_SUB_COMMAND_ROOT" ] || [ "$_SUB_COMMAND_ROOT" == "$_SUB_ROOT/libexec" ]; then - do_commands="true" - else - do_commands="false" - fi - elif [ "$command" == "commands" ] && [ "$command" == "$_SUB_COMMAND_FILE" ]; then +fi + +{ for path in ${PATH//:/$'\n'}; do + for command in "${path}/sub-"*; do + if [ ! "$command" == "$_SUB_COMMAND_ROOT/sub-$_SUB_COMMAND_FILE" ] || [ "$_SUB_COMMAND_FILE" == "commands" ]; then + if [ -d "$_SUB_COMMAND_ROOT" ] && [ "$_SUB_COMMAND_ROOT" == "$path" ]; then + do_commands="true" + elif [ ! -d "$_SUB_COMMAND_ROOT" ] || [ "$_SUB_COMMAND_ROOT" == "$_SUB_ROOT/libexec" ]; then do_commands="true" else do_commands="false" fi - if [ "$do_commands" == "true" ]; then - command="${command##*sub-}" - if [ -n "$sh" ]; then - if [ ${command:0:3} = "sh-" ]; then - echo ${command##sh-} - fi - elif [ -n "$nosh" ]; then - if [ ${command:0:3} != "sh-" ]; then - echo ${command##sh-} - fi - else + elif [ "$command" == "commands" ] && [ "$command" == "$_SUB_COMMAND_FILE" ]; then + do_commands="true" + else + do_commands="false" + fi + if [ "$do_commands" == "true" ]; then + command="${command##*sub-}" + if [ -n "$sh" ]; then + if [ ${command:0:3} = "sh-" ]; then + echo ${command##sh-} + fi + elif [ -n "$nosh" ]; then + if [ ${command:0:3} != "sh-" ]; then echo ${command##sh-} fi + else + echo ${command##sh-} fi - done + fi done - } | sort | uniq -fi + done +} | sort | uniq From 138b12407a677c2fe52a4be6504dc716ece65a0d Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Sun, 28 Apr 2013 10:35:04 -0400 Subject: [PATCH 22/23] Minor edit --- libexec/sub-example/sub-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/sub-example/sub-example b/libexec/sub-example/sub-example index 528f1e7..e3aa041 100755 --- a/libexec/sub-example/sub-example +++ b/libexec/sub-example/sub-example @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Usage: sub example +# Usage: sub example [command] # Summary: Collection of BASH Sub Example Scripts # Help: These commands are mostly used as examples and for testing sub modifications From d1d41081e736dc89f04fe99f5f65ce0ceed16bfd Mon Sep 17 00:00:00 2001 From: "Jeffrey L. Roberts" Date: Sun, 28 Apr 2013 10:47:32 -0400 Subject: [PATCH 23/23] Did some debugging --- libexec/sub-help | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libexec/sub-help b/libexec/sub-help index a17632a..971a034 100755 --- a/libexec/sub-help +++ b/libexec/sub-help @@ -2,6 +2,7 @@ set -e print_summaries() { + local sub_commands="$(sub commands)" local commands=() local summaries=() @@ -112,7 +113,7 @@ Some useful sub $command commands are: $(print_summaries) -See 'sub help $command' for information on a specific command." +See 'sub $_SUB_COMMAND_VARS [command]' for information on a specific command." fi else echo "Sorry, this command isn't documented yet." @@ -132,7 +133,7 @@ echo "Usage: sub $command [] Some useful sub $command commands are: $(print_summaries) -See 'sub help $command' for information on a specific command." +See 'sub $_SUB_COMMAND_VARS' for information on a specific command." else file="$(command_path "$command")"