Commit 723b284b473aae6f565803b4c91176190f9c8d91

Authored by Shrikant Sharat
1 parent 7a2ca59361

Use the arg parsing fn in -ensure-repo command.

Showing 1 changed file with 5 additions and 7 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 8
9 # Syntaxes 9 # Syntaxes
10 # antigen-bundle <url> [<loc>=/] 10 # antigen-bundle <url> [<loc>=/]
11 # Keyword only arguments: 11 # Keyword only arguments:
12 # branch - The branch of the repo to use for this bundle. 12 # branch - The branch of the repo to use for this bundle.
13 antigen-bundle () { 13 antigen-bundle () {
14 14
15 # Bundle spec arguments' default values. 15 # Bundle spec arguments' default values.
16 local url="$ANTIGEN_DEFAULT_REPO_URL" 16 local url="$ANTIGEN_DEFAULT_REPO_URL"
17 local loc=/ 17 local loc=/
18 local branch= 18 local branch=
19 local no_local_clone=false 19 local no_local_clone=false
20 local btype=plugin 20 local btype=plugin
21 21
22 # Parse the given arguments. (Will overwrite the above values). 22 # Parse the given arguments. (Will overwrite the above values).
23 eval "$(-antigen-parse-args \ 23 eval "$(-antigen-parse-args \
24 'url?, loc? ; branch:?, no-local-clone?, btype:?' \ 24 'url?, loc? ; branch:?, no-local-clone?, btype:?' \
25 "$@")" 25 "$@")"
26 26
27 # Check if url is just the plugin name. Super short syntax. 27 # Check if url is just the plugin name. Super short syntax.
28 if [[ "$url" != */* ]]; then 28 if [[ "$url" != */* ]]; then
29 loc="plugins/$url" 29 loc="plugins/$url"
30 url="$ANTIGEN_DEFAULT_REPO_URL" 30 url="$ANTIGEN_DEFAULT_REPO_URL"
31 fi 31 fi
32 32
33 # Resolve the url. 33 # Resolve the url.
34 url="$(-antigen-resolve-bundle-url "$url")" 34 url="$(-antigen-resolve-bundle-url "$url")"
35 35
36 # Add the branch information to the url. 36 # Add the branch information to the url.
37 if [[ ! -z $branch ]]; then 37 if [[ ! -z $branch ]]; then
38 url="$url|$branch" 38 url="$url|$branch"
39 fi 39 fi
40 40
41 # The `make_local_clone` variable better represents whether there should be 41 # The `make_local_clone` variable better represents whether there should be
42 # a local clone made. For cloning to be avoided, firstly, the `$url` should 42 # a local clone made. For cloning to be avoided, firstly, the `$url` should
43 # be an absolute local path and `$branch` should be empty. In addition to 43 # be an absolute local path and `$branch` should be empty. In addition to
44 # these two conditions, either the `--no-local-clone` option should be 44 # these two conditions, either the `--no-local-clone` option should be
45 # given, or `$url` should not a git repo. 45 # given, or `$url` should not a git repo.
46 local make_local_clone=true 46 local make_local_clone=true
47 if [[ $url == /* && -z $branch && 47 if [[ $url == /* && -z $branch &&
48 ( $no_local_clone == true || ! -d $url/.git ) ]]; then 48 ( $no_local_clone == true || ! -d $url/.git ) ]]; then
49 make_local_clone=false 49 make_local_clone=false
50 fi 50 fi
51 51
52 # Add it to the record. 52 # Add it to the record.
53 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype" 53 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype"
54 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone" 54 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone"
55 55
56 # Ensure a clone exists for this repo, if needed. 56 # Ensure a clone exists for this repo, if needed.
57 if $make_local_clone; then 57 if $make_local_clone; then
58 -antigen-ensure-repo "$url" 58 -antigen-ensure-repo "$url"
59 fi 59 fi
60 60
61 # Load the plugin. 61 # Load the plugin.
62 -antigen-load "$url" "$loc" "$btype" "$make_local_clone" 62 -antigen-load "$url" "$loc" "$btype" "$make_local_clone"
63 63
64 } 64 }
65 65
66 -antigen-resolve-bundle-url () { 66 -antigen-resolve-bundle-url () {
67 # Given an acceptable short/full form of a bundle's repo url, this function 67 # Given an acceptable short/full form of a bundle's repo url, this function
68 # echoes the full form of the repo's clone url. 68 # echoes the full form of the repo's clone url.
69 69
70 local url="$1" 70 local url="$1"
71 71
72 # Expand short github url syntax: `username/reponame`. 72 # Expand short github url syntax: `username/reponame`.
73 if [[ $url != git://* && 73 if [[ $url != git://* &&
74 $url != https://* && 74 $url != https://* &&
75 $url != /* && 75 $url != /* &&
76 $url != git@github.com:*/* 76 $url != git@github.com:*/*
77 ]]; then 77 ]]; then
78 url="https://github.com/${url%.git}.git" 78 url="https://github.com/${url%.git}.git"
79 fi 79 fi
80 80
81 echo "$url" 81 echo "$url"
82 } 82 }
83 83
84 antigen-bundles () { 84 antigen-bundles () {
85 # Bulk add many bundles at one go. Empty lines and lines starting with a `#` 85 # Bulk add many bundles at one go. Empty lines and lines starting with a `#`
86 # are ignored. Everything else is given to `antigen-bundle` as is, no 86 # are ignored. Everything else is given to `antigen-bundle` as is, no
87 # quoting rules applied. 87 # quoting rules applied.
88 88
89 local line 89 local line
90 90
91 grep -v '^\s*$\|^#' | while read line; do 91 grep -v '^\s*$\|^#' | while read line; do
92 # Using `eval` so that we can use the shell-style quoting in each line 92 # Using `eval` so that we can use the shell-style quoting in each line
93 # piped to `antigen-bundles`. 93 # piped to `antigen-bundles`.
94 eval "antigen-bundle $line" 94 eval "antigen-bundle $line"
95 done 95 done
96 } 96 }
97 97
98 antigen-update () { 98 antigen-update () {
99 # Update your bundles, i.e., `git pull` in all the plugin repos. 99 # Update your bundles, i.e., `git pull` in all the plugin repos.
100 -antigen-echo-record | 100 -antigen-echo-record |
101 awk '{print $1}' | 101 awk '{print $1}' |
102 sort -u | 102 sort -u |
103 while read url; do 103 while read url; do
104 echo "**** Pulling $url" 104 echo "**** Pulling $url"
105 -antigen-ensure-repo --update --verbose "$url" 105 -antigen-ensure-repo "$url" --update --verbose
106 echo 106 echo
107 done 107 done
108 } 108 }
109 109
110 -antigen-get-clone-dir () { 110 -antigen-get-clone-dir () {
111 # Takes a repo url and gives out the path that this url needs to be cloned 111 # Takes a repo url and gives out the path that this url needs to be cloned
112 # to. Doesn't actually clone anything. 112 # to. Doesn't actually clone anything.
113 # TODO: Memoize? 113 # TODO: Memoize?
114 114
115 # The url given. 115 # The url given.
116 local url="$1" 116 local url="$1"
117 117
118 # Echo the full path to the clone directory. 118 # Echo the full path to the clone directory.
119 echo -n $ADOTDIR/repos/ 119 echo -n $ADOTDIR/repos/
120 echo "$url" | sed \ 120 echo "$url" | sed \
121 -e 's./.-SLASH-.g' \ 121 -e 's./.-SLASH-.g' \
122 -e 's.:.-COLON-.g' \ 122 -e 's.:.-COLON-.g' \
123 -e 's.|.-PIPE-.g' 123 -e 's.|.-PIPE-.g'
124 } 124 }
125 125
126 -antigen-get-clone-url () { 126 -antigen-get-clone-url () {
127 # Takes a repo's clone dir and gives out the repo's original url that was 127 # Takes a repo's clone dir and gives out the repo's original url that was
128 # used to create the given directory path. 128 # used to create the given directory path.
129 # TODO: Memoize? 129 # TODO: Memoize?
130 echo "$1" | sed \ 130 echo "$1" | sed \
131 -e "s:^$ADOTDIR/repos/::" \ 131 -e "s:^$ADOTDIR/repos/::" \
132 -e 's.-SLASH-./.g' \ 132 -e 's.-SLASH-./.g' \
133 -e 's.-COLON-.:.g' \ 133 -e 's.-COLON-.:.g' \
134 -e 's.-PIPE-.|.g' 134 -e 's.-PIPE-.|.g'
135 } 135 }
136 136
137 -antigen-ensure-repo () { 137 -antigen-ensure-repo () {
138 138
139 # Ensure that a clone exists for the given repo url and branch. If the first 139 # Ensure that a clone exists for the given repo url and branch. If the first
140 # argument is `--update` and if a clone already exists for the given repo 140 # argument is `--update` and if a clone already exists for the given repo
141 # and branch, it is pull-ed, i.e., updated. 141 # and branch, it is pull-ed, i.e., updated.
142 142
143 # Argument defaults. 143 # Argument defaults.
144 # The url. No sane default for this, so just empty.
145 local url=
144 # Check if we have to update. 146 # Check if we have to update.
145 local update=false 147 local update=false
146 # Verbose output. 148 # Verbose output.
147 local verbose=false 149 local verbose=false
148 150
149 # Load any boolean arguments specified. 151 eval "$(-antigen-parse-args 'url ; update?, verbose?' "$@")"
150 while [[ $1 == --* ]]; do 152 shift $#
151 eval "local '${1#--}=true'"
152 shift
153 done
154 153
155 # Get the clone's directory as per the given repo url and branch. 154 # Get the clone's directory as per the given repo url and branch.
156 local url="$1"
157 local clone_dir="$(-antigen-get-clone-dir $url)" 155 local clone_dir="$(-antigen-get-clone-dir $url)"
158 156
159 # A temporary function wrapping the `git` command with repeated arguments. 157 # A temporary function wrapping the `git` command with repeated arguments.
160 --plugin-git () { 158 --plugin-git () {
161 eval git --git-dir=$clone_dir/.git --work-tree=$clone_dir "$@" 159 eval git --git-dir=$clone_dir/.git --work-tree=$clone_dir "$@"
162 } 160 }
163 161
164 # Clone if it doesn't already exist. 162 # Clone if it doesn't already exist.
165 if [[ ! -d $clone_dir ]]; then 163 if [[ ! -d $clone_dir ]]; then
166 git clone "${url%|*}" "$clone_dir" 164 git clone "${url%|*}" "$clone_dir"
167 elif $update; then 165 elif $update; then
168 # Save current revision. 166 # Save current revision.
169 local old_rev="$(--plugin-git rev-parse HEAD)" 167 local old_rev="$(--plugin-git rev-parse HEAD)"
170 # Pull changes if update requested. 168 # Pull changes if update requested.
171 --plugin-git pull 169 --plugin-git pull
172 # Get the new revision. 170 # Get the new revision.
173 local new_rev="$(--plugin-git rev-parse HEAD)" 171 local new_rev="$(--plugin-git rev-parse HEAD)"
174 fi 172 fi
175 173
176 # If its a specific branch that we want, checkout that branch. 174 # If its a specific branch that we want, checkout that branch.
177 if [[ $url == *\|* ]]; then 175 if [[ $url == *\|* ]]; then
178 local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/} 176 local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/}
179 local requested_branch="${url#*|}" 177 local requested_branch="${url#*|}"
180 # Only do the checkout when we are not already on the branch. 178 # Only do the checkout when we are not already on the branch.
181 [[ $requested_branch != $current_branch ]] && 179 [[ $requested_branch != $current_branch ]] &&
182 --plugin-git checkout $requested_branch 180 --plugin-git checkout $requested_branch
183 fi 181 fi
184 182
185 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then 183 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then
186 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}. 184 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}.
187 if $verbose; then 185 if $verbose; then
188 --plugin-git log --oneline --reverse --no-merges --stat '@{1}..' 186 --plugin-git log --oneline --reverse --no-merges --stat '@{1}..'
189 fi 187 fi
190 fi 188 fi
191 189
192 # Remove the temporary git wrapper function. 190 # Remove the temporary git wrapper function.
193 unfunction -- --plugin-git 191 unfunction -- --plugin-git
194 192
195 } 193 }
196 194
197 -antigen-load () { 195 -antigen-load () {
198 196
199 local url="$1" 197 local url="$1"
200 local loc="$2" 198 local loc="$2"
201 local btype="$3" 199 local btype="$3"
202 local make_local_clone="$4" 200 local make_local_clone="$4"
203 201
204 # The full location where the plugin is located. 202 # The full location where the plugin is located.
205 local location 203 local location
206 if $make_local_clone; then 204 if $make_local_clone; then
207 location="$(-antigen-get-clone-dir "$url")/$loc" 205 location="$(-antigen-get-clone-dir "$url")/$loc"
208 else 206 else
209 location="$url" 207 location="$url"
210 fi 208 fi
211 209
212 if [[ $btype == theme ]]; then 210 if [[ $btype == theme ]]; then
213 211
214 # Of course, if its a theme, the location would point to the script 212 # Of course, if its a theme, the location would point to the script
215 # file. 213 # file.
216 source "$location" 214 source "$location"
217 215
218 else 216 else
219 217
220 # Source the plugin script. 218 # Source the plugin script.
221 # FIXME: I don't know. Looks very very ugly. Needs a better 219 # FIXME: I don't know. Looks very very ugly. Needs a better
222 # implementation once tests are ready. 220 # implementation once tests are ready.
223 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')" 221 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')"
224 222
225 if [[ -f $script_loc ]]; then 223 if [[ -f $script_loc ]]; then
226 # If we have a `*.plugin.zsh`, source it. 224 # If we have a `*.plugin.zsh`, source it.
227 source "$script_loc" 225 source "$script_loc"
228 226
229 elif [[ ! -z "$(ls "$location" | grep -m1 '\.zsh$')" ]]; then 227 elif [[ ! -z "$(ls "$location" | grep -m1 '\.zsh$')" ]]; then
230 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh` 228 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh`
231 # files. 229 # files.
232 for script ($location/*.zsh(N)) source "$script" 230 for script ($location/*.zsh(N)) source "$script"
233 231
234 elif [[ ! -z "$(ls "$location" | grep -m1 '\.sh$')" ]]; then 232 elif [[ ! -z "$(ls "$location" | grep -m1 '\.sh$')" ]]; then
235 # If there are no `*.zsh` files either, we look for and source any 233 # If there are no `*.zsh` files either, we look for and source any
236 # `*.sh` files instead. 234 # `*.sh` files instead.
237 for script ($location/*.sh(N)) source "$script" 235 for script ($location/*.sh(N)) source "$script"
238 236
239 fi 237 fi
240 238
241 # Add to $fpath, for completion(s). 239 # Add to $fpath, for completion(s).
242 fpath=($location $fpath) 240 fpath=($location $fpath)
243 241
244 fi 242 fi
245 243
246 } 244 }
247 245
248 antigen-cleanup () { 246 antigen-cleanup () {
249 247
250 # Cleanup unused repositories. 248 # Cleanup unused repositories.
251 249
252 local force=false 250 local force=false
253 if [[ $1 == --force ]]; then 251 if [[ $1 == --force ]]; then
254 force=true 252 force=true
255 fi 253 fi
256 254
257 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then 255 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then
258 echo "You don't have any bundles." 256 echo "You don't have any bundles."
259 return 0 257 return 0
260 fi 258 fi
261 259
262 # Find directores in ADOTDIR/repos, that are not in the bundles record. 260 # Find directores in ADOTDIR/repos, that are not in the bundles record.
263 local unused_clones="$(comm -13 \ 261 local unused_clones="$(comm -13 \
264 <(-antigen-echo-record | 262 <(-antigen-echo-record |
265 awk '$4 == "true" {print $1}' | 263 awk '$4 == "true" {print $1}' |
266 while read line; do 264 while read line; do
267 -antigen-get-clone-dir "$line" 265 -antigen-get-clone-dir "$line"
268 done | 266 done |
269 sort -u) \ 267 sort -u) \
270 <(ls -d "$ADOTDIR/repos/"* | sort -u))" 268 <(ls -d "$ADOTDIR/repos/"* | sort -u))"
271 269
272 if [[ -z $unused_clones ]]; then 270 if [[ -z $unused_clones ]]; then
273 echo "You don't have any unidentified bundles." 271 echo "You don't have any unidentified bundles."
274 return 0 272 return 0
275 fi 273 fi
276 274
277 echo 'You have clones for the following repos, but are not used.' 275 echo 'You have clones for the following repos, but are not used.'
278 echo "$unused_clones" | 276 echo "$unused_clones" |
279 while read line; do 277 while read line; do
280 -antigen-get-clone-url "$line" 278 -antigen-get-clone-url "$line"
281 done | 279 done |
282 sed -e 's/^/ /' -e 's/|/, branch /' 280 sed -e 's/^/ /' -e 's/|/, branch /'
283 281
284 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then 282 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then
285 echo 283 echo
286 echo 284 echo
287 echo "$unused_clones" | while read line; do 285 echo "$unused_clones" | while read line; do
288 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..." 286 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..."
289 rm -rf "$line" 287 rm -rf "$line"
290 echo ' done.' 288 echo ' done.'
291 done 289 done
292 else 290 else
293 echo 291 echo
294 echo Nothing deleted. 292 echo Nothing deleted.
295 fi 293 fi
296 } 294 }
297 295
298 antigen-lib () { 296 antigen-lib () {
299 antigen-bundle --loc=lib 297 antigen-bundle --loc=lib
300 } 298 }
301 299
302 antigen-theme () { 300 antigen-theme () {
303 local name="${1:-robbyrussell}" 301 local name="${1:-robbyrussell}"
304 antigen-bundle --loc=themes/$name.zsh-theme --btype=theme 302 antigen-bundle --loc=themes/$name.zsh-theme --btype=theme
305 } 303 }
306 304
307 antigen-apply () { 305 antigen-apply () {
308 # Initialize completion. 306 # Initialize completion.
309 # TODO: Only load completions if there are any changes to the bundle 307 # TODO: Only load completions if there are any changes to the bundle
310 # repositories. 308 # repositories.
311 compinit -i 309 compinit -i
312 } 310 }
313 311
314 antigen-list () { 312 antigen-list () {
315 # List all currently installed bundles. 313 # List all currently installed bundles.
316 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then 314 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
317 echo "You don't have any bundles." >&2 315 echo "You don't have any bundles." >&2
318 return 1 316 return 1
319 else 317 else
320 -antigen-echo-record | sort -u 318 -antigen-echo-record | sort -u
321 fi 319 fi
322 } 320 }
323 321
324 antigen-help () { 322 antigen-help () {
325 cat <<EOF 323 cat <<EOF
326 Antigen is a plugin management system for zsh. It makes it easy to grab awesome 324 Antigen is a plugin management system for zsh. It makes it easy to grab awesome
327 shell scripts and utilities, put up on github. For further details and complete 325 shell scripts and utilities, put up on github. For further details and complete
328 documentation, visit the project's page at 'http://antigen.sharats.me'. 326 documentation, visit the project's page at 'http://antigen.sharats.me'.
329 EOF 327 EOF
330 } 328 }
331 329
332 # A syntax sugar to avoid the `-` when calling antigen commands. With this 330 # A syntax sugar to avoid the `-` when calling antigen commands. With this
333 # function, you can write `antigen-bundle` as `antigen bundle` and so on. 331 # function, you can write `antigen-bundle` as `antigen bundle` and so on.
334 antigen () { 332 antigen () {
335 local cmd="$1" 333 local cmd="$1"
336 shift 334 shift
337 "antigen-$cmd" "$@" 335 "antigen-$cmd" "$@"
338 } 336 }
339 337
340 -antigen-parse-args () { 338 -antigen-parse-args () {
341 # An argument parsing functionality to parse arguments the *antigen* way :). 339 # An argument parsing functionality to parse arguments the *antigen* way :).
342 # Takes one first argument (called spec), which dictates how to parse and 340 # Takes one first argument (called spec), which dictates how to parse and
343 # the rest of the arguments are parsed. Outputs a piece of valid shell code 341 # the rest of the arguments are parsed. Outputs a piece of valid shell code
344 # that can be passed to `eval` inside a function which creates the arguments 342 # that can be passed to `eval` inside a function which creates the arguments
345 # and their values as local variables. Suggested use is to set the defaults 343 # and their values as local variables. Suggested use is to set the defaults
346 # to all arguments first and then eval the output of this function. 344 # to all arguments first and then eval the output of this function.
347 345
348 # Spec: Only long argument supported. No support for parsing short options. 346 # Spec: Only long argument supported. No support for parsing short options.
349 # The spec must have two sections, separated by a `;`. 347 # The spec must have two sections, separated by a `;`.
350 # '<positional-arguments>;<keyword-only-arguments>' 348 # '<positional-arguments>;<keyword-only-arguments>'
351 # Positional arguments are passed as just values, like `command a b`. 349 # Positional arguments are passed as just values, like `command a b`.
352 # Keyword arguments are passed as a `--name=value` pair, like `command 350 # Keyword arguments are passed as a `--name=value` pair, like `command
353 # --arg1=a --arg2=b`. 351 # --arg1=a --arg2=b`.
354 352
355 # Each argument in the spec is separated by a `,`. Each keyword argument can 353 # Each argument in the spec is separated by a `,`. Each keyword argument can
356 # end in a `:` to specifiy that this argument wants a value, otherwise it 354 # end in a `:` to specifiy that this argument wants a value, otherwise it
357 # doesn't take a value. (The value in the output when the keyword argument 355 # doesn't take a value. (The value in the output when the keyword argument
358 # doesn't have a `:` is `true`). 356 # doesn't have a `:` is `true`).
359 357
360 # Arguments in either section can end with a `?` (should come after `:`, if 358 # Arguments in either section can end with a `?` (should come after `:`, if
361 # both are present), means optional. FIXME: Not yet implemented. 359 # both are present), means optional. FIXME: Not yet implemented.
362 360
363 # See the test file, tests/arg-parser.t for (working) examples. 361 # See the test file, tests/arg-parser.t for (working) examples.
364 362
365 local spec="$1" 363 local spec="$1"
366 shift 364 shift
367 365
368 # Sanitize the spec 366 # Sanitize the spec
369 spec="$(echo "$spec" | tr '\n' ' ' | sed -r 's/\s+//g')" 367 spec="$(echo "$spec" | tr '\n' ' ' | sed -r 's/\s+//g')"
370 368
371 local code='' 369 local code=''
372 370
373 --add-var () { 371 --add-var () {
374 test -z "$code" || code="$code\n" 372 test -z "$code" || code="$code\n"
375 code="${code}local $1='$2'" 373 code="${code}local $1='$2'"
376 } 374 }
377 375
378 local positional_args="$(echo "$spec" | cut -d\; -f1)" 376 local positional_args="$(echo "$spec" | cut -d\; -f1)"
379 local positional_args_count="$(echo $positional_args | 377 local positional_args_count="$(echo $positional_args |
380 awk -F, '{print NF}')" 378 awk -F, '{print NF}')"
381 379
382 # Set spec values based on the positional arguments. 380 # Set spec values based on the positional arguments.
383 local i=1 381 local i=1
384 while ! [[ -z $1 || $1 == --* ]]; do 382 while ! [[ -z $1 || $1 == --* ]]; do
385 383
386 if (( $i > $positional_args_count )); then 384 if (( $i > $positional_args_count )); then
387 echo "Only $positional_args_count positional arguments allowed." >&2 385 echo "Only $positional_args_count positional arguments allowed." >&2
388 echo "Found at least one more: '$1'" >&2 386 echo "Found at least one more: '$1'" >&2
389 return 387 return
390 fi 388 fi
391 389
392 local name_spec="$(echo "$positional_args" | cut -d, -f$i)" 390 local name_spec="$(echo "$positional_args" | cut -d, -f$i)"
393 local name="${${name_spec%\?}%:}" 391 local name="${${name_spec%\?}%:}"
394 local value="$1" 392 local value="$1"
395 393
396 --add-var $name "$value" 394 --add-var $name "$value"
397 395
398 shift 396 shift
399 i=$(($i + 1)) 397 i=$(($i + 1))
400 done 398 done
401 399
402 local keyword_args="$( 400 local keyword_args="$(
403 echo "$positional_args" | tr , '\n' | sed -r 's/(\??)$/:\1/' 401 echo "$positional_args" | tr , '\n' | sed -r 's/(\??)$/:\1/'
404 echo "$spec" | cut -d\; -f2 | tr , '\n' 402 echo "$spec" | cut -d\; -f2 | tr , '\n'
405 )" 403 )"
406 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')" 404 local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')"
407 405
408 # Set spec values from keyword arguments, if any. The remaining arguments 406 # Set spec values from keyword arguments, if any. The remaining arguments
409 # are all assumed to be keyword arguments. 407 # are all assumed to be keyword arguments.
410 while [[ $1 == --* ]]; do 408 while [[ $1 == --* ]]; do
411 # Remove the `--` at the start. 409 # Remove the `--` at the start.
412 local arg="${1#--}" 410 local arg="${1#--}"
413 411
414 # Get the argument name and value. 412 # Get the argument name and value.
415 if [[ $arg != *=* ]]; then 413 if [[ $arg != *=* ]]; then
416 local name="$arg" 414 local name="$arg"
417 local value='' 415 local value=''
418 else 416 else
419 local name="${arg%\=*}" 417 local name="${arg%\=*}"
420 local value="${arg#*=}" 418 local value="${arg#*=}"
421 fi 419 fi
422 420
423 # The specification for this argument, used for validations. 421 # The specification for this argument, used for validations.
424 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")" 422 local arg_line="$(echo "$keyword_args" | grep -m1 "^$name:\??\?")"
425 423
426 # Validate argument and value. 424 # Validate argument and value.
427 if [[ -z $arg_line ]]; then 425 if [[ -z $arg_line ]]; then
428 # This argument is not known to us. 426 # This argument is not known to us.
429 echo "Unknown argument '$name'." >&2 427 echo "Unknown argument '$name'." >&2
430 return 428 return
431 429
432 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then 430 elif (echo "$arg_line" | grep -qm1 ':') && [[ -z $value ]]; then
433 # This argument needs a value, but is not provided. 431 # This argument needs a value, but is not provided.
434 echo "Required argument for '$name' not provided." >&2 432 echo "Required argument for '$name' not provided." >&2
435 return 433 return
436 434
437 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then 435 elif (echo "$arg_line" | grep -vqm1 ':') && [[ ! -z $value ]]; then
438 # This argument doesn't need a value, but is provided. 436 # This argument doesn't need a value, but is provided.
439 echo "No argument required for '$name', but provided '$value'." >&2 437 echo "No argument required for '$name', but provided '$value'." >&2
440 return 438 return
441 439
442 fi 440 fi
443 441
444 if [[ -z $value ]]; then 442 if [[ -z $value ]]; then
445 value=true 443 value=true
446 fi 444 fi
447 445
448 --add-var "${name//-/_}" "$value" 446 --add-var "${name//-/_}" "$value"
449 shift 447 shift
450 done 448 done
451 449
452 echo "$code" 450 echo "$code"
453 451
454 unfunction -- --add-var 452 unfunction -- --add-var
455 453
456 } 454 }
457 455
458 # Echo the bundle specs as in the record. The first line is not echoed since it 456 # Echo the bundle specs as in the record. The first line is not echoed since it
459 # is a blank line. 457 # is a blank line.
460 -antigen-echo-record () { 458 -antigen-echo-record () {
461 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p' 459 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
462 } 460 }
463 461
464 -antigen-env-setup () { 462 -antigen-env-setup () {
465 # Pre-startup initializations. 463 # Pre-startup initializations.
466 -set-default ANTIGEN_DEFAULT_REPO_URL \ 464 -set-default ANTIGEN_DEFAULT_REPO_URL \
467 https://github.com/robbyrussell/oh-my-zsh.git 465 https://github.com/robbyrussell/oh-my-zsh.git
468 -set-default ADOTDIR $HOME/.antigen 466 -set-default ADOTDIR $HOME/.antigen
469 467
470 # Load the compinit module. 468 # Load the compinit module.
471 autoload -U compinit 469 autoload -U compinit
472 470
473 # Without the following, `compdef` function is not defined. 471 # Without the following, `compdef` function is not defined.
474 compinit -i 472 compinit -i
475 } 473 }
476 474
477 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is 475 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is
478 # not already set. 476 # not already set.
479 -set-default () { 477 -set-default () {
480 local arg_name="$1" 478 local arg_name="$1"
481 local arg_value="$2" 479 local arg_value="$2"
482 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'" 480 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
483 } 481 }
484 482