Commit 3e92539689534f4e563fb95416ecb5c39f72c2c5

Authored by Shrikant Sharat
1 parent 3c16e1f03b

Moved `-set-default` into a private function.

Its polluting the global namespace but doesn't have the `antigen` prefix, making
it hard to figure out where it came from.

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