Commit 5e23ab6fec6935fc10ae9b2242f1f73d56facd99

Authored by Will Boyce
Committed by Shrikant Sharat
1 parent 08e06125df

Defer `compdef` calls until after `compinit -i` is called

Conflicts:
	antigen.zsh

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