Commit 96f9ef54739841b53300624e7caa7fbc5b1d4519

Authored by Shrikant Sharat

Merge branch 'master' of https://github.com/xgarrido/antigen

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