That's generally the expected behaviour, and it's not too hard to
implement. We let _gsu_menu() take an additional argument for the
default item and maintain its value in _browse().
-In this tree, `hardware/`, `block_devices/` and `log/` are the only
+In this tree, `hardware/`, `storage/` and `log/` are the only
internal nodes. Note that these are written with a trailing slash
character while the leaf nodes have no slash at the end. All entries
of the menu tree must be indented by tab characters.
internal nodes. Note that these are written with a trailing slash
character while the leaf nodes have no slash at the end. All entries
of the menu tree must be indented by tab characters.
-The complete lsi script below can be used as a starting point
-for your own gsu gui application. If you cut and paste it, be
-sure to not turn tab characters into space characters.
+The complete lsi script below can be used as a starting point for your
+own gsu gui application. If you cut and paste it, be sure to not turn
+tab characters into space characters. The script must be named "lsi".
If an option is set both in the environment and in the config file,
the environment takes precedence.
If an option is set both in the environment and in the config file,
the environment takes precedence.
+The `$gsu_config_file` variable can actually contain more than one
+filename, separated by spaces. The config files are processed in
+order, so that an option that is specified in the second config file
+overwrites the definition given in the first. This is useful for
+applications which implement a system-wide config file in addition
+to a per-user config file.
+
___Checking config options___
The gsu config module defines two public functions for this purpose:
___Checking config options___
The gsu config module defines two public functions for this purpose:
----------
- [bash](http://www.gnu.org/software/bash/bash.html)
- [dialog](http://www.invisible-island.net/dialog/dialog.html)
----------
- [bash](http://www.gnu.org/software/bash/bash.html)
- [dialog](http://www.invisible-island.net/dialog/dialog.html)
+- [The author's home page](http://people.tuebingen.mpg.de/maan/)
# file.
gsu_check_options()
{
# file.
gsu_check_options()
{
- local i conf="${gsu_config_file:=${HOME:-}/.$gsu_name.rc}" val orig_val
+ local i f conf="${gsu_config_file:=${HOME:-}/.$gsu_name.rc}" val orig_val
local name option_type default_value required description help_text
for ((i=0; i < ${#gsu_options[@]}; i++)); do
local name option_type default_value required description help_text
for ((i=0; i < ${#gsu_options[@]}; i++)); do
eval orig_${gsu_config_var_prefix}_$name='"'${val}'"'
done
eval orig_${gsu_config_var_prefix}_$name='"'${val}'"'
done
- [[ -r "$conf" ]] && source "$conf"
+ for f in $conf; do
+ [[ -r "$f" ]] && source "$f"
+ done
for ((i=0; i < ${#gsu_options[@]}; i++)); do
name=
for ((i=0; i < ${#gsu_options[@]}; i++)); do
name=
case "$ec" in
0) ret=$GSU_SUCCESS;;
case "$ec" in
0) ret=$GSU_SUCCESS;;
+ 1|255) ret=1;; # cancelled
*)
result="dialog exit code $ec"
ret=-$E_GSU_DIALOG
*)
result="dialog exit code $ec"
ret=-$E_GSU_DIALOG
- local header="${1:-root}"
- local items="$2"
- local i opts num=0
+ local header=${1:-root} dflt_item=$2 items=$3
+ local geom
- opts="$result 16"
- for i in $items; do
- let num++
- opts+=" $i $num"
- done
- result="$(dialog --menu "$gsu_banner_txt ($header)" $opts 3>&1 1>&2 2>&3 3>&-)"
+ geom=$result
+ result="$(dialog --no-lines --no-items \
+ --default-item "$dflt_item" \
+ --menu "$gsu_banner_txt ($header)" \
+ $geom 16 $items 3>&1 1>&2 2>&3 3>&-)"
- local header="$1" old_header
- local tree="$2" subtree="$3"
+ local header=$1 tree=$2
+ local -a subtree=($3)
+ local old_header dflt_item=${subtree[0]}
- _gsu_menu "$header" "$subtree"
+ _gsu_menu "$header" "$dflt_item" "${subtree[*]}"
[[ -z "$result" ]] && return # menu was cancelled
if [[ "${result%/}" != "$result" ]]; then
old_header="$header"
[[ -z "$result" ]] && return # menu was cancelled
if [[ "${result%/}" != "$result" ]]; then
old_header="$header"
# [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c"
gsu_getopts()
{
# [[ -n "$o_c" ]] && echo "The -c option was given with arg $o_c"
gsu_getopts()
{
+ local -i i
+ local c c1 c2 tab=' ' cr='
'
gsu_check_arg_count $# 1 1
'
gsu_check_arg_count $# 1 1
_gsu_print_available_commands()
{
local cmd cmds
_gsu_print_available_commands()
{
local cmd cmds
+ local -i maxlen=0 cols width=80 count=0
+ result=$(stty size 2>/dev/null)
+ if (($? == 0)); then
+ gsu_is_a_number "${result#* }"
+ ((ret >= 0)) && ((result > 0)) && width=$result
+ fi
- cmds="$result"
- printf 'Available commands:\n'
+ cmds=$result
+ for cmd in $cmds; do
+ ((${#cmd} > maxlen)) && maxlen=${#cmd}
+ done
+ let maxlen++
+ ((width < maxlen)) && cols=1 || cols=$((width / maxlen))
+ printf 'Available commands:'
+ ((count % cols == 0)) && printf '\n'
+ printf '%-*s' $maxlen $cmd
- if ((count % 4)); then
- printf '\t'
- ((${#cmd} < 8)) && printf '\t'
- else
- printf '\n'
- fi
+declare -A _gsu_help_text=() # indexed by autocmd
+_gsu_help_text['prefs']='
Print the current preferences.
Usage: prefs [-e]
Print the current preferences.
Usage: prefs [-e]
If -e is given, the config file is opened with the default editor.
Without options, the command prints out a list of all config variables,
together with their current value and the default value.
If -e is given, the config file is opened with the default editor.
Without options, the command prints out a list of all config variables,
together with their current value and the default value.
(($? != 0)) && return
ret=-$E_GSU_EDITOR
result="${EDITOR:-vi}"
(($? != 0)) && return
ret=-$E_GSU_EDITOR
result="${EDITOR:-vi}"
(($? != 0)) && return
ret=$GSU_SUCCESS
return
(($? != 0)) && return
ret=$GSU_SUCCESS
return
[[ "$result" == 'm' ]] && printf 'roff\ntext\nhtml\n'
}
[[ "$result" == 'm' ]] && printf 'roff\ntext\nhtml\n'
}
Print the manual.
Usage: man [-m <mode>] [-b <browser>]
Print the manual.
Usage: man [-m <mode>] [-b <browser>]
fi
if [[ "${line:0:1}" == "$TAB" ]]; then # example
_gsu_change_roffify_state 'state' 'example'
fi
if [[ "${line:0:1}" == "$TAB" ]]; then # example
_gsu_change_roffify_state 'state' 'example'
+ _gsu_print_protected_roff_line "$line"
line="$next_line"
continue
fi
line="$next_line"
continue
fi
- local cmd="$1" help_txt="$2"
- {
- printf 'com_%s()\n' "$cmd"
- sed -e 's/^/## /g' <<< "$help_txt"
- } | _gsu_roffify_cmds
+ for cmd in "${!_gsu_help_text[@]}"; do
+ help_txt="${_gsu_help_text["$cmd"]}"
+ {
+ printf 'com_%s()\n' "$cmd"
+ sed -e 's/^/## /g' <<< "$help_txt"
+ } | _gsu_roffify_cmds
+ done
printf '\n.SH "GENERIC SUBCOMMANDS"\n'
printf 'The following commands are automatically created by gsu\n'
printf '\n.SH "GENERIC SUBCOMMANDS"\n'
printf 'The following commands are automatically created by gsu\n'
- _gsu_roffify_autocmd "help" "$_gsu_help_txt"
- _gsu_roffify_autocmd "man" "$_gsu_man_txt"
- _gsu_roffify_autocmd "prefs" "$_gsu_prefs_txt"
- _gsu_roffify_autocmd "complete" "$_gsu_complete_txt"
printf '\n.SH "LIST OF SUBCOMMANDS"\n'
printf 'Each command has its own set of options as described below.\n'
printf '\n.SH "LIST OF SUBCOMMANDS"\n'
printf 'Each command has its own set of options as described below.\n'
+_gsu_help_text['help']='
+Usage: help [-a] [command]
Without arguments, print the list of available commands. Otherwise,
Without arguments, print the list of available commands. Otherwise,
-print the help text for the given command."
+print the help text for the given command.
+
+-a: Also show the help of automatic commands. Ignored if a command
+is given.'
+_gsu_help_text['complete']='
Command line completion.
Usage: complete [<cword> <word>...]
Command line completion.
Usage: complete [<cword> <word>...]
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.
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.
+ local ere tab=' ' txt
+
+ gsu_getopts "$com_help_options"
+ eval "$result"
+ ((ret < 0)) && return
_gsu_get_command_regex
ere="$result"
_gsu_get_command_regex
ere="$result"
gsu_short_msg "### $gsu_name -- $gsu_banner_txt ###"
_gsu_usage 2>&1
{
gsu_short_msg "### $gsu_name -- $gsu_banner_txt ###"
_gsu_usage 2>&1
{
- printf "com_help()\n%s" "$_gsu_help_txt" | head -n 4; echo "--"
- printf "com_man()\n%s" "$_gsu_man_txt" | head -n 4; echo "--"
- printf "com_prefs()\n%s" "$_gsu_prefs_txt" | head -n 4; echo "--"
- printf "com_complete()\n%s" "$_gsu_complete_txt" | head -n 4; echo "--"
+ if [[ "$o_a" == 'true' ]]; then
+ _gsu_mfcb() { printf '%s\n' "$2"; }
+ for cmd in "${!_gsu_help_text[@]}"; do
+ printf "com_%s()" "$cmd"
+ txt="${_gsu_help_text["$cmd"]}"
+ mapfile -n 3 -c 1 -C _gsu_mfcb <<< "$txt"
+ printf -- '--\n'
+ done
+ fi
grep -EA 2 "$ere" "$0"
} | grep -v -- '--' \
| sed -En "/$ere/"'!d
grep -EA 2 "$ere" "$0"
} | grep -v -- '--' \
| sed -En "/$ere/"'!d
y/\n/'"$tab"'/
# and print the sucker
y/\n/'"$tab"'/
# and print the sucker
- p'
- echo
- echo "# Try $gsu_name help <command> for info on <command>."
- ret=$GSU_SUCCESS
- return
- fi
- if test "$1" = "help"; then
- echo "$_gsu_help_txt"
- ret=$GSU_SUCCESS
- return
- fi
- if test "$1" = "man"; then
- echo "$_gsu_man_txt"
- ret=$GSU_SUCCESS
- return
- fi
- if test "$1" = "prefs"; then
- echo "$_gsu_prefs_txt"
+ p
+ ' | {
+ local -a cmds=() descs=()
+ local -i i maxlen=1
+ local cmd desc
+ while read cmd desc; do
+ ((maxlen < ${#cmd})) && maxlen=${#cmd}
+ cmds[${#cmds[@]}]=$cmd
+ descs[${#descs[@]}]=$desc
+ done
+ for ((i = 0; i < ${#cmds[@]}; i++)); do
+ printf '%-*s %s\n' $maxlen ${cmds[$i]} \
+ "${descs[$i]}"
+ done
+ }
+ printf "\n# Try %s help <command> for info on <command>, or %s help -a to see\n" \
+ "$gsu_name" "$gsu_name"
+ printf '# also the subcommands which are automatically generated by gsu.\n'
ret=$GSU_SUCCESS
return
fi
ret=$GSU_SUCCESS
return
fi
- if test "$1" = "complete"; then
- echo "$_gsu_complete_txt"
+ for cmd in "${!_gsu_help_text[@]}"; do
+ [[ "$1" != "$cmd" ]] && continue
+ printf '%s\n' "${_gsu_help_text["$cmd"]}"
_gsu_get_command_regex "$1"
ere="$result"
if ! grep -Eq "$ere" "$0"; then
_gsu_get_command_regex "$1"
ere="$result"
if ! grep -Eq "$ere" "$0"; then
ret=-$E_GSU_BAD_COMMAND
result="$arg"
gsu_err_msg
ret=-$E_GSU_BAD_COMMAND
result="$arg"
gsu_err_msg
- _gsu_print_available_commands
+ _gsu_print_available_commands 1>&2