grunt.plugin.zsh 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #compdef grunt
  2. # -----------------------------------------------------------------------------
  3. # _grunt
  4. #
  5. # Completion script for grunt.
  6. # - https://github.com/gruntjs/grunt
  7. # - https://github.com/gruntjs/grunt-cli
  8. #
  9. # -----------------------------------------------------------------------------
  10. #
  11. # Version : 0.1.0
  12. # Author : Yonchu <yuyuchu3333@gmail.com>
  13. # License : MIT License
  14. # Repository : https://github.com/yonchu/grunt-zsh-completion
  15. # Last Change : 22 Jul 2013.
  16. #
  17. # Copyright (c) 2013 Yonchu.
  18. #
  19. # -----------------------------------------------------------------------------
  20. # USAGE
  21. # -----
  22. #
  23. # Enable caching:
  24. #
  25. # If you want to use the cache, set the followings in your .zshrc:
  26. #
  27. # zstyle ':completion:*' use-cache yes
  28. #
  29. #
  30. # Settings:
  31. #
  32. # - Show grunt file path:
  33. # zstyle ':completion::complete:grunt::options:' show_grunt_path yes
  34. #
  35. # - Cache expiration days (default: 7):
  36. # zstyle ':completion::complete:grunt::options:' expire 1
  37. #
  38. # - Not update options cache if target gruntfile is changed.
  39. # zstyle ':completion::complete:grunt::options:' no_update_options yes
  40. #
  41. # Note that if you change the zstyle settings,
  42. # you should delete the cache file and restart zsh.
  43. #
  44. # $ rm ~/.zcompcache/grunt
  45. # $ exec zsh
  46. #
  47. # -----------------------------------------------------------------------------
  48. function _grunt() {
  49. local curcontext="$curcontext" update_policy state
  50. local show_grunt_path update_msg gruntfile opts tasks
  51. # Setup cache-policy.
  52. zstyle -s ":completion:${curcontext}:" cache-policy update_policy
  53. if [[ -z $update_policy ]]; then
  54. zstyle ":completion:${curcontext}:" cache-policy __grunt_caching_policy
  55. fi
  56. # Check show_path option.
  57. zstyle -b ":completion:${curcontext}:options:" show_grunt_path show_grunt_path
  58. # Get current gruntfile.
  59. gruntfile=$(__grunt_get_gruntfile)
  60. # Initialize opts and tasks.
  61. opts=()
  62. tasks=()
  63. # Add help options.
  64. opts+=('(- 1 *)'{-h,--help}'[Display this help text.]')
  65. ## Complete without gruntfile.
  66. if [[ ! -f $gruntfile ]]; then
  67. _arguments "${opts[@]}"
  68. return
  69. fi
  70. ## Complete with gruntfile.
  71. # Retrieve cache.
  72. if ! __grunt_update_cache "$gruntfile"; then
  73. update_msg=' (cache updated)'
  74. fi
  75. # Make optioins completion.
  76. if [[ ${#__grunt_opts} -gt 0 ]]; then
  77. opts+=("${__grunt_opts[@]}")
  78. fi
  79. # Complete arguments.
  80. _arguments \
  81. "${opts[@]}" \
  82. '*: :->tasks' \
  83. && return
  84. case $state in
  85. tasks)
  86. if [[ $show_grunt_path == 'yes' ]]; then
  87. update_msg="$update_msg: ${${gruntfile/#$HOME/~}%/}"
  88. fi
  89. # Make tasks completion.
  90. if [[ ${#__grunt_tasks} -gt 0 ]]; then
  91. tasks+=("${__grunt_tasks[@]}")
  92. _describe -t grunt-task "$verbose grunt task$update_msg" tasks || return 1
  93. fi
  94. ;;
  95. esac
  96. return 0
  97. }
  98. # Cache policy:
  99. # The cache file name: grunt
  100. # The cache variable name: __grunt_version __grunt_gruntfile __grunt_opts __grunt_tasks
  101. function __grunt_update_cache() {
  102. # TODO
  103. local version='0.1.0'
  104. local is_updating=0
  105. local gruntfile="$1"
  106. local grunt_info no_update_options cache_path
  107. # Check no_update_options option.
  108. zstyle -b ":completion:${curcontext}:options:" no_update_options no_update_options
  109. if ! ( (( $+__grunt_gruntfile )) \
  110. && (( $+__grunt_opts )) \
  111. && (( $+__grunt_tasks )) ) \
  112. && ! _retrieve_cache 'grunt'; then
  113. is_updating=1
  114. fi
  115. if [[ $gruntfile != $__grunt_gruntfile ]]; then
  116. # Except for --help options.
  117. __grunt_gruntfile=$gruntfile
  118. if [[ $no_update_options == 'yes' ]]; then
  119. if [[ $PREFIX == ${PREFIX#-} ]]; then
  120. # Not options completions.
  121. is_updating=1
  122. elif [[ ${#__grunt_opts} -lt 2 ]]; then
  123. is_updating=1
  124. else
  125. unset __grunt_gruntfile
  126. fi
  127. else
  128. is_updating=1
  129. fi
  130. else
  131. if [[ $PREFIX != ${PREFIX#-} && ${#__grunt_opts} -gt 1 ]]; then
  132. unset __grunt_gruntfile
  133. fi
  134. fi
  135. if _cache_invalid 'grunt'; then
  136. is_updating=1
  137. fi
  138. # Check _grunt version.
  139. if [[ $__grunt_version != $version ]]; then
  140. is_updating=1
  141. fi
  142. if [[ $is_updating -ne 0 ]]; then
  143. # Update caceh.
  144. __grunt_version=$version
  145. __grunt_gruntfile=$gruntfile
  146. is_updating=1
  147. grunt_info=$(grunt --help --no-color --gruntfile "$__grunt_gruntfile" 2>/dev/null)
  148. __grunt_opts=(${(f)"$(__grunt_get_opts "$grunt_info")"})
  149. __grunt_tasks=(${(f)"$(__grunt_get_tasks "$grunt_info")"})
  150. _store_cache 'grunt' __grunt_version __grunt_gruntfile __grunt_opts __grunt_tasks
  151. fi
  152. return $is_updating
  153. }
  154. function __grunt_get_tasks() {
  155. echo -E "$1" \
  156. | grep 'Available tasks' -A 100 \
  157. | grep '^ ' \
  158. | sed -e 's/^[[:blank:]]*//' -e 's/[[:blank:]]*$//' \
  159. | sed -e 's/ /:/'
  160. }
  161. function __grunt_get_opts() {
  162. local opt_hunk opt_sep opt_num line opt
  163. opt_hunk=$(echo -E "$1" \
  164. | grep 'Options$' -A 100 \
  165. | sed '1 d' \
  166. | sed -e 's/[[:blank:]]*$//' \
  167. )
  168. opt_sep=()
  169. opt_hunk=(${(f)opt_hunk})
  170. opt_num=0
  171. for line in "$opt_hunk[@]"; do
  172. opt=$(echo -E "$line" | sed -e 's/^[[:blank:]]*//')
  173. if [[ $line == $opt ]]; then
  174. break
  175. fi
  176. if [[ $opt != ${opt#-} ]]; then
  177. # Start with -
  178. (( opt_num++ ))
  179. opt=$(echo -E "$opt" | sed 's/^\(\(--[^ ]*\)\(, \(-[^ ]*\)\)*\) */\2\\t\4\\\t/')
  180. fi
  181. opt_sep[$opt_num]=("${opt_sep[$opt_num]}${opt}")
  182. done
  183. for line in "$opt_sep[@]"; do
  184. opt=(${(s:\t:)line})
  185. if [[ ${opt[1]} == '--help' ]]; then
  186. continue
  187. fi
  188. if [[ ${#opt} -eq 2 ]]; then
  189. echo -E "(${opt[1]})${opt[1]}[${opt[2]}]"
  190. else
  191. echo -E "(${opt[1]},${opt[2]})${opt[1]}[${opt[3]}]"
  192. echo -E "(${opt[1]},${opt[2]})${opt[2]}[${opt[3]}]"
  193. fi
  194. done
  195. }
  196. function __grunt_get_gruntfile() {
  197. local gruntfile
  198. local curpath="$PWD"
  199. while [ "$curpath" ]; do
  200. for gruntfile in "$curpath/"{G,g}runtfile.{js,coffee}; do
  201. if [[ -e "$gruntfile" ]]; then
  202. echo "$gruntfile"
  203. return
  204. fi
  205. done
  206. curpath=${curpath%/*}
  207. done
  208. return 1
  209. }
  210. function __grunt_caching_policy() {
  211. # Returns status zero if the completions cache needs rebuilding.
  212. # Rebuild if .agignore more recent than cache.
  213. if [[ -f $__grunt_gruntfile && $__grunt_gruntfile -nt $1 ]]; then
  214. # Invalid cache because gruntfile is old.
  215. return 0
  216. fi
  217. local -a oldp
  218. local expire
  219. zstyle -s ":completion:${curcontext}:options:" expire expire || expire=7
  220. # Rebuild if cache is more than $expire days.
  221. oldp=( "$1"(Nm+$expire) )
  222. (( $#oldp ))
  223. }
  224. compdef _grunt grunt