Commit ce1316b685c0d9e9ac252230ac6f48b385083114

Authored by Shrikant Sharat

Merge pull request #62 from GUIpsp/patch-1

Update completion

Showing 1 changed file Inline Diff

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