Commit e393155e3391f243d7fc01c4a9a04f74a29b9095

Authored by Josh Matthews
1 parent b7d2d3e0c1

Making _ANTIGEN_INSTALL_DIR use absolute path.

This will prevent errors if someone sources antigen using a relative
path.

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

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