Commit 3e76602f837d1124fe00938da55015eb29bb105b

Authored by Corey Jewett
1 parent 6e46764655

cross platform md5

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