]> git.tuebingen.mpg.de Git - gsu.git/commitdiff
gui: Remember menu position. master
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 22 Aug 2023 16:06:57 +0000 (18:06 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 29 Oct 2023 00:57:03 +0000 (02:57 +0200)
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().

README.md
config
gui
subcommand

index 81768f5aec5ee8dbab1bb952a9d282ce49a688cc..44e111fb00b363f848bb72d36596163d5329e519 100644 (file)
--- a/README.md
+++ b/README.md
@@ -444,7 +444,7 @@ tree could look like this:
                                dmesg
                '
 
                                dmesg
                '
 
-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.
@@ -496,9 +496,9 @@ to do is to source the gsu gui module and to call `gsu_gui()`:
 
 ___Example___
 
 
 ___Example___
 
-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".
 
                #!/bin/bash
 
 
                #!/bin/bash
 
@@ -651,6 +651,13 @@ following two statements are equivalent
 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:
@@ -727,3 +734,4 @@ References
 ----------
 - [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/)
diff --git a/config b/config
index 70a83f1e59372765bed900ce9b9fd13dafcc7bc1..6152679d623e9b4b7873f9a92ca1c8557c301840 100644 (file)
--- a/config
+++ b/config
@@ -6,7 +6,7 @@
 # file.
 gsu_check_options()
 {
 # file.
 gsu_check_options()
 {
-       local i conf="${gsu_config_file:=${HOME:-}/.$gsu_name.rc}" val orig_val
+       local i 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
@@ -15,7 +15,9 @@ gsu_check_options()
                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=
diff --git a/gui b/gui
index 42975647e6900bb67c900c8108cc9925e4022739..fbcbb01e49dce6d7c6e55045c5286e2652411549 100644 (file)
--- a/gui
+++ b/gui
@@ -30,7 +30,7 @@ _set_dialog_ret()
 
        case "$ec" in
        0) ret=$GSU_SUCCESS;;
 
        case "$ec" in
        0) ret=$GSU_SUCCESS;;
-       1) ret=1;; # cancelled
+       1|255) ret=1;; # cancelled
        *)
                result="dialog exit code $ec"
                ret=-$E_GSU_DIALOG
        *)
                result="dialog exit code $ec"
                ret=-$E_GSU_DIALOG
@@ -95,17 +95,15 @@ gsu_msgbox()
 
 _gsu_menu()
 {
 
 _gsu_menu()
 {
-       local header="${1:-root}"
-       local items="$2"
-       local i opts num=0
+       local header=${1:-root} dflt_item=$2 items=$3
+       local geom
 
        _get_geometry
 
        _get_geometry
-       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>&-)"
        _set_dialog_ret $?
 }
 
        _set_dialog_ret $?
 }
 
@@ -156,12 +154,14 @@ _get_root_nodes()
 
 _browse()
 {
 
 _browse()
 {
-       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]}
 
        while :; do
 
        while :; do
-               _gsu_menu "$header" "$subtree"
+               _gsu_menu "$header" "$dflt_item" "${subtree[*]}"
                ((ret < 0)) && return
                ((ret < 0)) && return
