2 # (C) 2006-2011 Andre Noll
4 if [[ "$(type -t _gsu_setup)" != "function" ]]; then
5 gsu_dir=${gsu_dir:-${BASH_SOURCE[0]%/*}}
6 . $gsu_dir/common || exit 1
12 gsu_short_msg "# Usage: $gsu_name command [options]"
15 # Return an extended regular expression to match against $0.
17 # When called without argument, the expression matches all lines which define a
20 # If an argument is given, the returned expression matches only the subcommand
21 # passed as $1. This is useful to tell if a string is a valid subcommand.
23 # Regardless of whether an argument is given, the returned expression contains
24 # exactly one parenthesized subexpression for matching the command name.
25 _gsu_get_command_regex()
27 local cmd="${1:-[-a-zA-Z_0-9]+}"
28 result="^com_($cmd)\(\)"
31 _gsu_available_commands()
35 _gsu_get_command_regex
38 printf "help\nman\nprefs\ncomplete\n"
40 # if line matches, isolate command name
43 # if there is a match, (print it and) start next cycle
49 } | sort | tr '\n' ' ')"
52 _gsu_print_available_commands()
57 printf 'Available commands:\n'
58 for cmd in $gsu_cmds; do
61 if (($count % 4)); then
63 ((${#cmd} < 8)) && printf '\t'
71 # Print all options of the given optstring to stdout if the word in the current
72 # command line begins with a hyphen character.
73 gsu_complete_options()
75 local opts="$1" cword="$2" cur opt
80 cur="${words[$cword]}"
82 [[ ! "$cur" == -* ]] && return
85 for ((i=0; i < ${#opts}; i++)); do
87 [[ "$opt" == ":" ]] && continue
93 export gsu_prefs_txt="
94 Print the current preferences.
98 If -e is given, the config file is opened with the default editor. Without
99 options, the command prints out a list of all cmt config variables, together
100 with their current value and the default value."
103 local i conf="${gsu_config_file:=${HOME:-}/.$gsu_name.rc}"
107 (($ret < 0)) && return
108 gsu_check_arg_count $# 0 0
109 (($ret < 0)) && return
111 if [[ "$o_e" == "true" ]]; then
115 (($? != 0)) && return
117 result="${EDITOR:-vi}"
119 (($? != 0)) && return
124 for ((i=0; i < ${#gsu_options[@]}; i++)); do
125 local name= option_type= default_value= required=
126 local description= help_text=
127 eval "${gsu_options[$i]}"
128 eval val='"${'${gsu_config_var_prefix}_$name:-'}"'
137 printf " $option_type: $description"
138 if [[ "$required" != "yes" && "$required" != "true" ]]; then
139 printf " [$default_value]"
142 [[ -n "$help_text" ]] && sed -e '/^[ ]*$/d; s/^[ ]*/# /g' <<< "$help_text"
144 [[ "$val" == "$default_value" ]] && printf " # default"
151 gsu_complete_options "e" "$@"
161 local equal_signs="=================================================="
162 local minus_signs="--------------------------------------------------"
165 echo "$gsu_name (_${gsu_banner_txt}_) manual"
166 echo "${equal_signs:0:${#gsu_name} + ${#gsu_banner_txt} + 16}"
169 sed -e '1,/^#\{70,\}/d' -e '/^#\{70,\}/,$d' $0 -e 's/^# *//'
172 echo "$gsu_name usage"
173 echo "${minus_signs:0:${#gsu_name} + 6}"
176 echo "Each command has its own set of options as described below."
180 echo "Available commands:"
182 _gsu_available_commands
183 for com in $result; do
185 (($num < 4)) && num=4
186 echo "${minus_signs:0:$num}"
188 echo "${minus_signs:0:$num}"
195 export gsu_help_txt="
198 Usage: help [command]
200 Without arguments, print the list of available commands. Otherwise,
201 print the help text for the given command."
203 export gsu_complete_txt="
204 Command line completion.
206 Usage: complete [<cword> <word>...]
208 When executed without argument the command writes bash code to
209 stdout. This code is suitable to be evaled from .bashrc to enable
212 If at least one argument is given, all possible completions are
213 written to stdout. This can be used from the completion function of
219 local a b ere tab=' '
221 _gsu_get_command_regex
225 gsu_short_msg "### $gsu_name -- $gsu_banner_txt ###"
228 printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--"
229 printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--"
230 printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--"
231 printf "com_complete()\n$gsu_complete_txt" | head -n 4; echo "--"
233 } | grep -v -- '--' \
234 | sed -En "/$ere/"'!d
235 # remove everything but the command name
236 s/^com_(.*)\(\).*/\1/
238 # append tab after short commands (less than 8 chars)
239 s/^(.{1,7})$/\1'"$tab"'/g
241 # remove next line (should contain only ## anyway)
245 # append next line, removing leading ##
249 # replace newline by tab
252 # and print the sucker
255 echo "# Try $gsu_name help <command> for info on <command>."
259 if test "$1" = "help"; then
264 if test "$1" = "man"; then
269 if test "$1" = "prefs"; then
270 echo "$gsu_prefs_txt"
274 if test "$1" = "complete"; then
275 echo "$gsu_complete_txt"
280 _gsu_get_command_regex "$1"
282 if ! grep -Eq "$ere" $0; then
283 _gsu_print_available_commands
285 ret=-$E_GSU_BAD_COMMAND
289 # only consider lines in the comment of the function
295 # if it did start with ##, jump to label p and print it
298 # otherwise, move on to next line
310 _gsu_available_commands
314 # Wrapper for the bash getopts builtin.
316 # Aborts on programming errors such as missing or invalid option string. On
317 # success $result contains shell code that can be eval'ed. For each defined
318 # option x, the local variable o_x will be created when calling eval "$result".
319 # o_x contains true/false for options without argument and either the empty
320 # string or the given argument for options that take an argument.
323 # gsu_getopts abc:x:y
325 # (($ret < 0)) && return
327 # [[ "$o_a" = 'true' ]] && echo 'The -a flag was given'
328 # [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c"
331 local i c tab=' ' cr='
334 gsu_check_arg_count $# 1 1
335 if (($ret < 0)); then
341 result="invalid optstring $1"
342 if [[ -z "$1" ]] || grep -q '::' <<< "$1" ; then
347 for ((i=0; i < ${#1}; i++)); do
353 result="invalid character $c in optstring"
358 result="local _gsu_getopts_opt"
359 for ((i=0; i < ${#1}; i++)); do
361 c2=${1:$(($i + 1)):1}
363 if [[ "$c2" = ":" ]]; then
371 while getopts $1 _gsu_getopts_opt \"\$@\"; do
372 case \"\$_gsu_getopts_opt\" in
374 for ((i=0; i < ${#1}; i++)); do
376 c2=${1:$(($i + 1)):1}
377 result+="$tab$tab$c1) o_$c1="
378 if [[ "$c2" = ":" ]]; then
379 result+="\"\$OPTARG\""
389 result=\"invalid option given\"
394 shift \$((\$OPTIND - 1))
406 local cur="\${COMP_WORDS[\$COMP_CWORD]}";
409 candidates=(\$($0 complete "\$COMP_CWORD" "\${COMP_WORDS[@]}"));
410 COMPREPLY=(\$(compgen -W "\${candidates[*]}" -- "\$cur"));
417 gsu_is_a_number "$cword"
418 (($ret < 0)) && return
419 if (($cword <= 1)); then
420 _gsu_available_commands
428 ret=$GSU_SUCCESS # It's not an error if no completer was defined
429 [[ "$(type -t complete_$cmd)" != "function" ]] && return
430 complete_$cmd "$cword" "${words[@]}"
431 # ignore errors, they would only clutter the completion output
435 # Find out if the current word is a parameter for an option.
437 # $1: usual getopts option string.
438 # $2: The current word number.
439 # $3..: All words of the current command line.
441 # return: If yes, $result contains the letter of the option for which the
442 # current word is a parameter. Otherwise, $result is empty.
444 gsu_cword_is_option_parameter()
446 local opts="$1" cword="$2" prev i n
450 (($cword == 0)) && return
451 ((${#opts} < 2)) && return
455 prev="${words[$(($cword - 1))]}"
456 [[ ! "$prev" == -* ]] && return
459 for ((i=0; i <= $n; i++)); do
461 [[ "${opts:$(($i + 1)):1}" != ":" ]] && continue
463 [[ "$prev" != "-$opt" ]] && continue
470 # Get the word number on which the cursor is, not counting options.
472 # This is useful for completing commands whose possible completions depend
473 # on the word number, for example mount.
475 # $1: Getopt option string.
476 # $2: The current word number.
477 # $3..: All words of the current command line.
479 # return: If the current word is an option, or a parameter to an option,
480 # this function sets $result to -1. Otherwise, the number of the non-option
481 # is returned in $result.
483 gsu_get_unnamed_arg_num()
485 local opts="$1" cword="$2" prev cur
491 cur="${words[$cword]}"
492 prev="${words[$(($cword - 1))]}"
494 [[ "$cur" == -* ]] && return
495 [[ "$prev" == -* ]] && [[ "$opts" == *${prev#-}:* ]] && return
497 for ((i=1; i <= $cword; i++)); do
498 prev="${words[$(($i - 1))]}"
500 [[ "$cur" == -* ]] && continue
501 if [[ "$prev" == -* ]]; then
503 [[ "$opts" != *$opt:* ]] && let n++
511 # Entry point for all gsu-based scripts.
513 # The startup part of the application script should source this file to load
514 # the functions defined here, and then call gsu(). Functions starting with com_
515 # are automatically recognized as subcommands.
523 # gsu_dir=${gsu_dir:-/system/location/where/gsu/is/installed}
524 # . $gsu_dir/subcommand || exit 1
529 _gsu_available_commands
533 _gsu_print_available_commands
538 # check internal commands
539 if [[ "$arg" = "help" || "$arg" = "man" || "$arg" = "prefs" || "$arg" = "complete" ]]; then
541 if (("$ret" < 0)); then
549 for i in $gsu_cmds; do
550 if test "$arg" = "$i"; then
552 if (("$ret" < 0)); then
560 ret=-$E_GSU_BAD_COMMAND
563 _gsu_print_available_commands
567 # Check number of arguments.
569 # Usage: gsu_check_arg_count <num_given> <num1> [<num2>]
571 # Check that <num_given> is between <num1> and <num2> inclusively.
572 # If only <num1> ist given, num2 is assumed to be infinity.
575 # 0 0 no argument allowed
576 # 1 1 exactly one argument required
577 # 0 2 at most two arguments admissible
578 # 2 at least two arguments required
579 gsu_check_arg_count()
581 ret=-$E_GSU_BAD_ARG_COUNT
582 if (($# == 2)); then # only num1 is given
583 result="at least $2 args required, $1 given"
584 (($1 < $2)) && return
588 # num1 and num2 given
589 result="need at least $2 args, $1 given"
590 (($1 < $2)) && return
591 result="need at most $3 args, $1 given"
592 (($1 > $3)) && return