X-Git-Url: http://git.tuebingen.mpg.de/?p=gsu.git;a=blobdiff_plain;f=misc%2Fgsu%2Fsubcommand;h=6b5df0a37c2a676c7c86d74c5a07371fddd2e1bf;hp=84c0174ccbdaaf5b7ef8e22bb1a032b485b4c46e;hb=1098785778a242838668df8c45f4a07d1690b06c;hpb=0f548f1367bfdba2e270242bb0fccad1da5f8adf diff --git a/misc/gsu/subcommand b/misc/gsu/subcommand index 84c0174..6b5df0a 100644 --- a/misc/gsu/subcommand +++ b/misc/gsu/subcommand @@ -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 [ ...] -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