Commit 454a2c673efe30a6ba59d679fffac94da75a2153

Authored by Shrikant Sharat

Merge PR for allowing other urls. Fix #77.

Showing 1 changed file Inline Diff

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