grunt.plugin.zsh 7.0 KB

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