shell dot on steroids https://pagure.io/shellfu

charmenu.sh 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/bin/sh
  2. #shellcheck disable=SC2039
  3. CHARMENU_FILE="${CHARMENU_FILE:-}"
  4. charmenu() {
  5. #
  6. # Present "1-char-menu" (but actually N-char) or its parts
  7. #
  8. # Usage:
  9. # CHARMENU_FILE=/path/to/file
  10. # charmenu [options] full [ARG]...
  11. # charmenu [options] items
  12. # charmenu [options] prompt
  13. # charmenu [options] has ITEM
  14. #
  15. # Read file in $CHARMENU_FILE and display either `full`
  16. # menu, `items` menu (e.g. "y,n,q,?") or just `prompt`.
  17. #
  18. # Options:
  19. #
  20. # -f FILE, --file FILE Read contents of menu freom FILE
  21. # instead of variable `$CHARMENU_FILE`.
  22. #
  23. # -p PROMPT, --prompt PROMPT Set prompt string to PROMPT.
  24. # If PROMPT contains '%s', it will be replaced by 'items'
  25. # menu (eg. "y,n,q"). Note that you most probably want
  26. # to include space as last character. Default: "What
  27. # next [%s]? ".
  28. #
  29. # -i, --ignore-case Ignore case of user reply. Default:
  30. # case is respected.
  31. #
  32. # -d DLM, --delimiter DLM Use delimiter DLM when printing
  33. # 'items' menu. Default: "," (comma).
  34. #
  35. # Format of menu file is one item per line, where item is
  36. # delimited from its description by single colon. Leading
  37. # and trailing spaces and spaces around the colon are
  38. # stripped.
  39. #
  40. # Simple example menu file:
  41. #
  42. # a: abort
  43. # r: retry
  44. # f: fail
  45. #
  46. # You can use printf symbols like `%s` in menu and then
  47. # call `charmenu full arg1 arg2...` to have your arguments
  48. # expanded in the full menu. More fleshed out example:
  49. #
  50. # . "$(sfpath)" || exit 3
  51. # shellfu import charmenu
  52. # shellfu import pretty
  53. #
  54. # cat <<EOM >menu
  55. # r: re-run test %s
  56. # c: clean screen
  57. # d: download results to %s
  58. # q: quit
  59. # EOM
  60. #
  61. # CHARMENU_FILE=menu
  62. # running=true
  63. # while $running; do
  64. # charmenu full "mytest" "some storage"
  65. # read -r response
  66. # case $response in
  67. # r) rerun_test ;;
  68. # c) reset ;;
  69. # d) download_results ;;
  70. # q) running=false ;;
  71. # *) warn "invalid response: $response"
  72. # esac
  73. # done
  74. # clean_up
  75. #
  76. # `charmenu has ITEM` exits with zero if ITEM is a valid
  77. # menu item. With abort/retry/fail example above, calling
  78. # `if charmenu has a; echo OK; fi` would print "OK"..
  79. #
  80. local mfile # path to menu file
  81. local prompt # prompt text
  82. local delim # delimiter (in 'items' menu)
  83. local cmd # command do execute
  84. local cases # "-i" in case-insensitive mode
  85. local menu # loaded menu text
  86. local alist # loaded list of items
  87. mfile=$CHARMENU_FILE
  88. prompt="What next [%s]? "
  89. delim=,
  90. while true; do case $1 in
  91. -d|--delimiter) delim="$2"; shift 2 || return 2 ;;
  92. -f|--file) mfile="$2"; shift 2 || return 2 ;;
  93. -i|--ignore-case) cases="-i"; shift ;;
  94. -p|--prompt) prompt="$2"; shift 2 || return 2 ;;
  95. full|items|prompt|has) cmd=$1; shift; break ;;
  96. *) mkusage "full [PRINTF_ARG...]" \
  97. "items [DELIM]" \
  98. "prompt [PRINTF_FMT]" \
  99. "has ITEM" ;;
  100. esac done
  101. menu="$(cat "$mfile")"
  102. alist="$(echo "$menu" | cut -d: -f1 | sed -re 's/^ +//; s/ +$//')"
  103. #shellcheck disable=SC2059
  104. case $cmd in
  105. full) # print the full menu, with any printf notation expanded
  106. printf "$menu\n" "$@"
  107. ;;
  108. items) # print just the list of actions
  109. echo "$alist" paste -sd"$delim"
  110. ;;
  111. prompt) # print prompt for user
  112. printf "$prompt" "$(charmenu items)"
  113. ;;
  114. has) # check if response is valid ("on the menu")
  115. local res="$1"
  116. test -n "$res" || return 1 # "" is not valid
  117. echo "$alist" | grep $cases -e "^$res$"
  118. return $?
  119. ;;
  120. esac
  121. }