Commit c0632ccd53f6a80cdd4facea78fa16713223caad

Authored by Shrikant Sharat

Merge commit 'a58d8cf'

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 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`
274 source "$location/init.zsh" 274 if (( $+functions[pmodload] )); then
275 275 # If pmodload is defined pmodload the module. Remove `modules/`
276 elif ls "$location" | grep -qm1 '\.zsh$'; then 276 # from loc to find module name.
277 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh` 277 pmodload "${loc#modules/}"
278 else
279 # Otherwise source it.
280 source "$location/init.zsh"
281 fi
282
283 elif ls "$location" | grep -qm1 '\.zsh$'; then
284 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh`
278 # files. 285 # files.
279 for script ($location/*.zsh(N)) source "$script" 286 for script ($location/*.zsh(N)) source "$script"
280 287
281 elif ls "$location" | grep -qm1 '\.sh$'; then 288 elif ls "$location" | grep -qm1 '\.sh$'; then
282 # If there are no `*.zsh` files either, we look for and source any 289 # If there are no `*.zsh` files either, we look for and source any
283 # `*.sh` files instead. 290 # `*.sh` files instead.
284 for script ($location/*.sh(N)) source "$script" 291 for script ($location/*.sh(N)) source "$script"
285 292
286 fi 293 fi
287 294
288 # Add to $fpath, for completion(s). 295 # Add to $fpath, for completion(s).
289 fpath=($location $fpath) 296 fpath=($location $fpath)
290 297
291 fi 298 fi
292 299
293 } 300 }
294 301
295 # Update (with `git pull`) antigen itself. 302 # Update (with `git pull`) antigen itself.
296 # TODO: Once update is finished, show a summary of the new commits, as a kind of 303 # TODO: Once update is finished, show a summary of the new commits, as a kind of
297 # "what's new" message. 304 # "what's new" message.
298 antigen-selfupdate () { 305 antigen-selfupdate () {
299 ( cd $_ANTIGEN_INSTALL_DIR 306 ( cd $_ANTIGEN_INSTALL_DIR
300 if [[ ! -d .git ]]; then 307 if [[ ! -d .git ]]; then
301 echo "Your copy of antigen doesn't appear to be a git clone. " \ 308 echo "Your copy of antigen doesn't appear to be a git clone. " \
302 "The 'selfupdate' command cannot work in this case." 309 "The 'selfupdate' command cannot work in this case."
303 return 1 310 return 1
304 fi 311 fi
305 git pull 312 git pull
306 ) 313 )
307 } 314 }
308 315
309 antigen-cleanup () { 316 antigen-cleanup () {
310 317
311 # Cleanup unused repositories. 318 # Cleanup unused repositories.
312 319
313 local force=false 320 local force=false
314 if [[ $1 == --force ]]; then 321 if [[ $1 == --force ]]; then
315 force=true 322 force=true
316 fi 323 fi
317 324
318 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then 325 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then
319 echo "You don't have any bundles." 326 echo "You don't have any bundles."
320 return 0 327 return 0
321 fi 328 fi
322 329
323 # Find directores in ADOTDIR/repos, that are not in the bundles record. 330 # Find directores in ADOTDIR/repos, that are not in the bundles record.
324 local unused_clones="$(comm -13 \ 331 local unused_clones="$(comm -13 \
325 <(-antigen-echo-record | 332 <(-antigen-echo-record |
326 awk '$4 == "true" {print $1}' | 333 awk '$4 == "true" {print $1}' |
327 while read line; do 334 while read line; do
328 -antigen-get-clone-dir "$line" 335 -antigen-get-clone-dir "$line"
329 done | 336 done |
330 sort -u) \ 337 sort -u) \
331 <(ls -d "$ADOTDIR/repos/"* | sort -u))" 338 <(ls -d "$ADOTDIR/repos/"* | sort -u))"
332 339
333 if [[ -z $unused_clones ]]; then 340 if [[ -z $unused_clones ]]; then
334 echo "You don't have any unidentified bundles." 341 echo "You don't have any unidentified bundles."
335 return 0 342 return 0
336 fi 343 fi
337 344
338 echo 'You have clones for the following repos, but are not used.' 345 echo 'You have clones for the following repos, but are not used.'
339 echo "$unused_clones" | 346 echo "$unused_clones" |
340 while read line; do 347 while read line; do
341 -antigen-get-clone-url "$line" 348 -antigen-get-clone-url "$line"
342 done | 349 done |
343 sed -e 's/^/ /' -e 's/|/, branch /' 350 sed -e 's/^/ /' -e 's/|/, branch /'
344 351
345 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then 352 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then
346 echo 353 echo
347 echo 354 echo
348 echo "$unused_clones" | while read line; do 355 echo "$unused_clones" | while read line; do
349 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..." 356 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..."
350 rm -rf "$line" 357 rm -rf "$line"
351 echo ' done.' 358 echo ' done.'
352 done 359 done
353 else 360 else
354 echo 361 echo
355 echo Nothing deleted. 362 echo Nothing deleted.
356 fi 363 fi
357 } 364 }
358 365
359 antigen-lib () { 366 antigen-lib () {
360 antigen-bundle --loc=lib 367 antigen-bundle --loc=lib
361 } 368 }
362 369
363 antigen-prezto-lib () { 370 antigen-prezto-lib () {
364 antigen-bundle sorin-ionescu/prezto 371 antigen-bundle sorin-ionescu/prezto
365 export ZDOTDIR=$ADOTDIR/repos/ 372 export ZDOTDIR=$ADOTDIR/repos/
366 } 373 }
367 374
368 antigen-theme () { 375 antigen-theme () {
369 376
370 if [[ "$1" != */* && "$1" != --* ]]; then 377 if [[ "$1" != */* && "$1" != --* ]]; then
371 # The first argument is just a name of the plugin, to be picked up from 378 # The first argument is just a name of the plugin, to be picked up from
372 # the default repo. 379 # the default repo.
373 local name="${1:-robbyrussell}" 380 local name="${1:-robbyrussell}"
374 antigen-bundle --loc=themes/$name --btype=theme 381 antigen-bundle --loc=themes/$name --btype=theme
375 382
376 else 383 else
377 antigen-bundle "$@" --btype=theme 384 antigen-bundle "$@" --btype=theme
378 385
379 fi 386 fi
380 387
381 } 388 }
382 389
383 antigen-apply () { 390 antigen-apply () {
384 # Initialize completion. 391 # Initialize completion.
385 # TODO: Only load completions if there are any changes to the bundle 392 # TODO: Only load completions if there are any changes to the bundle
386 # repositories. 393 # repositories.
387 compinit -i 394 compinit -i
388 } 395 }
389 396
390 antigen-list () { 397 antigen-list () {
391 # List all currently installed bundles. 398 # List all currently installed bundles.
392 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then 399 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
393 echo "You don't have any bundles." >&2 400 echo "You don't have any bundles." >&2
394 return 1 401 return 1
395 else 402 else
396 -antigen-echo-record | sort -u 403 -antigen-echo-record | sort -u
397 fi 404 fi
398 } 405 }
399 406
400 antigen-snapshot () { 407 antigen-snapshot () {
401 408
402 local snapshot_file="${1:-antigen-shapshot}" 409 local snapshot_file="${1:-antigen-shapshot}"
403 410
404 # The snapshot content lines are pairs of repo-url and git version hash, in 411 # The snapshot content lines are pairs of repo-url and git version hash, in
405 # the form: 412 # the form:
406 # <version-hash> <repo-url> 413 # <version-hash> <repo-url>
407 local snapshot_content="$(-antigen-echo-record | 414 local snapshot_content="$(-antigen-echo-record |
408 grep 'true$' | 415 grep 'true$' |
409 sed 's/ .*$//' | 416 sed 's/ .*$//' |
410 sort -u | 417 sort -u |
411 while read url; do 418 while read url; do
412 local dir="$(-antigen-get-clone-dir "$url")" 419 local dir="$(-antigen-get-clone-dir "$url")"
413 local version_hash="$(cd "$dir" && git rev-parse HEAD)" 420 local version_hash="$(cd "$dir" && git rev-parse HEAD)"
414 echo "$version_hash $url" 421 echo "$version_hash $url"
415 done)" 422 done)"
416 423
417 { 424 {
418 # The first line in the snapshot file is for metadata, in the form: 425 # The first line in the snapshot file is for metadata, in the form:
419 # key='value'; key='value'; key='value'; 426 # key='value'; key='value'; key='value';
420 # Where `key`s are valid shell variable names. 427 # Where `key`s are valid shell variable names.
421 428
422 # Snapshot version. Has no relation to antigen version. If the snapshot 429 # Snapshot version. Has no relation to antigen version. If the snapshot
423 # file format changes, this number can be incremented. 430 # file format changes, this number can be incremented.
424 echo -n "version='1';" 431 echo -n "version='1';"
425 432
426 # Snapshot creation date+time. 433 # Snapshot creation date+time.
427 echo -n " created_on='$(date)';" 434 echo -n " created_on='$(date)';"
428 435
429 # Add a checksum with the md5 checksum of all the snapshot lines. 436 # Add a checksum with the md5 checksum of all the snapshot lines.
430 local checksum="$(echo "$snapshot_content" | md5sum)" 437 local checksum="$(echo "$snapshot_content" | md5sum)"
431 echo -n " checksum='${checksum%% *}';" 438 echo -n " checksum='${checksum%% *}';"
432 439
433 # A newline after the metadata and then the snapshot lines. 440 # A newline after the metadata and then the snapshot lines.
434 echo "\n$snapshot_content" 441 echo "\n$snapshot_content"
435 442
436 } > "$snapshot_file" 443 } > "$snapshot_file"
437 444
438 } 445 }
439 446
440 antigen-restore () { 447 antigen-restore () {
441 448
442 if [[ $# == 0 ]]; then 449 if [[ $# == 0 ]]; then
443 echo 'Please provide a snapshot file to restore from.' >&2 450 echo 'Please provide a snapshot file to restore from.' >&2
444 return 1 451 return 1
445 fi 452 fi
446 453
447 local snapshot_file="$1" 454 local snapshot_file="$1"
448 455
449 # TODO: Before doing anything with the snapshot file, verify its checksum. 456 # TODO: Before doing anything with the snapshot file, verify its checksum.
450 # If it fails, notify this to the user and confirm if restore should 457 # If it fails, notify this to the user and confirm if restore should
451 # proceed. 458 # proceed.
452 459
453 echo -n "Restoring from $snapshot_file..." 460 echo -n "Restoring from $snapshot_file..."
454 461
455 sed -n '1!p' "$snapshot_file" | 462 sed -n '1!p' "$snapshot_file" |
456 while read line; do 463 while read line; do
457 464
458 local version_hash="${line%% *}" 465 local version_hash="${line%% *}"
459 local url="${line##* }" 466 local url="${line##* }"
460 local clone_dir="$(-antigen-get-clone-dir "$url")" 467 local clone_dir="$(-antigen-get-clone-dir "$url")"
461 468
462 if [[ ! -d $clone_dir ]]; then 469 if [[ ! -d $clone_dir ]]; then
463 git clone "$url" "$clone_dir" > /dev/null 470 git clone "$url" "$clone_dir" > /dev/null
464 fi 471 fi
465 472
466 (cd "$clone_dir" && git checkout $version_hash) 2> /dev/null 473 (cd "$clone_dir" && git checkout $version_hash) 2> /dev/null
467 474
468 done 475 done
469 476
470 echo ' done.' 477 echo ' done.'
471 echo 'Please open a new shell to get the restored changes.' 478 echo 'Please open a new shell to get the restored changes.'
472 } 479 }
473 480
474 antigen-help () { 481 antigen-help () {
475 cat <<EOF 482 cat <<EOF
476 Antigen is a plugin management system for zsh. It makes it easy to grab awesome 483 Antigen is a plugin management system for zsh. It makes it easy to grab awesome
477 shell scripts and utilities, put up on github. For further details and complete 484 shell scripts and utilities, put up on github. For further details and complete
478 documentation, visit the project's page at 'http://antigen.sharats.me'. 485 documentation, visit the project's page at 'http://antigen.sharats.me'.
479 EOF 486 EOF
480 } 487 }
481 488
482 # A syntax sugar to avoid the `-` when calling antigen commands. With this 489 # A syntax sugar to avoid the `-` when calling antigen commands. With this
483 # function, you can write `antigen-bundle` as `antigen bundle` and so on. 490 # function, you can write `antigen-bundle` as `antigen bundle` and so on.
484 antigen () { 491 antigen () {
485 local cmd="$1" 492 local cmd="$1"
486 shift 493 shift
487 "antigen-$cmd" "$@" 494 "antigen-$cmd" "$@"
488 } 495 }
489 496
490 -antigen-parse-args () { 497 -antigen-parse-args () {
491 # An argument parsing functionality to parse arguments the *antigen* way :). 498 # An argument parsing functionality to parse arguments the *antigen* way :).
492 # Takes one first argument (called spec), which dictates how to parse and 499 # Takes one first argument (called spec), which dictates how to parse and
493 # the rest of the arguments are parsed. Outputs a piece of valid shell code 500 # the rest of the arguments are parsed. Outputs a piece of valid shell code
494 # that can be passed to `eval` inside a function which creates the arguments 501 # that can be passed to `eval` inside a function which creates the arguments
495 # and their values as local variables. Suggested use is to set the defaults 502 # and their values as local variables. Suggested use is to set the defaults
496 # to all arguments first and then eval the output of this function. 503 # to all arguments first and then eval the output of this function.
497 504
498 # Spec: Only long argument supported. No support for parsing short options. 505 # Spec: Only long argument supported. No support for parsing short options.
499 # The spec must have two sections, separated by a `;`. 506 # The spec must have two sections, separated by a `;`.
500 # '<positional-arguments>;<keyword-only-arguments>' 507 # '<positional-arguments>;<keyword-only-arguments>'
501 # Positional arguments are passed as just values, like `command a b`. 508 # Positional arguments are passed as just values, like `command a b`.
502 # Keyword arguments are passed as a `--name=value` pair, like `command 509 # Keyword arguments are passed as a `--name=value` pair, like `command
503 # --arg1=a --arg2=b`. 510 # --arg1=a --arg2=b`.
504 511
505 # Each argument in the spec is separated by a `,`. Each keyword argument can 512 # Each argument in the spec is separated by a `,`. Each keyword argument can
506 # end in a `:` to specifiy that this argument wants a value, otherwise it 513 # end in a `:` to specifiy that this argument wants a value, otherwise it
507 # doesn't take a value. (The value in the output when the keyword argument 514 # doesn't take a value. (The value in the output when the keyword argument
508 # doesn't have a `:` is `true`). 515 # doesn't have a `:` is `true`).
509 516
510 # Arguments in either section can end with a `?` (should come after `:`, if 517 # Arguments in either section can end with a `?` (should come after `:`, if
511 # both are present), means optional. FIXME: Not yet implemented. 518 # both are present), means optional. FIXME: Not yet implemented.
512 519
513 # See the test file, tests/arg-parser.t for (working) examples. 520 # See the test file, tests/arg-parser.t for (working) examples.
514 521
515 local spec="$1" 522 local spec="$1"
516 shift 523 shift
517 524
518 # Sanitize the spec 525 # Sanitize the spec
519 spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')" 526 spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')"
520 527
521 local code='' 528 local code=''
522 529
523 --add-var () { 530 --add-var () {
524 test -z "$code" || code="$code\n" 531 test -z "$code" || code="$code\n"
525 code="${code}local $1='$2'" 532 code="${code}local $1='$2'"
526 } 533 }
527 534
528 local positional_args="$(echo "$spec" | cut -d\; -f1)" 535 local positional_args="$(echo "$spec" | cut -d\; -f1)"
529 local positional_args_count="$(echo $positional_args | 536 local positional_args_count="$(echo $positional_args |
530 awk -F, '{print NF}')" 537 awk -F, '{print NF}')"
531 538
532 # Set spec values based on the positional arguments. 539 # Set spec values based on the positional arguments.
533 local i=1 540 local i=1
534 while ! [[ -z $1 || $1 == --* ]]; do 541 while ! [[ -z $1 || $1 == --* ]]; do
535 542
536 if (( $i > $positional_args_count )); then 543 if (( $i > $positional_args_count )); then
537 echo "Only $positional_args_count positional arguments allowed." >&2 544 echo "Only $positional_args_count positional arguments allowed." >&2
538 echo "Found at least one more: '$1'" >&2 545 echo "Found at least one more: '$1'" >&2
539 return 546 return
540 fi 547 fi
541 548
542 local name_spec="$(echo "$positional_args" | cut -d, -f$i)" 549 local name_spec="$(echo "$positional_args" | cut -d, -f$i)"
543 local name="${${name_spec%\?}%:}" 550 local name="${${name_spec%\?}%:}"
544 local value="$1" 551 local value="$1"
545 552
546 if echo "$code" | grep -qm1 "^local $name="; then 553 if echo "$code" | grep -qm1 "^local $name="; then
547 echo "Argument '$name' repeated with the value '$value'". >&2 554 echo "Argument '$name' repeated with the value '$value'". >&2
548 return 555 return
549 fi 556 fi
550 557
551 --add-var $name "$value" 558 --add-var $name "$value"
552 559
553 shift 560 shift
554 i=$(($i + 1)) 561 i=$(($i + 1))
555 done 562 done
556 563
557 local keyword_args="$( 564 local keyword_args="$(
558 # Positional arguments can double up as keyword arguments too. 565 # Positional arguments can double up as keyword arguments too.
559 echo "$positional_args" | tr , '\n' | 566 echo "$positional_args" | tr , '\n' |
560 while read line; do 567 while read line; do
561 if [[ $line == *\? ]]; then 568 if [[ $line == *\? ]]; then
562 echo "${line%?}:?" 569 echo "${line%?}:?"
563 else 570 else
564 echo "$line:" 571 echo "$line:"
565 fi 572 fi
566 done 573 done
567 574
568 # Specified keyword arguments. 575 # Specified keyword arguments.
569 echo "$spec" | cut -d\; -f2 | tr , '\n' 576 echo "$spec" | cut -d\; -f2 | tr , '\n'
570 )" 577 )"
571 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')" 578 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')"
572 579
573 # Set spec values from keyword arguments, if any. The remaining arguments 580 # Set spec values from keyword arguments, if any. The remaining arguments
574 # are all assumed to be keyword arguments. 581 # are all assumed to be keyword arguments.
575 while [[ $1 == --* ]]; do 582 while [[ $1 == --* ]]; do
576 # Remove the `--` at the start. 583 # Remove the `--` at the start.
577 local arg="${1#--}" 584 local arg="${1#--}"
578 585
579 # Get the argument name and value. 586 # Get the argument name and value.
580 if [[ $arg != *=* ]]; then 587 if [[ $arg != *=* ]]; then
581 local name="$arg" 588 local name="$arg"
582 local value='' 589 local value=''
583 else 590 else
584 local name="${arg%\=*}" 591 local name="${arg%\=*}"
585 local value="${arg#*=}" 592 local value="${arg#*=}"
586 fi 593 fi
587 594
588 if echo "$code" | grep -qm1 "^local $name="; then 595 if echo "$code" | grep -qm1 "^local $name="; then
589 echo "Argument '$name' repeated with the value '$value'". >&2 596 echo "Argument '$name' repeated with the value '$value'". >&2
590 return 597 return
591 fi 598 fi
592 599
593 # The specification for this argument, used for validations. 600 # The specification for this argument, used for validations.
594 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")" 601 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")"
595 602
596 # Validate argument and value. 603 # Validate argument and value.
597 if [[ -z $arg_line ]]; then 604 if [[ -z $arg_line ]]; then
598 # This argument is not known to us. 605 # This argument is not known to us.
599 echo "Unknown argument '$name'." >&2 606 echo "Unknown argument '$name'." >&2
600 return 607 return
601 608
602 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then 609 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then
603 # This argument needs a value, but is not provided. 610 # This argument needs a value, but is not provided.
604 echo "Required argument for '$name' not provided." >&2 611 echo "Required argument for '$name' not provided." >&2
605 return 612 return
606 613
607 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then 614 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then
608 # This argument doesn't need a value, but is provided. 615 # This argument doesn't need a value, but is provided.
609 echo "No argument required for '$name', but provided '$value'." >&2 616 echo "No argument required for '$name', but provided '$value'." >&2
610 return 617 return
611 618
612 fi 619 fi
613 620
614 if [[ -z $value ]]; then 621 if [[ -z $value ]]; then
615 value=true 622 value=true
616 fi 623 fi
617 624
618 --add-var "${name//-/_}" "$value" 625 --add-var "${name//-/_}" "$value"
619 shift 626 shift
620 done 627 done
621 628
622 echo "$code" 629 echo "$code"
623 630
624 unfunction -- --add-var 631 unfunction -- --add-var
625 632
626 } 633 }
627 634
628 # Echo the bundle specs as in the record. The first line is not echoed since it 635 # Echo the bundle specs as in the record. The first line is not echoed since it
629 # is a blank line. 636 # is a blank line.
630 -antigen-echo-record () { 637 -antigen-echo-record () {
631 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p' 638 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
632 } 639 }
633 640
634 -antigen-env-setup () { 641 -antigen-env-setup () {
635 642
636 # Helper function: Same as `export $1=$2`, but will only happen if the name 643 # Helper function: Same as `export $1=$2`, but will only happen if the name
637 # specified by `$1` is not already set. 644 # specified by `$1` is not already set.
638 -set-default () { 645 -set-default () {
639 local arg_name="$1" 646 local arg_name="$1"
640 local arg_value="$2" 647 local arg_value="$2"
641 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'" 648 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
642 } 649 }
643 650
644 # Pre-startup initializations. 651 # Pre-startup initializations.
645 -set-default ANTIGEN_DEFAULT_REPO_URL \ 652 -set-default ANTIGEN_DEFAULT_REPO_URL \
646 https://github.com/robbyrussell/oh-my-zsh.git 653 https://github.com/robbyrussell/oh-my-zsh.git
647 -set-default ADOTDIR $HOME/.antigen 654 -set-default ADOTDIR $HOME/.antigen
648 655
649 # Load the compinit module. Required for `compdef` to be defined, which is 656 # Load the compinit module. Required for `compdef` to be defined, which is
650 # used by many plugins to define completions. 657 # used by many plugins to define completions.
651 autoload -U compinit 658 autoload -U compinit
652 compinit -i 659 compinit -i
653 660
654 # Setup antigen's own completion. 661 # Setup antigen's own completion.
655 compdef _antigen antigen 662 compdef _antigen antigen
656 663
657 # Remove private functions. 664 # Remove private functions.
658 unfunction -- -set-default 665 unfunction -- -set-default
659 } 666 }
660 667
661 # Setup antigen's autocompletion 668 # Setup antigen's autocompletion
662 _antigen () { 669 _antigen () {
663 compadd \ 670 compadd \
664 bundle \ 671 bundle \
665 bundles \ 672 bundles \
666 update \ 673 update \
667 revert \ 674 revert \
668 list \ 675 list \
669 cleanup \ 676 cleanup \
670 lib \ 677 lib \
671 selfupdate \ 678 selfupdate \
672 theme \ 679 theme \
673 apply \ 680 apply \
674 help 681 help
675 } 682 }
676 683
677 -antigen-env-setup 684 -antigen-env-setup
678 685