+               dflt_item=$result
                [[ -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"
index 5e55580013dad9ec224e8c11a8e191b18c00428e..d37481cdbdccb5b62268d3b788de84b61a2ab347 100644 (file)
@@ -96,7 +96,8 @@ gsu_check_arg_count()
 #      [[ -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 c tab=' ' cr='
+       local -i i
+       local c c1 c2 tab='     ' cr='
 '
 
        gsu_check_arg_count $# 1 1
 '
 
        gsu_check_arg_count $# 1 1
@@ -167,20 +168,25 @@ gsu_getopts()
 _gsu_print_available_commands()
 {
        local cmd cmds
 _gsu_print_available_commands()
 {
        local cmd cmds
-       local -i count=0
+       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
        _gsu_available_commands
        _gsu_available_commands
-       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:'
        for cmd in $cmds; do
        for cmd in $cmds; do
-               printf '%s' "$cmd"
+               ((count % cols == 0)) && printf '\n'
+               printf '%-*s' $maxlen $cmd
                let ++count
                let ++count
-               if ((count % 4)); then
-                       printf '\t'
-                       ((${#cmd} < 8)) && printf '\t'
-               else
-                       printf '\n'
-               fi
        done
        printf '\n'
 }
        done
        printf '\n'
 }
@@ -208,9 +214,10 @@ gsu_complete_options()
        ret=1
 }
 
        ret=1
 }
 
+declare -A _gsu_help_text=() # indexed by autocmd
 com_prefs_options='e'
 
 com_prefs_options='e'
 
-_gsu_prefs_txt="
+_gsu_help_text['prefs']='
 Print the current preferences.
 
 Usage: prefs [-e]
 Print the current preferences.
 
 Usage: prefs [-e]
@@ -218,7 +225,7 @@ 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.
-"
+'
 
 com_prefs()
 {
 
 com_prefs()
 {
@@ -237,7 +244,7 @@ com_prefs()
                (($? != 0)) && return
                ret=-$E_GSU_EDITOR
                result="${EDITOR:-vi}"
                (($? != 0)) && return
                ret=-$E_GSU_EDITOR
                result="${EDITOR:-vi}"
-               "$result" "$conf"
+               "$result" $conf
                (($? != 0)) && return
                ret=$GSU_SUCCESS
                return
                (($? != 0)) && return
                ret=$GSU_SUCCESS
                return
@@ -289,7 +296,7 @@ complete_man()
        [[ "$result" == 'm' ]] && printf 'roff\ntext\nhtml\n'
 }
 
        [[ "$result" == 'm' ]] && printf 'roff\ntext\nhtml\n'
 }
 
-_gsu_man_txt='
+_gsu_help_text['man']='
 Print the manual.
 
 Usage: man [-m <mode>] [-b <browser>]
 Print the manual.
 
 Usage: man [-m <mode>] [-b <browser>]
@@ -374,7 +381,7 @@ _gsu_roffify_maindoc()
                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'
-                       printf '%s\n' "$line"
+                       _gsu_print_protected_roff_line "$line"
                        line="$next_line"
                        continue
                fi
                        line="$next_line"
                        continue
                fi
@@ -451,14 +458,17 @@ _gsu_roffify_cmds()
        done
 }
 
        done
 }
 
-_gsu_roffify_autocmd()
+_gsu_roffify_autocmds()
 {
 {
-       local cmd="$1" help_txt="$2"
+       local cmd help_txt
 
 
-       {
-               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
 }
 
 _gsu_roff_man()
 }
 
 _gsu_roff_man()
@@ -480,10 +490,7 @@ EOF
 
        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"
+       _gsu_roffify_autocmds
 
        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'
@@ -606,15 +613,18 @@ com_man()
        ret=$GSU_SUCCESS
 }
 
        ret=$GSU_SUCCESS
 }
 
-_gsu_help_txt="
+_gsu_help_text['help']='
 Print online help.
 
 Print online help.
 
-Usage: help [command]
+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_complete_txt="
+_gsu_help_text['complete']='
 Command line completion.
 
 Usage: complete [<cword> <word>...]
 Command line completion.
 
 Usage: complete [<cword> <word>...]
@@ -626,11 +636,16 @@ completion.
 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.
-"
+'
 
 
+com_help_options='a'
 com_help()
 {
 com_help()
 {
-       local ere tab=' '
+       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"
@@ -639,10 +654,15 @@ com_help()
                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
@@ -664,33 +684,33 @@ com_help()
                                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"]}"
                ret=$GSU_SUCCESS
                return
                ret=$GSU_SUCCESS
                return
-       fi
-       ret=$GSU_SUCCESS
+       done
        _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
@@ -717,6 +737,7 @@ com_help()
                        p
                }
        ' "$0"
                        p
                }
        ' "$0"
+       ret=$GSU_SUCCESS
 }
 
 complete_help()
 }
 
 complete_help()
@@ -881,6 +902,6 @@ gsu()
        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
        exit 1
 }
        exit 1
 }