Commit 3635aa19e8e624ad3336530184a49bef7b415b2d

Authored by Shrikant Sharat
1 parent b29510ce70

Refactoring to prefer arrays over string hacks.

The position_args variable is now an array, instead of a string with argument
names split by a space. This feels much cleaner.

Showing 1 changed file with 3 additions and 2 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> 5 # <repo-url>, <plugin-location>, <bundle-type>
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 btype=plugin 19 local btype=plugin
20 20
21 # Set spec values based on the positional arguments. 21 # Set spec values based on the positional arguments.
22 local position_args='url loc' 22 local position_args
23 position_args=(url loc)
23 local i=1 24 local i=1
24 while ! [[ -z $1 || $1 == --*=* ]]; do 25 while ! [[ -z $1 || $1 == --*=* ]]; do
25 local arg_name="$(echo "$position_args" | cut -d\ -f$i)" 26 local arg_name="${position_args[$i]}"
26 local arg_value="$1" 27 local arg_value="$1"
27 eval "local $arg_name='$arg_value'" 28 eval "local $arg_name='$arg_value'"
28 shift 29 shift
29 i=$(($i + 1)) 30 i=$(($i + 1))
30 done 31 done
31 32
32 # Set spec values from keyword arguments, if any. The remaining arguments 33 # Set spec values from keyword arguments, if any. The remaining arguments
33 # are all assumed to be keyword arguments. 34 # are all assumed to be keyword arguments.
34 while [[ $1 == --* ]]; do 35 while [[ $1 == --* ]]; do
35 local arg="${1#--}" 36 local arg="${1#--}"
36 37
37 if [[ $arg != *=* ]]; then 38 if [[ $arg != *=* ]]; then
38 arg="$arg=true" 39 arg="$arg=true"
39 fi 40 fi
40 41
41 local arg_name="${arg%\=*}" 42 local arg_name="${arg%\=*}"
42 local arg_value="${arg#*\=}" 43 local arg_value="${arg#*\=}"
43 44
44 eval "local $arg_name='$arg_value'" 45 eval "local $arg_name='$arg_value'"
45 shift 46 shift
46 done 47 done
47 48
48 # Check if url is just the plugin name. Super short syntax. 49 # Check if url is just the plugin name. Super short syntax.
49 if [[ "$url" != */* ]]; then 50 if [[ "$url" != */* ]]; then
50 loc="plugins/$url" 51 loc="plugins/$url"
51 url="$ANTIGEN_DEFAULT_REPO_URL" 52 url="$ANTIGEN_DEFAULT_REPO_URL"
52 fi 53 fi
53 54
54 # Resolve the url. 55 # Resolve the url.
55 url="$(-antigen-resolve-bundle-url "$url")" 56 url="$(-antigen-resolve-bundle-url "$url")"
56 57
57 # Add the branch information to the url. 58 # Add the branch information to the url.
58 if [[ ! -z $branch ]]; then 59 if [[ ! -z $branch ]]; then
59 url="$url|$branch" 60 url="$url|$branch"
60 fi 61 fi
61 62
62 # Add it to the record. 63 # Add it to the record.
63 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype" 64 _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype"
64 65
65 # Ensure a clone exists for this repo. 66 # Ensure a clone exists for this repo.
66 -antigen-ensure-repo "$url" 67 -antigen-ensure-repo "$url"
67 68
68 # Load the plugin. 69 # Load the plugin.
69 -antigen-load "$url" "$loc" "$btype" 70 -antigen-load "$url" "$loc" "$btype"
70 71
71 } 72 }
72 73
73 -antigen-resolve-bundle-url () { 74 -antigen-resolve-bundle-url () {
74 # Given an acceptable short/full form of a bundle's repo url, this function 75 # Given an acceptable short/full form of a bundle's repo url, this function
75 # echoes the full form of the repo's clone url. 76 # echoes the full form of the repo's clone url.
76 77
77 local url="$1" 78 local url="$1"
78 79
79 # Expand short github url syntax: `username/reponame` 80 # Expand short github url syntax: `username/reponame`
80 if [[ $url != git://* && \ 81 if [[ $url != git://* && \
81 $url != https://* && \ 82 $url != https://* && \
82 $url != /* && \ 83 $url != /* && \
83 $url != git@github.com:*/* 84 $url != git@github.com:*/*
84 ]]; then 85 ]]; then
85 url="https://github.com/${url%.git}.git" 86 url="https://github.com/${url%.git}.git"
86 fi 87 fi
87 88
88 echo "$url" 89 echo "$url"
89 } 90 }
90 91
91 antigen-bundles () { 92 antigen-bundles () {
92 # Bulk add many bundles at one go. Empty lines and lines starting with a `#` 93 # Bulk add many bundles at one go. Empty lines and lines starting with a `#`
93 # are ignored. Everything else is given to `antigen-bundle` as is, no 94 # are ignored. Everything else is given to `antigen-bundle` as is, no
94 # quoting rules applied. 95 # quoting rules applied.
95 96
96 local line 97 local line
97 98
98 grep -v '^\s*$\|^#' | while read line; do 99 grep -v '^\s*$\|^#' | while read line; do
99 # Using `eval` so that we can use the shell-style quoting in each line 100 # Using `eval` so that we can use the shell-style quoting in each line
100 # piped to `antigen-bundles`. 101 # piped to `antigen-bundles`.
101 eval "antigen-bundle $line" 102 eval "antigen-bundle $line"
102 done 103 done
103 } 104 }
104 105
105 antigen-update () { 106 antigen-update () {
106 # Update your bundles, i.e., `git pull` in all the plugin repos. 107 # Update your bundles, i.e., `git pull` in all the plugin repos.
107 -antigen-echo-record \ 108 -antigen-echo-record \
108 | awk '{print $1}' \ 109 | awk '{print $1}' \
109 | sort -u \ 110 | sort -u \
110 | while read url; do 111 | while read url; do
111 echo "**** Pulling $url" 112 echo "**** Pulling $url"
112 -antigen-ensure-repo --update --verbose "$url" 113 -antigen-ensure-repo --update --verbose "$url"
113 echo 114 echo
114 done 115 done
115 } 116 }
116 117
117 -antigen-get-clone-dir () { 118 -antigen-get-clone-dir () {
118 # Takes a repo url and gives out the path that this url needs to be cloned 119 # Takes a repo url and gives out the path that this url needs to be cloned
119 # to. Doesn't actually clone anything. 120 # to. Doesn't actually clone anything.
120 # TODO: Memoize? 121 # TODO: Memoize?
121 122
122 # The url given. 123 # The url given.
123 local url="$1" 124 local url="$1"
124 125
125 # Echo the full path to the clone directory. 126 # Echo the full path to the clone directory.
126 echo -n $ADOTDIR/repos/ 127 echo -n $ADOTDIR/repos/
127 echo "$url" | sed \ 128 echo "$url" | sed \
128 -e 's./.-SLASH-.g' \ 129 -e 's./.-SLASH-.g' \
129 -e 's.:.-COLON-.g' \ 130 -e 's.:.-COLON-.g' \
130 -e 's.|.-PIPE-.g' 131 -e 's.|.-PIPE-.g'
131 } 132 }
132 133
133 -antigen-get-clone-url () { 134 -antigen-get-clone-url () {
134 # Takes a repo's clone dir and gives out the repo's original url that was 135 # Takes a repo's clone dir and gives out the repo's original url that was
135 # used to create the given directory path. 136 # used to create the given directory path.
136 # TODO: Memoize? 137 # TODO: Memoize?
137 echo "$1" | sed \ 138 echo "$1" | sed \
138 -e "s:^$ADOTDIR/repos/::" \ 139 -e "s:^$ADOTDIR/repos/::" \
139 -e 's.-SLASH-./.g' \ 140 -e 's.-SLASH-./.g' \
140 -e 's.-COLON-.:.g' \ 141 -e 's.-COLON-.:.g' \
141 -e 's.-PIPE-.|.g' 142 -e 's.-PIPE-.|.g'
142 } 143 }
143 144
144 -antigen-ensure-repo () { 145 -antigen-ensure-repo () {
145 146
146 # Ensure that a clone exists for the given repo url and branch. If the first 147 # Ensure that a clone exists for the given repo url and branch. If the first
147 # argument is `--update` and if a clone already exists for the given repo 148 # argument is `--update` and if a clone already exists for the given repo
148 # and branch, it is pull-ed, i.e., updated. 149 # and branch, it is pull-ed, i.e., updated.
149 150
150 # Argument defaults. 151 # Argument defaults.
151 # Check if we have to update. 152 # Check if we have to update.
152 local update=false 153 local update=false
153 # Verbose output. 154 # Verbose output.
154 local verbose=false 155 local verbose=false
155 156
156 # Load any boolean arguments specified. 157 # Load any boolean arguments specified.
157 while [[ $1 == --* ]]; do 158 while [[ $1 == --* ]]; do
158 eval "local '${1#--}=true'" 159 eval "local '${1#--}=true'"
159 shift 160 shift
160 done 161 done
161 162
162 # Get the clone's directory as per the given repo url and branch. 163 # Get the clone's directory as per the given repo url and branch.
163 local url="$1" 164 local url="$1"
164 local clone_dir="$(-antigen-get-clone-dir $url)" 165 local clone_dir="$(-antigen-get-clone-dir $url)"
165 166
166 # Clone if it doesn't already exist. 167 # Clone if it doesn't already exist.
167 if [[ ! -d $clone_dir ]]; then 168 if [[ ! -d $clone_dir ]]; then
168 git clone "${url%|*}" "$clone_dir" 169 git clone "${url%|*}" "$clone_dir"
169 elif $update; then 170 elif $update; then
170 # Save current revision. 171 # Save current revision.
171 old_rev="$(git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \ 172 old_rev="$(git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \
172 rev-parse HEAD)" 173 rev-parse HEAD)"
173 # Pull changes if update requested. 174 # Pull changes if update requested.
174 git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \ 175 git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \
175 pull 176 pull
176 # Get the new revision. 177 # Get the new revision.
177 new_rev="$(git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \ 178 new_rev="$(git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \
178 rev-parse HEAD)" 179 rev-parse HEAD)"
179 fi 180 fi
180 181
181 # If its a specific branch that we want, checkout that branch. 182 # If its a specific branch that we want, checkout that branch.
182 if [[ $url == *\|* ]]; then 183 if [[ $url == *\|* ]]; then
183 git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \ 184 git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \
184 checkout "${url#*|}" 185 checkout "${url#*|}"
185 fi 186 fi
186 187
187 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then 188 if ! [[ -z $old_rev || $old_rev == $new_rev ]]; then
188 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}. 189 echo Updated from ${old_rev:0:7} to ${new_rev:0:7}.
189 if $verbose; then 190 if $verbose; then
190 git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \ 191 git --git-dir "$clone_dir/.git" --work-tree "$clone_dir" \
191 log --oneline --reverse --no-merges --stat '@{1}..' 192 log --oneline --reverse --no-merges --stat '@{1}..'
192 fi 193 fi
193 fi 194 fi
194 195
195 } 196 }
196 197
197 -antigen-load () { 198 -antigen-load () {
198 199
199 local url="$1" 200 local url="$1"
200 local loc="$2" 201 local loc="$2"
201 local btype="$3" 202 local btype="$3"
202 203
203 # The full location where the plugin is located. 204 # The full location where the plugin is located.
204 local location="$(-antigen-get-clone-dir "$url")/$loc" 205 local location="$(-antigen-get-clone-dir "$url")/$loc"
205 206
206 if [[ $btype == theme ]]; then 207 if [[ $btype == theme ]]; then
207 208
208 # Of course, if its a theme, the location would point to the script 209 # Of course, if its a theme, the location would point to the script
209 # file. 210 # file.
210 source "$location" 211 source "$location"
211 212
212 else 213 else
213 214
214 # Source the plugin script 215 # Source the plugin script
215 # FIXME: I don't know. Looks very very ugly. Needs a better 216 # FIXME: I don't know. Looks very very ugly. Needs a better
216 # implementation once tests are ready. 217 # implementation once tests are ready.
217 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')" 218 local script_loc="$(ls "$location" | grep -m1 '\.plugin\.zsh$')"
218 219
219 if [[ -f $script_loc ]]; then 220 if [[ -f $script_loc ]]; then
220 # If we have a `*.plugin.zsh`, source it. 221 # If we have a `*.plugin.zsh`, source it.
221 source "$script_loc" 222 source "$script_loc"
222 223
223 elif [[ ! -z "$(ls "$location" | grep -m1 '\.zsh$')" ]]; then 224 elif [[ ! -z "$(ls "$location" | grep -m1 '\.zsh$')" ]]; then
224 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh` 225 # If there is no `*.plugin.zsh` file, source *all* the `*.zsh`
225 # files. 226 # files.
226 for script ($location/*.zsh(N)) source "$script" 227 for script ($location/*.zsh(N)) source "$script"
227 228
228 elif [[ ! -z "$(ls "$location" | grep -m1 '\.sh$')" ]]; then 229 elif [[ ! -z "$(ls "$location" | grep -m1 '\.sh$')" ]]; then
229 # If there are no `*.zsh` files either, we look for and source any 230 # If there are no `*.zsh` files either, we look for and source any
230 # `*.sh` files instead. 231 # `*.sh` files instead.
231 for script ($location/*.sh(N)) source "$script" 232 for script ($location/*.sh(N)) source "$script"
232 233
233 fi 234 fi
234 235
235 # Add to $fpath, for completion(s). 236 # Add to $fpath, for completion(s).
236 fpath=($location $fpath) 237 fpath=($location $fpath)
237 238
238 fi 239 fi
239 240
240 } 241 }
241 242
242 antigen-cleanup () { 243 antigen-cleanup () {
243 244
244 # Cleanup unused repositories. 245 # Cleanup unused repositories.
245 246
246 local force=false 247 local force=false
247 if [[ $1 == --force ]]; then 248 if [[ $1 == --force ]]; then
248 force=true 249 force=true
249 fi 250 fi
250 251
251 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then 252 if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then
252 echo "You don't have any bundles." 253 echo "You don't have any bundles."
253 return 0 254 return 0
254 fi 255 fi
255 256
256 # Find directores in ADOTDIR/repos, that are not in the bundles record. 257 # Find directores in ADOTDIR/repos, that are not in the bundles record.
257 local unused_clones="$(comm -13 \ 258 local unused_clones="$(comm -13 \
258 <(-antigen-echo-record \ 259 <(-antigen-echo-record \
259 | awk '{print $1}' \ 260 | awk '{print $1}' \
260 | while read line; do 261 | while read line; do
261 -antigen-get-clone-dir "$line" 262 -antigen-get-clone-dir "$line"
262 done \ 263 done \
263 | sort -u) \ 264 | sort -u) \
264 <(ls -d "$ADOTDIR/repos/"* | sort -u))" 265 <(ls -d "$ADOTDIR/repos/"* | sort -u))"
265 266
266 if [[ -z $unused_clones ]]; then 267 if [[ -z $unused_clones ]]; then
267 echo "You don't have any unidentified bundles." 268 echo "You don't have any unidentified bundles."
268 return 0 269 return 0
269 fi 270 fi
270 271
271 echo 'You have clones for the following repos, but are not used.' 272 echo 'You have clones for the following repos, but are not used.'
272 echo "$unused_clones" \ 273 echo "$unused_clones" \
273 | while read line; do 274 | while read line; do
274 -antigen-get-clone-url "$line" 275 -antigen-get-clone-url "$line"
275 done \ 276 done \
276 | sed -e 's/^/ /' -e 's/|/, branch /' 277 | sed -e 's/^/ /' -e 's/|/, branch /'
277 278
278 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then 279 if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then
279 echo 280 echo
280 echo 281 echo
281 echo "$unused_clones" | while read line; do 282 echo "$unused_clones" | while read line; do
282 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..." 283 echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..."
283 rm -rf "$line" 284 rm -rf "$line"
284 echo ' done.' 285 echo ' done.'
285 done 286 done
286 else 287 else
287 echo 288 echo
288 echo Nothing deleted. 289 echo Nothing deleted.
289 fi 290 fi
290 } 291 }
291 292
292 antigen-lib () { 293 antigen-lib () {
293 antigen-bundle --loc=lib 294 antigen-bundle --loc=lib
294 } 295 }
295 296
296 antigen-theme () { 297 antigen-theme () {
297 local name="${1:-robbyrussell}" 298 local name="${1:-robbyrussell}"
298 antigen-bundle --loc=themes/$name.zsh-theme --btype=theme 299 antigen-bundle --loc=themes/$name.zsh-theme --btype=theme
299 } 300 }
300 301
301 antigen-apply () { 302 antigen-apply () {
302 # Initialize completion. 303 # Initialize completion.
303 # TODO: Only load completions if there are any changes to the bundle 304 # TODO: Only load completions if there are any changes to the bundle
304 # repositories. 305 # repositories.
305 compinit -i 306 compinit -i
306 } 307 }
307 308
308 antigen-list () { 309 antigen-list () {
309 # List all currently installed bundles 310 # List all currently installed bundles
310 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then 311 if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
311 echo "You don't have any bundles." >&2 312 echo "You don't have any bundles." >&2
312 return 1 313 return 1
313 else 314 else
314 -antigen-echo-record | sort -u 315 -antigen-echo-record | sort -u
315 fi 316 fi
316 } 317 }
317 318
318 antigen-help () { 319 antigen-help () {
319 cat <<EOF 320 cat <<EOF
320 Antigen is a plugin management system for zsh. It makes it easy to grab awesome 321 Antigen is a plugin management system for zsh. It makes it easy to grab awesome
321 shell scripts and utilities, put up on github. For further details and complete 322 shell scripts and utilities, put up on github. For further details and complete
322 documentation, visit the project's page at 'http://antigen.sharats.me'. 323 documentation, visit the project's page at 'http://antigen.sharats.me'.
323 EOF 324 EOF
324 } 325 }
325 326
326 # A syntax sugar to avoid the `-` when calling antigen commands. With this 327 # A syntax sugar to avoid the `-` when calling antigen commands. With this
327 # function, you can write `antigen-bundle` as `antigen bundle` and so on. 328 # function, you can write `antigen-bundle` as `antigen bundle` and so on.
328 antigen () { 329 antigen () {
329 local cmd="$1" 330 local cmd="$1"
330 shift 331 shift
331 "antigen-$cmd" "$@" 332 "antigen-$cmd" "$@"
332 } 333 }
333 334
334 # Echo the bundle specs as in the record. The first line is not echoed since it 335 # Echo the bundle specs as in the record. The first line is not echoed since it
335 # is a blank line. 336 # is a blank line.
336 -antigen-echo-record () { 337 -antigen-echo-record () {
337 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p' 338 echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
338 } 339 }
339 340
340 -antigen-env-setup () { 341 -antigen-env-setup () {
341 # Pre-startup initializations 342 # Pre-startup initializations
342 -set-default ANTIGEN_DEFAULT_REPO_URL \ 343 -set-default ANTIGEN_DEFAULT_REPO_URL \
343 https://github.com/robbyrussell/oh-my-zsh.git 344 https://github.com/robbyrussell/oh-my-zsh.git
344 -set-default ADOTDIR $HOME/.antigen 345 -set-default ADOTDIR $HOME/.antigen
345 346
346 # Load the compinit module 347 # Load the compinit module
347 autoload -U compinit 348 autoload -U compinit
348 349
349 # Without the following, `compdef` function is not defined. 350 # Without the following, `compdef` function is not defined.
350 compinit -i 351 compinit -i
351 } 352 }
352 353
353 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is 354 # Same as `export $1=$2`, but will only happen if the name specified by `$1` is
354 # not already set. 355 # not already set.
355 -set-default () { 356 -set-default () {
356 local arg_name="$1" 357 local arg_name="$1"
357 local arg_value="$2" 358 local arg_value="$2"
358 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'" 359 eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
359 } 360 }
360 361
361 -antigen-env-setup 362 -antigen-env-setup
362 363