Commit c0ee02666f3790a41664db2dd2e4cda8fb5b5f5d

Authored by Hugaerts@gmail.com
Committed by Shrikant Sharat
1 parent 9a97880f48

add support for prezto plugins

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