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

sfdoc 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #!/bin/bash
  2. #shellcheck disable=SC1090
  3. . "$(sfpath)" || exit 3
  4. shellfu import pretty
  5. shellfu import sfdoc
  6. usage() {
  7. mkusage "$@" \
  8. "[options] MODULE" \
  9. "[options] --ls [MODULE]" \
  10. "[options] --ls{var|fun} MODULE" \
  11. "[options] --which MODULE" \
  12. "[options] --lsmod" \
  13. "[options] -s|--src MODULE" \
  14. "[options] --export FMT MODULE" \
  15. -c \
  16. "-l, --ls [MODULE] list contents of MODULE if specified," \
  17. " otherwise of all modules" \
  18. "-L, --lsmod show list of modules" \
  19. "--lsfun MODULE show list of functions in MODULE" \
  20. "--lsvar MODULE show list of variables in MODULE" \
  21. "--which MODULE show path to MODULE file" \
  22. "-s, --src MODULE show MODULE source code" \
  23. "-e, --export FMT MODULE export MODULE documentation in" \
  24. " format FMT: 'markdown', 'manpage' and" \
  25. " 'pod' are supported" \
  26. -o \
  27. "-O, --object Treat MODULE as function or variable" \
  28. " name and find respective module first." \
  29. "-d, --debug Turn on debugging" \
  30. "-h, --hide REGEX Use REGEX to determine what is hidden." \
  31. " (See also -a and 'sfdoc sfdoc'.)" \
  32. "-a, --all Don't ignore hidden (starting with" \
  33. " underscore) modules or objects" \
  34. "--encoding ENC Override encoding of the source text" \
  35. " (default: utf8)" \
  36. "--name NAME Override module name (useful when" \
  37. " exporting from a file and the filename" \
  38. " is not helpful)" \
  39. "-I PTH, --include PTH Include path PTH when searching" \
  40. " for modules; can be specified multiple" \
  41. " times." \
  42. "-o PTH, --only-from PTH Search only under path PTH." \
  43. -- \
  44. "Without command specified, will try to display documentation" \
  45. "in man(1) pager."
  46. }
  47. select_mfile() {
  48. #
  49. # Find and/or verify file that holds module $1
  50. #
  51. local module=$1
  52. local mfile
  53. case $module in
  54. */*) mfile="$module" ;;
  55. *) mfile=$(shellfu _select_mfile "$module") ;;
  56. esac
  57. debug -v mfile
  58. test -n "$mfile" || { warn "no such module found: $module"; return 3; }
  59. test -f "$mfile" || { warn "no such file found: $mfile"; return 3; }
  60. echo "$mfile"
  61. }
  62. find_lesspipe() {
  63. #
  64. # Output correct path to src-hilite-lesspipe.sh
  65. #
  66. find \
  67. /usr/bin/src-hilite-lesspipe.sh \
  68. /usr/share/source-highlight/src-hilite-lesspipe.sh \
  69. 2>/dev/null
  70. }
  71. find_by() {
  72. #
  73. # Find module by object type $1 and name $2
  74. #
  75. local name=$1
  76. sfdoc -a -l \
  77. | grep ":$name$" \
  78. | cut -d: -f1 \
  79. | grep .
  80. }
  81. main() {
  82. local action # what to do
  83. local format # export format
  84. local module # module name or path/to/module.sh
  85. local mspec # module/function name or path/to/module.sh
  86. local m # module helper var
  87. local RealModuleName # name to override eg. if accessing via filename
  88. local encoding # encoding
  89. local mpath # path to module file
  90. local jump # jump to first occurence of this
  91. action=man
  92. format=markdown
  93. encoding=utf8
  94. spectype=mod
  95. #shellcheck disable=SC2034
  96. while true; do case "$1" in
  97. -O|--object) spectype=obj; shift ;;
  98. -d|--debug) PRETTY_DEBUG=true; shift ;;
  99. -a|--all) SFDOC_SHOW_HIDDEN=true; shift ;;
  100. -h|--hide) SFDOC_SHOW_HIDDEN=false; SFDOC_HIDE_REGEX="$2"; shift 2 || usage -w "no REGEX?" ;;
  101. -I|--include) SHELLFU_PATH="$2:$SHELLFU_PATH"; shift 2 || usage -w "no PTH?" ;;
  102. -s|--src) action=src; shift; break ;;
  103. -l|--ls) action=lsx; shift; break ;;
  104. -L|--lsmod) action=lsm; shift; break ;;
  105. --which) action=wch; shift; break ;;
  106. -o|--only-from) SHELLFU_PATH="$2"; SHELLFU_INCLUDE=""; shift 2 || usage -w "no PTH?" ;;
  107. --lsvar) action=lsv; shift; break ;;
  108. --lsfun) action=lsf; shift; break ;;
  109. -e|--export) action=exp; format="$2"; shift 2 || usage -w "no FMT?"; break ;;
  110. --encoding) encoding="$2"; shift 2 || usage -w "no ENC?" ;;
  111. --name) RealModuleName="$2"; shift 2 || usage -w "no NAME?" ;;
  112. -*) usage -w "unknown argument: $1" ;;
  113. *) break ;;
  114. esac done
  115. mspec="$1"; shift
  116. debug -v SHELLFU_INCLUDE SHELLFU_PATH SFDOC_SHOW_HIDDEN
  117. debug -v action format module RealModuleName
  118. case $action:$mspec in
  119. lsx:*|lsm:*) true ;;
  120. *:) usage -w "no MODULE?" ;;
  121. esac
  122. case $spectype in
  123. obj) module=$(find_by "$mspec") \
  124. || die "no module found with: $mspec"
  125. jump="$mspec"
  126. ;;
  127. *) module=$mspec ;;
  128. esac
  129. case $action in
  130. lsm) : ;;
  131. *) mpath=$(select_mfile "$module") || die ;;
  132. esac
  133. case $action in
  134. exp) # --export
  135. grep -qwe "$format" <<<manpage,markdown,pod \
  136. || die "unknown format: $format"
  137. sfdoc__export "$format" "${RealModuleName:-$module}" "$mpath" "$encoding"
  138. ;;
  139. lsm) # --lsmod
  140. sfdoc__ls_m | LC_ALL=C sort
  141. ;;
  142. lsv) # --lsvar MODULE
  143. sfdoc__ls v "$mpath" | LC_ALL=C sort
  144. ;;
  145. lsf) # --lsfun MODULE
  146. sfdoc__ls f "$mpath" | LC_ALL=C sort
  147. ;;
  148. lsx) # --ls [MODULE]
  149. case $module in
  150. "") shellfu _list_mfiles ;;
  151. *) echo "$mpath" ;;
  152. esac \
  153. | while read -r m;
  154. do
  155. sfdoc__ls v "$m"
  156. sfdoc__ls f "$m"
  157. done \
  158. | LC_ALL=C sort
  159. ;;
  160. man)
  161. which pod2man &>/dev/null \
  162. || die "pod2man is missing; cannot use man page mode"
  163. manfile=$(mktemp -t "sfdoc.manfile.XXXXXXXX")
  164. sfdoc__export manpage "${RealModuleName:-$module}" "$mpath" "$encoding" >"$manfile"
  165. manless="$LESS"
  166. test -n "$jump" && manless+=" +/$jump"
  167. LESS="$manless" man "$manfile"
  168. rm "$manfile"
  169. ;;
  170. src)
  171. local lesspipe
  172. lesspipe=$(find_lesspipe)
  173. if test -n "$lesspipe";
  174. then
  175. LESS="$LESS -R " \
  176. LESSOPEN="| $lesspipe %s" \
  177. less "$mpath"
  178. else
  179. less "$mpath"
  180. fi
  181. ;;
  182. wch)
  183. echo "$mpath"
  184. ;;
  185. esac
  186. }
  187. main "$@"