2 # (C) 2006-2011 Andre Noll
4 if [[ $(type -t gsu_is_a_number) != "function" ]]; then
5 GSU_DIR=${GSU_DIR:=$HOME/.gsu}
6 . $GSU_DIR/common || exit 1
11 gsu_short_msg "# Usage: $_gsu_self command [options]"
14 # Each line matching this is recognized as a subcommand. The name of the may be
15 # given as $1. In any case the subcommand is the first subexpression.
16 _gsu_get_command_regex()
18 local cmd="${1:-[-a-zA-Z_0-9]+}"
19 result="^com_($cmd)\(\)"
22 _gsu_available_commands()
26 _gsu_get_command_regex
29 printf "help\nman\nprefs\ncomplete\n"
31 # if line matches, isolate command name
34 # if there is a match, (print it and) start next cycle
40 } | sort | tr '\n' ' ')"
43 _gsu_print_available_commands()
46 gsu_short_msg "Available commands:"
47 for i in $gsu_cmds; do
50 if test $(($count % 4)) -eq 0; then
54 if test ${#i} -lt 8; then
63 gsu_complete_options()
65 local opts="$1" cword="$2" cur
70 cur="${words[$cword]}"
72 [[ ! "$cur" == -* ]] && return
75 for ((i=0; i < ${#opts}; i++)); do
77 [[ "$opt" == ":" ]] && continue
83 export gsu_prefs_txt="
84 Print the current preferences.
88 If -e is given, the config file is opened with the default editor. Without
89 options, the command prints out a list of all cmt config variables, together
90 with their current value and the default value."
93 local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}"
97 (($ret < 0)) && return
98 gsu_check_arg_count $# 0 0
99 (($ret < 0)) && return
101 if [[ "$o_e" == "true" ]]; then
105 [[ $? -ne 0 ]] && return
107 result="${EDITOR:-vi}"
109 [[ $? -ne 0 ]] && return
114 for ((i=0; i < ${#gsu_options[@]}; i++)); do
115 local name= option_type= default_value= required=
116 local description= help_text=
117 eval "${gsu_options[$i]}"
118 eval val='"$'${gsu_config_var_prefix}_$name'"'
127 printf " $option_type: $description"
128 if [[ "$required" != "yes" && "$required" != "true" ]]; then
129 printf " [$default_value]"
132 [[ -n "$help_text" ]] && sed -e '/^[ ]*$/d; s/^[ ]*/# /g' <<< "$help_text"
134 [[ "$val" == "$default_value" ]] && printf " # default"
141 gsu_complete_options "e" "$@"
151 local equal_signs="=================================================="
152 local minus_signs="--------------------------------------------------"
155 echo "$_gsu_self (_${gsu_banner_txt}_) manual"
156 echo "${equal_signs:0:${#_gsu_self} + ${#gsu_banner_txt} + 16}"
159 sed -e '1,/^#\{70,\}/d' -e '/^#\{70,\}/,$d' $0 -e 's/^# *//'
162 echo "$_gsu_self usage"
163 echo "${minus_signs:0:${#_gsu_self} + 6}"
166 echo "Each command has its own set of options as described below."
170 echo "Available commands:"
172 _gsu_available_commands
173 for com in $result; do
175 if test $num -lt 4; then
178 echo "${minus_signs:0:$num}"
180 echo "${minus_signs:0:$num}"
189 local txt="### $_gsu_self --"
190 if test -z "$gsu_banner_txt"; then
191 txt="$txt set \$gsu_banner_txt to customize this message"
193 txt="$txt $gsu_banner_txt"
195 gsu_short_msg "$txt ###"
198 export gsu_help_txt="
201 Usage: help [command]
203 Without arguments, print the list of available commands. Otherwise,
204 print the help text for the given command."
206 export gsu_complete_txt="
207 Command line completion.
209 Usage: complete [<cword> <word>...]
211 In the first form, the command prints all possible completions to stdout.
212 This can be used from the completion function of the shell.
214 Completion code suitable to be evaled is written to stdout if no argument
220 local a b ere tab=' '
222 _gsu_get_command_regex
229 printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--"
230 printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--"
231 printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--"
232 printf "com_complete()\n$gsu_complete_txt" | head -n 4; echo "--"
234 } | grep -v -- '--' \
235 | sed -En "/$ere/"'!d
236 # remove everything but the command name
237 s/^com_(.*)\(\).*/\1/
239 # append tab after short commands (less than 8 chars)
240 s/^(.{1,7})$/\1'"$tab"'/g
242 # remove next line (should contain only ## anyway)
246 # append next line, removing leading ##
250 # replace newline by tab
253 # and print the sucker
256 echo "# Try $_gsu_self help <command> for info on <command>."
260 if test "$1" = "help"; then
265 if test "$1" = "man"; then
270 if test "$1" = "prefs"; then
271 echo "$gsu_prefs_txt"
275 if test "$1" = "complete"; then
276 echo "$gsu_complete_txt"
281 _gsu_get_command_regex "$1"
283 if ! grep -Eq "$ere" $0; then
284 _gsu_print_available_commands
286 ret=-$E_GSU_BAD_COMMAND
290 # only consider lines in the comment of the function
296 # if it did start with ##, jump to label p and print it
299 # otherwise, move on to next line
311 _gsu_available_commands
315 # Wrapper for bash's getopts.
317 # Aborts on programming errors such as missing or invalid option string. On
318 # success $result contains shell code that can be eval'ed. For each defined
319 # option x, the local variable o_x will be created when calling eval "$result".
320 # o_x contains true/false for options without an argument or the emtpy string/the
321 # given argument, depending on whether this option was contained in the "$@"
325 # gsu_getopts abc:x:y
327 # [[ $ret -lt 0 ]] && return
329 # [[ "$o_a" = "true ]] && echo "The -a flag was given"
330 # [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c"
333 local i c tab=' ' cr='
336 gsu_check_arg_count $# 1 1
337 if [[ $ret -lt 0 ]]; then
343 result="invalid optstring $1"
344 if [[ -z "$1" ]] || grep -q '::' <<< "$1" ; then
349 for ((i=0; i < ${#1}; i++)); do
355 result="invalid character $c in optstring"
360 result="local _gsu_getopts_opt"
361 for ((i=0; i < ${#1}; i++)); do
363 c2=${1:$(($i + 1)):1}
365 if [[ "$c2" = ":" ]]; then
373 while getopts $1 _gsu_getopts_opt \"\$@\"; do
374 case \"\$_gsu_getopts_opt\" in
376 for ((i=0; i < ${#1}; i++)); do
378 c2=${1:$(($i + 1)):1}
379 result+="$tab$tab$c1) o_$c1="
380 if [[ "$c2" = ":" ]]; then
381 result+="\"\$OPTARG\""
391 result=\"invalid option given\"
396 shift \$((\$OPTIND - 1))
403 local cmd n cword="$1"
408 local cur="\${COMP_WORDS[\$COMP_CWORD]}";
411 candidates=(\$($0 complete "\$COMP_CWORD" "\${COMP_WORDS[@]}"));
412 COMPREPLY=(\$(compgen -W "\${candidates[*]}" -- "\$cur"));
416 [[ -z "$cword" ]] && return
417 if (($cword <= 1)); then
418 _gsu_available_commands
426 ret=$GSU_SUCCESS # It's not an error if no completer was defined
427 [[ "$(type -t complete_$cmd)" != "function" ]] && return
428 complete_$cmd "$cword" "${words[@]}"
429 # ignore errors, they would only clutter the completion output
433 gsu_cword_is_option_parameter()
435 local opts="$1" cword="$2" prev i n
439 (($cword == 0)) && return
440 ((${#opts} < 2)) && return
444 prev="${words[$(($cword - 1))]}"
445 [[ ! "$prev" == -* ]] && return
448 for ((i=0; i < $n; i++)); do
450 [[ "${opts:$(($i + 1)):1}" != ":" ]] && continue
452 [[ "$prev" != "-$opt" ]] && continue
463 _gsu_available_commands
465 if test $# -eq 0; then
467 _gsu_print_available_commands
472 # check internal commands
473 if [[ "$arg" = "help" || "$arg" = "man" || "$arg" = "prefs" || "$arg" = "complete" ]]; then
475 if [[ "$ret" -lt 0 ]]; then
483 for i in $gsu_cmds; do
484 if test "$arg" = "$i"; then
486 if [[ "$ret" -lt 0 ]]; then
494 ret=-$E_GSU_BAD_COMMAND
497 _gsu_print_available_commands
501 # Check number of arguments.
503 # Usage: gsu_check_arg_count <num_given> <num1> [<num2>]
505 # Check that <num_given> is between <num1> and <num2> inclusively.
506 # If only <num1> ist given, num2 is assumed to be infinity.
509 # 0 0 no argument allowed
510 # 1 1 exactly one argument required
511 # 0 2 at most two arguments admissible
512 # 2 at least two arguments reqired
514 gsu_check_arg_count()
516 ret=-$E_GSU_BAD_ARG_COUNT
517 if [[ $# -eq 2 ]]; then # only num1 is given
518 result="at least $2 args required, $1 given"
519 [[ $1 -lt $2 ]] && return
523 # num1 and num2 given
524 result="need at least $2 args, $1 given"
525 [[ $1 -lt $2 ]] && return
526 result="need at most $3 args, $1 given"
527 [[ $1 -gt $3 ]] && return