]> git.tuebingen.mpg.de Git - gsu.git/blobdiff - misc/gsu/subcommand
gsu: Document gsu().
[gsu.git] / misc / gsu / subcommand
index 84c0174ccbdaaf5b7ef8e22bb1a032b485b4c46e..6b5df0a37c2a676c7c86d74c5a07371fddd2e1bf 100644 (file)
@@ -2,7 +2,7 @@
 # (C) 2006-2011 Andre Noll
 
 if [[ $(type -t gsu_is_a_number) != "function" ]]; then
-       GSU_DIR=${GSU_DIR:=$HOME/.gsu}
+       GSU_DIR=${GSU_DIR:=${HOME-}/.gsu}
        . $GSU_DIR/common || exit 1
 fi
 
@@ -11,8 +11,16 @@ _gsu_usage()
        gsu_short_msg "# Usage: $_gsu_self command [options]"
 }
 
-# Each line matching this is recognized as a subcommand. The name of the may be
-# given as $1. In any case the subcommand is the first subexpression.
+# Return an extended regular expression to match against $0.
+#
+# When called without argument, the expression matches all lines which define a
+# subcommand.
+#
+# If an argument is given, the returned expression matches only the subcommand
+# passed as $1. This is useful to tell if a string is a valid subcommand.
+#
+# Regardless of whether an argument is given, the returned expression contains
+# exactly one parenthesized subexpression for matching the command name.
 _gsu_get_command_regex()
 {
        local cmd="${1:-[-a-zA-Z_0-9]+}"
@@ -62,7 +70,7 @@ _gsu_print_available_commands()
 
 gsu_complete_options()
 {
-       local opts="$1" cword="$2" cur
+       local opts="$1" cword="$2" cur opt
        local -a words
 
        shift 2
@@ -90,7 +98,7 @@ options, the command prints out a list of all cmt config variables, together
 with their current value and the default value."
 _com_prefs()
 {
-       local i conf="${gsu_config_file:=$HOME/.$gsu_name.rc}"
+       local i conf="${gsu_config_file:=${HOME:-}/.$gsu_name.rc}"
 
        gsu_getopts "e"
        eval "$result"
@@ -115,7 +123,7 @@ _com_prefs()
                local name= option_type= default_value= required=
                local description= help_text=
                eval "${gsu_options[$i]}"
-               eval val='"$'${gsu_config_var_prefix}_$name'"'
+               eval val='"${'${gsu_config_var_prefix}_$name:-'}"'
                case "$required" in
                true|yes)
                        printf "# required"
@@ -186,13 +194,7 @@ _com_man()
 
 _gsu_banner_msg()
 {
-       local txt="### $_gsu_self --"
-       if test -z "$gsu_banner_txt"; then
-               txt="$txt set \$gsu_banner_txt to customize this message"
-       else
-               txt="$txt $gsu_banner_txt"
-       fi
-       gsu_short_msg "$txt ###"
+       gsu_short_msg "### $_gsu_self -- ###"
 }
 
 export gsu_help_txt="
@@ -208,11 +210,13 @@ Command line completion.
 
 Usage: complete [<cword> <word>...]
 
-In the first form, the command prints all possible completions to stdout.
-This can be used from the completion function of the shell.
+When executed without argument the command writes bash code to
+stdout. This code is suitable to be evaled from .bashrc to enable
+completion.
 
-Completion code suitable to be evaled is written to stdout if no argument
-was given.
+If at least one argument is given, all possible completions are
+written to stdout. This can be used from the completion function of
+the subcommand.
 "
 
 _com_help()
@@ -312,21 +316,20 @@ complete_help()
        echo "$result"
 }
 
-# Wrapper for bash's getopts.
+# Wrapper for the bash getopts builtin.
 #
 # Aborts on programming errors such as missing or invalid option string.  On
 # success $result contains shell code that can be eval'ed. For each defined
 # option x, the local variable o_x will be created when calling eval "$result".
-# o_x contains true/false for options without an argument or the emtpy string/the
-# given argument, depending on whether this option was contained in the "$@"
-# array.
+# o_x contains true/false for options without argument and either the emtpy
+# string or the given argument for options that take an argument.
 #
 # Example:
 #      gsu_getopts abc:x:y
 #      eval "$result"
-#      [[ $ret -lt 0 ]] && return
+#      (($ret < 0)) && return
 #
-#      [[ "$o_a" = "true ]] && echo "The -a flag was given"
+#      [[ "$o_a" = 'true' ]] && echo 'The -a flag was given'
 #      [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c"
 gsu_getopts()
 {
@@ -469,6 +472,62 @@ gsu_cword_is_option_parameter()
        ret=0
 }
 
+# Get the word number on which the cursor is, not counting options.
+#
+# This is useful for completing commands whose possible completions depend
+# on the word number, for example mount.
+#
+# $1:   Getopt option string.
+# $2:   The current word number.
+# $3..: All words of the current command line.
+#
+# return: If the current word is an option, or a parameter to an option,
+# this function sets $result to -1. Otherwise, the number of the non-option
+# is returned in $result.
+#
+gsu_get_unnamed_arg_num()
+{
+       local opts="$1" cword="$2" prev cur
+       local -i i n=0
+       local -a words
+
+       shift 2
+       words=("$@")
+       cur="${words[$cword]}"
+       prev="${words[$(($cword - 1))]}"
+       result=-1
+       [[ "$cur" == -* ]] && return
+       [[ "$prev" == -* ]] && [[ "$opts" == *${prev#-}:* ]] && return
+
+       for ((i=1; i <= $cword; i++)); do
+               prev="${words[$(($i - 1))]}"
+               cur="${words[$i]}"
+               [[ "$cur" == -* ]] && continue
+               if [[ "$prev" == -* ]]; then
+                       opt=${prev#-}
+                       [[ "$opts" != *$opt:* ]] && let n++
+                       continue
+               fi
+               let n++
+       done
+       result="$(($n - 1))"
+}
+
+# Entry point for all gsu-based scripts.
+#
+# The startup part of the application script should source this file to load
+# the functions defined here, and then call gsu(). Functions starting with com_
+# are automatically recognized as subcommands.
+#
+# Minimal example:
+#
+#      com_hello()
+#      {
+#              echo 'hello world'
+#      }
+#      gsu_dir=${gsu_dir:-/system/location/where/gsu/is/installed}
+#      . $gsu_dir/subcommand || exit 1
+#      gsu "$@"
 gsu()
 {
        local i