Commit dbdac1aad8d2cec5b604b2afb538b074f1f72c44

Authored by Will Boyce
Committed by Shrikant Sharat
1 parent 5e23ab6fec

process deferred compdefs in the order they were called

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

1 #!/bin/zsh 1 #!/bin/zsh
2 2
3 # Each line in this string has the following entries separated by a space 3 # Each line in this string has the following entries separated by a space
4 # character. 4 # character.
5 # <repo-url>, <plugin-location>, <bundle-type>, <has-local-clone> 5 # <repo-url>, <plugin-location>, <bundle-type>, <has-local-clone>
6 # FIXME: Is not kept local by zsh! 6 # FIXME: Is not kept local by zsh!
7 local _ANTIGEN_BUNDLE_RECORD="" 7 local _ANTIGEN_BUNDLE_RECORD=""
8 local _ANTIGEN_INSTALL_DIR="$(dirname $0)" 8 local _ANTIGEN_INSTALL_DIR="$(dirname $0)"
9 9
10 # Used to defer compinit/compdef 10 # Used to defer compinit/compdef
11 typeset -a __deferred_compdefs 11 typeset -a __deferred_compdefs
12 compdef () { __deferred_compdefs[$(($#__deferred_compdefs+1))]=$* } 12 compdef () { __deferred_compdefs=(${__deferred_compdefs} "${*}") }
13 13
14 # Syntaxes 14 # Syntaxes
15 # antigen-bundle <url> [<loc>=/] 15 # antigen-bundle <url> [<loc>=/]
16 # Keyword only arguments: 16 # Keyword only arguments:
17 # branch - The branch of the repo to use for this bundle. 17 # branch - The branch of the repo to use for this bundle.
18 antigen-bundle () { 18 antigen-bundle () {
19 19
20 # Bundle spec arguments' default values. 20 # Bundle spec arguments' default values.
21 local url="$ANTIGEN_DEFAULT_REPO_URL" 21 local url="$ANTIGEN_DEFAULT_REPO_URL"
22 local loc=/ 22 local loc=/
23 local branch= 23 local branch=
24 local no_local_clone=false 24 local no_local_clone=false
25 local btype=plugin 25 local btype=plugin
26 26
27 # Parse the given arguments. (Will overwrite the above values). 27 # Parse the given arguments. (Will overwrite the above values).
28 eval "$(-antigen-parse-args \ 28 eval "$(-antigen-parse-args \
29 'url?, loc? ; branch:?, no-local-clone?, btype:?' \ 29 'url?, loc? ; branch:?, no-local-clone?, btype:?' \
30 "$@")" 30 "$@")"
31 31
32 # Check if url is just the plugin name. Super short syntax. 32 # Check if url is just the plugin name. Super short syntax.
33 if [[ "$url" != */* ]]; then 33 if [[ "$url" != */* ]]; then
34 loc="plugins/$url" 34 loc="plugins/$url"
35 url="$ANTIGEN_DEFAULT_REPO_URL" 35 url="$ANTIGEN_DEFAULT_REPO_URL"
36 fi 36 fi
37 37
38 # Resolve the url. 38 # Resolve the url.
39 url="$(-antigen-resolve-bundle-url "$url")" 39 url="$(-antigen-resolve-bundle-url "$url")"
40 40
41 # Add the branch information to the url. 41 # Add the branch information to the url.
42 if [[ ! -z $branch ]]; then 42 if [[ ! -z $branch ]]; then
43 url="$url|$branch" 43 url="$url|$branch"
44 fi 44 fi
45 45
46 # The `make_local_clone` variable better represents whether there should be 46 # The `make_local_clone` variable better represents whether there should be
47 # a local clone made. For cloning to be avoided, firstly, the `$url` should 47 # a local clone made. For cloning to be avoided, firstly, the `$url` should
48 # be an absolute local path and `$branch` should be empty. In addition to 48 # be an absolute local path and `$branch` should be empty. In addition to
49 # these two conditions, either the `--no-local-clone` option should be 49 # these two conditions, either the `--no-local-clone` option should be
50 # given, or `$url` should not a git repo. 50 # given, or `$url` should not a git repo.
51 local make_local_clone=true 51 local make_local_clone=true
52 if [[ $url == /* && -z $branch && 52 if [[ $url == /* && -z $branch &&
53 ( $no_local_clone == true || ! -d $url/.git ) ]]; then 53 ( $no_local_clone == true || ! -d $url/.git ) ]]; then
54 make_local_clone=false 54 make_local_clone=false
55 fi 55 fi
56 56
57 # Add the theme extension to `loc`, if this is a theme. 57 # Add the theme extension to `loc`, if this is a theme.
58 if [[ $btype == theme && $loc != *.zsh-theme ]]; then 58 if [[ $btype == theme && $loc != *.zsh-theme ]]; then
59 loc="$loc.zsh-theme" 59 loc="$loc.zsh-theme"
60 fi 60 fi
61 61
62 # Add it to the record. 62 # Add it to the record.
63 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype" 63 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype"
64 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone" 64 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone"
65 65
66 # Ensure a clone exists for this repo, if needed. 66 # Ensure a clone exists for this repo, if needed.
67 if $make_local_clone; then 67 if $make_local_clone; then
68 -antigen-ensure-repo "$url" 68 -antigen-ensure-repo "$url"
69 fi 69 fi
70 70
71 # Load the plugin. 71 # Load the plugin.
72 -antigen-load "$url" "$loc" "$btype" "$make_local_clone" 72 -antigen-load "$url" "$loc" "$btype" "$make_local_clone"
73 73
74 } 74 }
75 75
76 -antigen-resolve-bundle-url () { 76 -antigen-resolve-bundle-url () {
77 # Given an acceptable short/full form of a bundle's repo url, this function 77 # Given an acceptable short/full form of a bundle's repo url, this function
78 # echoes the full form of the repo's clone url. 78 # echoes the full form of the repo's clone url.
79 79
80 local url="$1" 80 local url="$1"
81 81
82 # Expand short github url syntax: `username/reponame`. 82 # Expand short github url syntax: `username/reponame`.
83 if [[ $url != git://* && 83 if [[ $url != git://* &&
84 $url != https://* && 84 $url != https://* &&
85 $url != /* && 85 $url != /* &&
86 $url != git@github.com:*/* 86 $url != git@github.com:*/*
87 ]]; then 87 ]]; then
88 url="https://github.com/${url%.git}.git" 88 url="https://github.com/${url%.git}.git"
89 fi 89 fi
90 90
91 echo "$url" 91 echo "$url"
92 } 92 }
93 93
94 antigen-bundles () { 94 antigen-bundles () {
95 # Bulk add many bundles at one go. Empty lines and lines starting with a `#` 95 # Bulk add many bundles at one go. Empty lines and lines starting with a `#`
96 # are ignored. Everything else is given to `antigen-bundle` as is, no 96 # are ignored. Everything else is given to `antigen-bundle` as is, no
97 # quoting rules applied. 97 # quoting rules applied.
98 98
99 local line 99 local line
100 100
101 grep -v '^\s*$\|^#' | while read line; do 101 grep -v '^\s*$\|^#' | while read line; do
102 # Using `eval` so that we can use the shell-style quoting in each line 102 # Using `eval` so that we can use the shell-style quoting in each line
103 # piped to `antigen-bundles`. 103 # piped to `antigen-bundles`.
104 eval "antigen-bundle $line" 104 eval "antigen-bundle $line"
105 done 105 done
106 } 106 }
107 107
108 antigen-update () { 108 antigen-update () {
109 # Update your bundles, i.e., `git pull` in all the plugin repos. 109 # Update your bundles, i.e., `git pull` in all the plugin repos.
110 110
111 date > $ADOTDIR/revert-info 111 date > $ADOTDIR/revert-info
112 112
113 -antigen-echo-record | 113 -antigen-echo-record |
114 awk '$4 == "true" {print $1}' | 114 awk '$4 == "true" {print $1}' |
115 sort -u | 115 sort -u |
116 while read url; do 116 while read url; do
117 echo "**** Pulling $url" 117 echo "**** Pulling $url"
118 118
119 local clone_dir="$(-antigen-get-clone-dir "$url")" 119 local clone_dir="$(-antigen-get-clone-dir "$url")"
120 if [[ -d "$clone_dir" ]]; then 120 if [[ -d "$clone_dir" ]]; then
121 (echo -n "$clone_dir:" 121 (echo -n "$clone_dir:"
122 cd "$clone_dir" 122 cd "$clone_dir"
123 git rev-parse HEAD) >> $ADOTDIR/revert-info 123 git rev-parse HEAD) >> $ADOTDIR/revert-info
124 fi 124 fi
125 125
126 -antigen-ensure-repo "$url" --update --verbose 126 -antigen-ensure-repo "$url" --update --verbose
127 127
128 echo 128 echo
129 done 129 done
130 } 130 }
131 131
132 antigen-revert () { 132 antigen-revert () {
133 if ! [[ -f $ADOTDIR/revert-info ]]; then 133 if ! [[ -f $ADOTDIR/revert-info ]]; then
134 echo 'No revert information available. Cannot revert.' >&2 134 echo 'No revert information available. Cannot revert.' >&2
135 fi 135 fi
136 136
137 cat $ADOTDIR/revert-info | sed '1!p' | while read line; do 137 cat $ADOTDIR/revert-info | sed '1!p' | while read line; do
138 dir="$(echo "$line" | cut -d: -f1)" 138 dir="$(echo "$line" | cut -d: -f1)"
139 git --git-dir="$dir/.git" --work-tree="$dir" \ 139 git --git-dir="$dir/.git" --work-tree="$dir" \
140 checkout "$(echo "$line" | cut -d: -f2)" 2> /dev/null 140 checkout "$(echo "$line" | cut -d: -f2)" 2> /dev/null
141 done 141 done
142 142
143 echo "Reverted to state before running -update on $( 143 echo "Reverted to state before running -update on $(
144 cat $ADOTDIR/revert-info | sed -n 1p)." 144 cat $ADOTDIR/revert-info | sed -n 1p)."
145 } 145 }
146 146
147 -antigen-get-clone-dir () { 147 -antigen-get-clone-dir () {
148 # Takes a repo url and gives out the path that this url needs to be cloned 148 # Takes a repo url and gives out the path that this url needs to be cloned
149 # to. Doesn't actually clone anything. 149 # to. Doesn't actually clone anything.
150 echo -n $ADOTDIR/repos/ 150 echo -n $ADOTDIR/repos/
151 151
152 if [[ "$1" == "https://github.com/sorin-ionescu/prezto.git" ]]; then 152 if [[ "$1" == "https://github.com/sorin-ionescu/prezto.git" ]]; then
153 # Prezto's directory *has* to be `.zprezto`. 153 # Prezto's directory *has* to be `.zprezto`.
154 echo .zprezto 154 echo .zprezto
155 155
156 else 156 else
157 echo "$1" | sed \ 157 echo "$1" | sed \
158 -e 's./.-SLASH-.g' \ 158 -e 's./.-SLASH-.g' \
159 -e 's.:.-COLON-.g' \ 159 -e 's.:.-COLON-.g' \
160 -e 's.|.-PIPE-.g' 160 -e 's.|.-PIPE-.g'
161 161
162 fi 162 fi
163 } 163 }
164 164
165 -antigen-get-clone-url () { 165 -antigen-get-clone-url () {
166 # Takes a repo's clone dir and gives out the repo's original url that was 166 # Takes a repo's clone dir and gives out the repo's original url that was
167 # used to create the given directory path. 167 # used to create the given directory path.
168 168
169 if [[ "$1" == ".zprezto" ]]; then 169 if [[ "$1" == ".zprezto" ]]; then
170 # Prezto's (in `.zprezto`), is assumed to be from `sorin-ionescu`'s 170 # Prezto's (in `.zprezto`), is assumed to be from `sorin-ionescu`'s
171 # remote. 171 # remote.
172 echo https://github.com/sorin-ionescu/prezto.git 172 echo https://github.com/sorin-ionescu/prezto.git
173 173
174 else 174 else
175 echo "$1" | sed \ 175 echo "$1" | sed \
176 -e "s:^$ADOTDIR/repos/::" \ 176 -e "s:^$ADOTDIR/repos/::" \
177 -e 's.-SLASH-./.g' \ 177 -e 's.-SLASH-./.g' \
178 -e 's.-COLON-.:.g' \ 178 -e 's.-COLON-.:.g' \
179 -e 's.-PIPE-.|.g' 179 -e 's.-PIPE-.|.g'
180 180
181 fi 181 fi
182 } 182 }
183 183
184 -antigen-ensure-repo () { 184 -antigen-ensure-repo () {
185 185
186 # Ensure that a clone exists for the given repo url and branch. If the first 186 # Ensure that a clone exists for the given repo url and branch. If the first
187 # argument is `--update` and if a clone already exists for the given repo 187 # argument is `--update` and if a clone already exists for the given repo
188 # and branch, it is pull-ed, i.e., updated. 188 # and branch, it is pull-ed, i.e., updated.
189 189
190 # Argument defaults. 190 # Argument defaults.
191 # The url. No sane default for this, so just empty. 191 # The url. No sane default for this, so just empty.
192 local url= 192 local url=
193 # Check if we have to update. 193 # Check if we have to update.
194 local update=false 194 local update=false
195 # Verbose output. 195 # Verbose output.
196 local verbose=false 196 local verbose=false
197 197
198 eval "$(-antigen-parse-args 'url ; update?, verbose?' "$@")" 198 eval "$(-antigen-parse-args 'url ; update?, verbose?' "$@")"
199 shift $# 199 shift $#
200 200
201 # Get the clone's directory as per the given repo url and branch. 201 # Get the clone's directory as per the given repo url and branch.
202 local clone_dir="$(-antigen-get-clone-dir $url)" 202 local clone_dir="$(-antigen-get-clone-dir $url)"
203 203
204 # A temporary function wrapping the `git` command with repeated arguments. 204 # A temporary function wrapping the `git` command with repeated arguments.
205 --plugin-git () { 205 --plugin-git () {
206 (cd "$clone_dir" && git --no-pager "$@") 206 (cd "$clone_dir" && git --no-pager "$@")
207 } 207 }
208 208
209 # Clone if it doesn't already exist. 209 # Clone if it doesn't already exist.
210 if [[ ! -d $clone_dir ]]; then 210 if [[ ! -d $clone_dir ]]; then
211 git clone --recursive "${url%|*}" "$clone_dir" 211 git clone --recursive "${url%|*}" "$clone_dir"
212 elif $update; then 212 elif $update; then
213 # Save current revision. 213 # Save current revision.
214 local old_rev="$(--plugin-git rev-parse HEAD)" 214 local old_rev="$(--plugin-git rev-parse HEAD)"
215 # Pull changes if update requested. 215 # Pull changes if update requested.
216 --plugin-git pull 216 --plugin-git pull
217 # Update submodules. 217 # Update submodules.
218 --plugin-git submodule update --recursive 218 --plugin-git submodule update --recursive
219 # Get the new revision. 219 # Get the new revision.
220 local new_rev="$(--plugin-git rev-parse HEAD)" 220 local new_rev="$(--plugin-git rev-parse HEAD)"
221 fi 221 fi
222 222
223 # If its a specific branch that we want, checkout that branch. 223 # If its a specific branch that we want, checkout that branch.
224 if [[ $url == *\|* ]]; then 224 if [[ $url == *\|* ]]; then
225 local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/} 225 local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/}
226 local requested_branch="${url#*|}" 226 local requested_branch="${url#*|}"
227 # Only do the checkout when we are not already on the branch. 227 # Only do the checkout when we are not already on the branch.
228 [[ $requested_branch != $current_branch ]] && 228 [[ $requested_branch != $current_branch ]] &&
229 --plugin-git checkout $requested_branch 229 --plugin-git checkout $requested_branch
230 fi 230 fi
231 231
232 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then 232 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then
233 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}. 233 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}.
234 if $verbose; then 234 if $verbose; then
235 --plugin-git log --oneline --reverse --no-merges --stat '@{1}..' 235 --plugin-git log --oneline --reverse --no-merges --stat '@{1}..'
236 fi 236 fi
237 fi 237 fi
238 238
239 # Remove the temporary git wrapper function. 239 # Remove the temporary git wrapper function.
240 unfunction -- --plugin-git 240 unfunction -- --plugin-git
241 241
242 } 242 }
243 243
244 -antigen-load () { 244 -antigen-load () {
245 245
246 local url="$1" 246 local url="$1"
247 local loc="$2" 247 local loc="$2"
248 local btype="$3" 248 local btype="$3"
249 local make_local_clone="$4" 249 local make_local_clone="$4"
250 250
251 # The full location where the plugin is located. 251 # The full location where the plugin is located.
252 local location 252 local location
253 if $make_local_clone; then 253 if $make_local_clone; then
254 location="$(-antigen-get-clone-dir "$url")/$loc" 254 location="$(-antigen-get-clone-dir "$url")/$loc"
255 else 255 else
256 location="$url" 256 location="$url"
257 fi 257 fi
258 258
259 if [[ $btype == theme ]]; then 259 if [[ $btype == theme ]]; then
260 260
261 # Of course, if its a theme, the location would point to the script 261 # Of course, if its a theme, the location would point to the script
262 # file. 262 # file.
263 source "$location" 263 source "$location"
264 264
265 else 265 else
266 266
267 # Source the plugin script. 267 # Source the plugin script.
268 # FIXME: I don't know. Looks very very ugly. Needs a better 268 # FIXME: I don't know. Looks very very ugly. Needs a better
269 # implementation once tests are ready. 269 # implementation once tests are ready.
270 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')" 270 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')"
271 271
272 if [[ -f $location/$script_loc ]]; then 272 if [[ -f $location/$script_loc ]]; then
273 # If we have a `*.plugin.zsh`, source it. 273 # If we have a `*.plugin.zsh`, source it.
274 source "$location/$script_loc" 274 source "$location/$script_loc"
275 275
276 elif [[ -f $location/init.zsh ]]; then 276 elif [[ -f $location/init.zsh ]]; then
277 # If we have a `init.zsh` 277 # If we have a `init.zsh`
278 if (( $+functions[pmodload] )); then 278 if (( $+functions[pmodload] )); then
279 # If pmodload is defined pmodload the module. Remove `modules/` 279 # If pmodload is defined pmodload the module. Remove `modules/`
280 # from loc to find module name. 280 # from loc to find module name.
281 pmodload "${loc#modules/}" 281 pmodload "${loc#modules/}"
282 else 282 else
283 # Otherwise source it. 283 # Otherwise source it.
284 source "$location/init.zsh" 284 source "$location/init.zsh"
285 fi 285 fi
286 286
287 elif ls "$location" | grep -qm1 '\.zsh$'; then 287 elif ls "$location" | grep -qm1 '\.zsh$'; then
288 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh` 288 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh`
289 # files. 289 # files.
290 for script ($location/*.zsh(N)) source "$script" 290 for script ($location/*.zsh(N)) source "$script"
291 291
292 elif ls "$location" | grep -qm1 '\.sh$'; then 292 elif ls "$location" | grep -qm1 '\.sh$'; then
293 # If there are no `*.zsh` files either, we look for and source any 293 # If there are no `*.zsh` files either, we look for and source any
294 # `*.sh` files instead. 294 # `*.sh` files instead.
295 for script ($location/*.sh(N)) source "$script" 295 for script ($location/*.sh(N)) source "$script"
296 296
297 fi 297 fi
298 298
299 # Add to $fpath, for completion(s). 299 # Add to $fpath, for completion(s).
300 fpath=($location $fpath) 300 fpath=($location $fpath)
301 301
302 fi 302 fi
303 303
304 } 304 }
305 305
306 # Update (with `git pull`) antigen itself. 306 # Update (with `git pull`) antigen itself.
307 # TODO: Once update is finished, show a summary of the new commits, as a kind of 307 # TODO: Once update is finished, show a summary of the new commits, as a kind of
308 # "what's new" message. 308 # "what's new" message.
309 antigen-selfupdate () { 309 antigen-selfupdate () {
310 ( cd $_ANTIGEN_INSTALL_DIR 310 ( cd $_ANTIGEN_INSTALL_DIR
311 if [[ ! -d .git ]]; then 311 if [[ ! -d .git ]]; then
312 echo "Your copy of antigen doesn't appear to be a git clone. " \ 312 echo "Your copy of antigen doesn't appear to be a git clone. " \
313 "The 'selfupdate' command cannot work in this case." 313 "The 'selfupdate' command cannot work in this case."
314 return 1 314 return 1
315 fi 315 fi
316 git pull 316 git pull
317 ) 317 )
318 } 318 }
319 319
320 antigen-cleanup () { 320 antigen-cleanup () {
321 321
322 # Cleanup unused repositories. 322 # Cleanup unused repositories.
323 323
324 local force=false 324 local force=false
325 if [[ $1 == --force ]]; then 325 if [[ $1 == --force ]]; then
326 force=true 326 force=true
327 fi 327 fi
328 328
329 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then 329 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then
330 echo "You don't have any bundles." 330 echo "You don't have any bundles."
331 return 0 331 return 0
332 fi 332 fi
333 333
334 # Find directores in ADOTDIR/repos, that are not in the bundles record. 334 # Find directores in ADOTDIR/repos, that are not in the bundles record.
335 local unused_clones="$(comm -13 \ 335 local unused_clones="$(comm -13 \
336 <(-antigen-echo-record | 336 <(-antigen-echo-record |
337 awk '$4 == "true" {print $1}' | 337 awk '$4 == "true" {print $1}' |
338 while read line; do 338 while read line; do
339 -antigen-get-clone-dir "$line" 339 -antigen-get-clone-dir "$line"
340 done | 340 done |
341 sort -u) \ 341 sort -u) \
342 <(ls -d "$ADOTDIR/repos/"* | sort -u))" 342 <(ls -d "$ADOTDIR/repos/"* | sort -u))"
343 343
344 if [[ -z $unused_clones ]]; then 344 if [[ -z $unused_clones ]]; then
345 echo "You don't have any unidentified bundles." 345 echo "You don't have any unidentified bundles."
346 return 0 346 return 0
347 fi 347 fi
348 348
349 echo 'You have clones for the following repos, but are not used.' 349 echo 'You have clones for the following repos, but are not used.'
350 echo "$unused_clones" | 350 echo "$unused_clones" |
351 while read line; do 351 while read line; do
352 -antigen-get-clone-url "$line" 352 -antigen-get-clone-url "$line"
353 done | 353 done |
354 sed -e 's/^/ /' -e 's/|/, branch /' 354 sed -e 's/^/ /' -e 's/|/, branch /'
355 355
356 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then 356 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then
357 echo 357 echo
358 echo 358 echo
359 echo "$unused_clones" | while read line; do 359 echo "$unused_clones" | while read line; do
360 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..." 360 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..."
361 rm -rf "$line" 361 rm -rf "$line"
362 echo ' done.' 362 echo ' done.'
363 done 363 done
364 else 364 else
365 echo 365 echo
366 echo Nothing deleted. 366 echo Nothing deleted.
367 fi 367 fi
368 } 368 }
369 369
370 antigen-lib () { 370 antigen-lib () {
371 if [[ -z "$ZSH" ]]; then 371 if [[ -z "$ZSH" ]]; then
372 export ZSH="$(-antigen-get-clone-dir "$ANTIGEN_DEFAULT_REPO_URL")" 372 export ZSH="$(-antigen-get-clone-dir "$ANTIGEN_DEFAULT_REPO_URL")"
373 fi 373 fi
374 antigen-bundle --loc=lib 374 antigen-bundle --loc=lib
375 } 375 }
376 376
377 antigen-prezto-lib () { 377 antigen-prezto-lib () {
378 antigen-bundle sorin-ionescu/prezto 378 antigen-bundle sorin-ionescu/prezto
379 export ZDOTDIR=$ADOTDIR/repos/ 379 export ZDOTDIR=$ADOTDIR/repos/
380 } 380 }
381 381
382 antigen-theme () { 382 antigen-theme () {
383 383
384 if [[ "$1" != */* && "$1" != --* ]]; then 384 if [[ "$1" != */* && "$1" != --* ]]; then
385 # The first argument is just a name of the plugin, to be picked up from 385 # The first argument is just a name of the plugin, to be picked up from
386 # the default repo. 386 # the default repo.
387 local name="${1:-robbyrussell}" 387 local name="${1:-robbyrussell}"
388 antigen-bundle --loc=themes/$name --btype=theme 388 antigen-bundle --loc=themes/$name --btype=theme
389 389
390 else 390 else
391 antigen-bundle "$@" --btype=theme 391 antigen-bundle "$@" --btype=theme
392 392
393 fi 393 fi
394 394
395 } 395 }
396 396
397 antigen-apply () { 397 antigen-apply () {
398 # Initialize completion. 398 # Initialize completion.
399 local cd 399 local cd
400 for cd in $__deferred_compdefs; do 400 for cd in $__deferred_compdefs; do
401 compdef $cd 401 compdef $cd
402 done 402 done
403 unset __deferred_compdefs 403 unset __deferred_compdefs
404 compdef _antigen antigen 404 compdef _antigen antigen
405 } 405 }
406 406
407 antigen-list () { 407 antigen-list () {
408 # List all currently installed bundles. 408 # List all currently installed bundles.
409 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then 409 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
410 echo "You don't have any bundles." >&2 410 echo "You don't have any bundles." >&2
411 return 1 411 return 1
412 else 412 else
413 -antigen-echo-record | sort -u 413 -antigen-echo-record | sort -u
414 fi 414 fi
415 } 415 }
416 416
417 antigen-snapshot () { 417 antigen-snapshot () {
418 418
419 local snapshot_file="${1:-antigen-shapshot}" 419 local snapshot_file="${1:-antigen-shapshot}"
420 420
421 # The snapshot content lines are pairs of repo-url and git version hash, in 421 # The snapshot content lines are pairs of repo-url and git version hash, in
422 # the form: 422 # the form:
423 # <version-hash> <repo-url> 423 # <version-hash> <repo-url>
424 local snapshot_content="$(-antigen-echo-record | 424 local snapshot_content="$(-antigen-echo-record |
425 grep 'true$' | 425 grep 'true$' |
426 sed 's/ .*$//' | 426 sed 's/ .*$//' |
427 sort -u | 427 sort -u |
428 while read url; do 428 while read url; do
429 local dir="$(-antigen-get-clone-dir "$url")" 429 local dir="$(-antigen-get-clone-dir "$url")"
430 local version_hash="$(cd "$dir" && git rev-parse HEAD)" 430 local version_hash="$(cd "$dir" && git rev-parse HEAD)"
431 echo "$version_hash $url" 431 echo "$version_hash $url"
432 done)" 432 done)"
433 433
434 { 434 {
435 # The first line in the snapshot file is for metadata, in the form: 435 # The first line in the snapshot file is for metadata, in the form:
436 # key='value'; key='value'; key='value'; 436 # key='value'; key='value'; key='value';
437 # Where `key`s are valid shell variable names. 437 # Where `key`s are valid shell variable names.
438 438
439 # Snapshot version. Has no relation to antigen version. If the snapshot 439 # Snapshot version. Has no relation to antigen version. If the snapshot
440 # file format changes, this number can be incremented. 440 # file format changes, this number can be incremented.
441 echo -n "version='1';" 441 echo -n "version='1';"
442 442
443 # Snapshot creation date+time. 443 # Snapshot creation date+time.
444 echo -n " created_on='$(date)';" 444 echo -n " created_on='$(date)';"
445 445
446 # Add a checksum with the md5 checksum of all the snapshot lines. 446 # Add a checksum with the md5 checksum of all the snapshot lines.
447 local checksum="$(echo "$snapshot_content" | md5sum)" 447 local checksum="$(echo "$snapshot_content" | md5sum)"
448 echo -n " checksum='${checksum%% *}';" 448 echo -n " checksum='${checksum%% *}';"
449 449
450 # A newline after the metadata and then the snapshot lines. 450 # A newline after the metadata and then the snapshot lines.
451 echo "\n$snapshot_content" 451 echo "\n$snapshot_content"
452 452
453 } > "$snapshot_file" 453 } > "$snapshot_file"
454 454
455 } 455 }
456 456
457 antigen-restore () { 457 antigen-restore () {
458 458
459 if [[ $# == 0 ]]; then 459 if [[ $# == 0 ]]; then
460 echo 'Please provide a snapshot file to restore from.' >&2 460 echo 'Please provide a snapshot file to restore from.' >&2
461 return 1 461 return 1
462 fi 462 fi
463 463
464 local snapshot_file="$1" 464 local snapshot_file="$1"
465 465
466 # TODO: Before doing anything with the snapshot file, verify its checksum. 466 # TODO: Before doing anything with the snapshot file, verify its checksum.
467 # If it fails, notify this to the user and confirm if restore should 467 # If it fails, notify this to the user and confirm if restore should
468 # proceed. 468 # proceed.
469 469
470 echo -n "Restoring from $snapshot_file..." 470 echo -n "Restoring from $snapshot_file..."
471 471
472 sed -n '1!p' "$snapshot_file" | 472 sed -n '1!p' "$snapshot_file" |
473 while read line; do 473 while read line; do
474 474
475 local version_hash="${line%% *}" 475 local version_hash="${line%% *}"
476 local url="${line##* }" 476 local url="${line##* }"
477 local clone_dir="$(-antigen-get-clone-dir "$url")" 477 local clone_dir="$(-antigen-get-clone-dir "$url")"
478 478
479 if [[ ! -d $clone_dir ]]; then 479 if [[ ! -d $clone_dir ]]; then
480 git clone "$url" "$clone_dir" > /dev/null 480 git clone "$url" "$clone_dir" > /dev/null
481 fi 481 fi
482 482
483 (cd "$clone_dir" && git checkout $version_hash) 2> /dev/null 483 (cd "$clone_dir" && git checkout $version_hash) 2> /dev/null
484 484
485 done 485 done
486 486
487 echo ' done.' 487 echo ' done.'
488 echo 'Please open a new shell to get the restored changes.' 488 echo 'Please open a new shell to get the restored changes.'
489 } 489 }
490 490
491 antigen-help () { 491 antigen-help () {
492 cat <<EOF 492 cat <<EOF
493 Antigen is a plugin management system for zsh. It makes it easy to grab awesome 493 Antigen is a plugin management system for zsh. It makes it easy to grab awesome
494 shell scripts and utilities, put up on github. For further details and complete 494 shell scripts and utilities, put up on github. For further details and complete
495 documentation, visit the project's page at 'http://antigen.sharats.me'. 495 documentation, visit the project's page at 'http://antigen.sharats.me'.
496 EOF 496 EOF
497 } 497 }
498 498
499 # A syntax sugar to avoid the `-` when calling antigen commands. With this 499 # A syntax sugar to avoid the `-` when calling antigen commands. With this
500 # function, you can write `antigen-bundle` as `antigen bundle` and so on. 500 # function, you can write `antigen-bundle` as `antigen bundle` and so on.
501 antigen () { 501 antigen () {
502 local cmd="$1" 502 local cmd="$1"
503 shift 503 shift
504 "antigen-$cmd" "$@" 504 "antigen-$cmd" "$@"
505 } 505 }
506 506
507 -antigen-parse-args () { 507 -antigen-parse-args () {
508 # An argument parsing functionality to parse arguments the *antigen* way :). 508 # An argument parsing functionality to parse arguments the *antigen* way :).
509 # Takes one first argument (called spec), which dictates how to parse and 509 # Takes one first argument (called spec), which dictates how to parse and
510 # the rest of the arguments are parsed. Outputs a piece of valid shell code 510 # the rest of the arguments are parsed. Outputs a piece of valid shell code
511 # that can be passed to `eval` inside a function which creates the arguments 511 # that can be passed to `eval` inside a function which creates the arguments
512 # and their values as local variables. Suggested use is to set the defaults 512 # and their values as local variables. Suggested use is to set the defaults
513 # to all arguments first and then eval the output of this function. 513 # to all arguments first and then eval the output of this function.
514 514
515 # Spec: Only long argument supported. No support for parsing short options. 515 # Spec: Only long argument supported. No support for parsing short options.
516 # The spec must have two sections, separated by a `;`. 516 # The spec must have two sections, separated by a `;`.
517 # '<positional-arguments>;<keyword-only-arguments>' 517 # '<positional-arguments>;<keyword-only-arguments>'
518 # Positional arguments are passed as just values, like `command a b`. 518 # Positional arguments are passed as just values, like `command a b`.
519 # Keyword arguments are passed as a `--name=value` pair, like `command 519 # Keyword arguments are passed as a `--name=value` pair, like `command
520 # --arg1=a --arg2=b`. 520 # --arg1=a --arg2=b`.
521 521
522 # Each argument in the spec is separated by a `,`. Each keyword argument can 522 # Each argument in the spec is separated by a `,`. Each keyword argument can
523 # end in a `:` to specifiy that this argument wants a value, otherwise it 523 # end in a `:` to specifiy that this argument wants a value, otherwise it
524 # doesn't take a value. (The value in the output when the keyword argument 524 # doesn't take a value. (The value in the output when the keyword argument
525 # doesn't have a `:` is `true`). 525 # doesn't have a `:` is `true`).
526 526
527 # Arguments in either section can end with a `?` (should come after `:`, if 527 # Arguments in either section can end with a `?` (should come after `:`, if
528 # both are present), means optional. FIXME: Not yet implemented. 528 # both are present), means optional. FIXME: Not yet implemented.
529 529
530 # See the test file, tests/arg-parser.t for (working) examples. 530 # See the test file, tests/arg-parser.t for (working) examples.
531 531
532 local spec="$1" 532 local spec="$1"
533 shift 533 shift
534 534
535 # Sanitize the spec 535 # Sanitize the spec
536 spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')" 536 spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')"
537 537
538 local code='' 538 local code=''
539 539
540 --add-var () { 540 --add-var () {
541 test -z "$code" || code="$code\n" 541 test -z "$code" || code="$code\n"
542 code="${code}local $1='$2'" 542 code="${code}local $1='$2'"
543 } 543 }
544 544
545 local positional_args="$(echo "$spec" | cut -d\; -f1)" 545 local positional_args="$(echo "$spec" | cut -d\; -f1)"
546 local positional_args_count="$(echo $positional_args | 546 local positional_args_count="$(echo $positional_args |
547 awk -F, '{print NF}')" 547 awk -F, '{print NF}')"
548 548
549 # Set spec values based on the positional arguments. 549 # Set spec values based on the positional arguments.
550 local i=1 550 local i=1
551 while ! [[ -z $1 || $1 == --* ]]; do 551 while ! [[ -z $1 || $1 == --* ]]; do
552 552
553 if (( $i > $positional_args_count )); then 553 if (( $i > $positional_args_count )); then
554 echo "Only $positional_args_count positional arguments allowed." >&2 554 echo "Only $positional_args_count positional arguments allowed." >&2
555 echo "Found at least one more: '$1'" >&2 555 echo "Found at least one more: '$1'" >&2
556 return 556 return
557 fi 557 fi
558 558
559 local name_spec="$(echo "$positional_args" | cut -d, -f$i)" 559 local name_spec="$(echo "$positional_args" | cut -d, -f$i)"
560 local name="${${name_spec%\?}%:}" 560 local name="${${name_spec%\?}%:}"
561 local value="$1" 561 local value="$1"
562 562
563 if echo "$code" | grep -qm1 "^local $name="; then 563 if echo "$code" | grep -qm1 "^local $name="; then
564 echo "Argument '$name' repeated with the value '$value'". >&2 564 echo "Argument '$name' repeated with the value '$value'". >&2
565 return 565 return
566 fi 566 fi
567 567
568 --add-var $name "$value" 568 --add-var $name "$value"
569 569
570 shift 570 shift
571 i=$(($i + 1)) 571 i=$(($i + 1))
572 done 572 done
573 573
574 local keyword_args="$( 574 local keyword_args="$(
575 # Positional arguments can double up as keyword arguments too. 575 # Positional arguments can double up as keyword arguments too.
576 echo "$positional_args" | tr , '\n' | 576 echo "$positional_args" | tr , '\n' |
577 while read line; do 577 while read line; do
578 if [[ $line == *\? ]]; then 578 if [[ $line == *\? ]]; then
579 echo "${line%?}:?" 579 echo "${line%?}:?"
580 else 580 else
581 echo "$line:" 581 echo "$line:"
582 fi 582 fi
583 done 583 done
584 584
585 # Specified keyword arguments. 585 # Specified keyword arguments.
586 echo "$spec" | cut -d\; -f2 | tr , '\n' 586 echo "$spec" | cut -d\; -f2 | tr , '\n'
587 )" 587 )"
588 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')" 588 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')"
589 589
590 # Set spec values from keyword arguments, if any. The remaining arguments 590 # Set spec values from keyword arguments, if any. The remaining arguments
591 # are all assumed to be keyword arguments. 591 # are all assumed to be keyword arguments.
592 while [[ $1 == --* ]]; do 592 while [[ $1 == --* ]]; do
593 # Remove the `--` at the start. 593 # Remove the `--` at the start.
594 local arg="${1#--}" 594 local arg="${1#--}"
595 595
596 # Get the argument name and value. 596 # Get the argument name and value.
597 if [[ $arg != *=* ]]; then 597 if [[ $arg != *=* ]]; then
598 local name="$arg" 598 local name="$arg"
599 local value='' 599 local value=''
600 else 600 else
601 local name="${arg%\=*}" 601 local name="${arg%\=*}"
602 local value="${arg#*=}" 602 local value="${arg#*=}"
603 fi 603 fi
604 604
605 if echo "$code" | grep -qm1 "^local $name="; then 605 if echo "$code" | grep -qm1 "^local $name="; then
606 echo "Argument '$name' repeated with the value '$value'". >&2 606 echo "Argument '$name' repeated with the value '$value'". >&2
607 return 607 return
608 fi 608 fi
609 609
610 # The specification for this argument, used for validations. 610 # The specification for this argument, used for validations.
611 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")" 611 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")"
612 612
613 # Validate argument and value. 613 # Validate argument and value.
614 if [[ -z $arg_line ]]; then 614 if [[ -z $arg_line ]]; then
615 # This argument is not known to us. 615 # This argument is not known to us.
616 echo "Unknown argument '$name'." >&2 616 echo "Unknown argument '$name'." >&2
617 return 617 return
618 618
619 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then 619 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then
620 # This argument needs a value, but is not provided. 620 # This argument needs a value, but is not provided.
621 echo "Required argument for '$name' not provided." >&2 621 echo "Required argument for '$name' not provided." >&2
622 return 622 return
623 623
624 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then 624 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then
625 # This argument doesn't need a value, but is provided. 625 # This argument doesn't need a value, but is provided.
626 echo "No argument required for '$name', but provided '$value'." >&2 626 echo "No argument required for '$name', but provided '$value'." >&2
627 return 627 return
628 628
629 fi 629 fi
630 630
631 if [[ -z $value ]]; then 631 if [[ -z $value ]]; then
632 value=true 632 value=true
633 fi 633 fi
634 634
635 --add-var "${name//-/_}" "$value" 635 --add-var "${name//-/_}" "$value"
636 shift 636 shift
637 done 637 done
638 638
639 echo "$code" 639 echo "$code"
640 640
641 unfunction -- --add-var 641 unfunction -- --add-var
642 642
643 } 643 }
644 644
645 # Echo the bundle specs as in the record. The first line is not echoed since it 645 # Echo the bundle specs as in the record. The first line is not echoed since it
646 # is a blank line. 646 # is a blank line.
647 -antigen-echo-record () { 647 -antigen-echo-record () {
648 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p' 648 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
649 } 649 }
650 650
651 -antigen-env-setup () { 651 -antigen-env-setup () {
652 652
653 # Helper function: Same as `export $1=$2`, but will only happen if the name 653 # Helper function: Same as `export $1=$2`, but will only happen if the name
654 # specified by `$1` is not already set. 654 # specified by `$1` is not already set.
655 -set-default () { 655 -set-default () {
656 local arg_name="$1" 656 local arg_name="$1"
657 local arg_value="$2" 657 local arg_value="$2"
658 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'" 658 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
659 } 659 }
660 660
661 # Pre-startup initializations. 661 # Pre-startup initializations.
662 -set-default ANTIGEN_DEFAULT_REPO_URL \ 662 -set-default ANTIGEN_DEFAULT_REPO_URL \
663 https://github.com/robbyrussell/oh-my-zsh.git 663 https://github.com/robbyrussell/oh-my-zsh.git
664 -set-default ADOTDIR $HOME/.antigen 664 -set-default ADOTDIR $HOME/.antigen
665 665
666 # Load the compinit module. Required for `compdef` to be defined, which is 666 # Load the compinit module. Required for `compdef` to be defined, which is
667 # used by many plugins to define completions. 667 # used by many plugins to define completions.
668 autoload -U compinit 668 autoload -U compinit
669 compinit -i 669 compinit -i
670 670
671 # Setup antigen's own completion. 671 # Setup antigen's own completion.
672 compdef _antigen antigen 672 compdef _antigen antigen
673 673
674 # Remove private functions. 674 # Remove private functions.
675 unfunction -- -set-default 675 unfunction -- -set-default
676 } 676 }
677 677
678 # Setup antigen's autocompletion 678 # Setup antigen's autocompletion
679 _antigen () { 679 _antigen () {
680 compadd \ 680 compadd \
681 bundle \ 681 bundle \
682 bundles \ 682 bundles \
683 update \ 683 update \
684 revert \ 684 revert \
685 list \ 685 list \
686 cleanup \ 686 cleanup \
687 lib \ 687 lib \
688 selfupdate \ 688 selfupdate \
689 theme \ 689 theme \
690 apply \ 690 apply \
691 help 691 help
692 } 692 }
693 693
694 -antigen-env-setup 694 -antigen-env-setup
695 695