diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..88c9438
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+# Running tests creates this completion dump file.
+tests/.zcompdump
+
+# Test failure reports
+tests/*.t.err
+
+# If the $ADOTDIR is the same as the antigen's clone directory itself, the
+# following would be shown as untracked.
+repos/
+revert-info
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..e1032a6
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,35 @@
+# Using python for running the tests, using the `cram` test framework.
+language: python
+
+# Python version to run tests with.
+python:
+ - "2.7"
+
+env:
+ # Default zsh
+ - PPA="none"
+ # zsh 5 PPA
+ - PPA="ppa:brainpower/testing"
+
+before_script:
+
+ # Show the git version being used to test.
+ - "git --version"
+
+ # Show the zsh version being used to test.
+ - "zsh --version"
+
+ # Test config for git.
+ - "git config --global user.name test"
+ - "git config --global user.email test@test.test"
+
+install:
+ # Add PPA if needed
+ - "./travis-ppa.sh"
+ # Install python requirements.
+ - "pip install -r requirements.txt --use-mirrors"
+ # Install zsh.
+ - "sudo apt-get install zsh"
+
+# Run the tests.
+script: "make tests PYENV="
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..342d213
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+.PHONY: itests tests
+
+PYENV ?= . .pyenv/bin/activate &&
+TESTS ?= tests
+
+itests:
+ ${MAKE} tests CRAM_OPTS=-i
+
+tests:
+ ${PYENV} ZDOTDIR="${PWD}/tests" cram ${CRAM_OPTS} --shell=zsh ${TESTS}
diff --git a/README.mkd b/README.mkd
new file mode 100644
index 0000000..b9d1ac6
--- /dev/null
+++ b/README.mkd
@@ -0,0 +1,616 @@
+# Antigen v1
+
+[](http://travis-ci.org/zsh-users/antigen)
+
+Antigen is a small set of functions that help you easily manage your shell (zsh)
+plugins, called bundles. The concept is pretty much the same as bundles in a
+typical vim+pathogen setup. Antigen is to zsh, what [Vundle][] is to vim.
+
+> [Donate to Antigen](https://gum.co/antigen)
+
+Antigen has reached a certain level of stability and has been used in the wild
+for around a couple of years. If you face any problems, please open an issue.
+
+Note: Please read the commit comments of the changesets when you pull a new
+version of antigen.
+
+## Show off
+
+> Enough talk. Let's fight!
+> -- Po, Kung-fu Panda.
+
+You're going to experience antigen right in your open shell. No `.zshrc`
+tweaking and reading the rest of this documentation. Kinda like an ice-cream
+sample, if you will.
+
+Get and load antigen.
+
+ curl -L https://raw.githubusercontent.com/zsh-users/antigen/master/antigen.zsh > antigen.zsh
+ source antigen.zsh
+
+There. You now have all the antigen goodies. Let's try install some plugins. How
+about some color to start with. Get the [syntax highlighting plugin][] by
+running
+
+ antigen bundle zsh-users/zsh-syntax-highlighting
+
+Now let it do its thing and once you're back at your prompt, try and type a
+command. See that? Colors!
+
+So, you do git? ruby? git and ruby? There are lots of awesome plugins over at
+oh-my-zsh. Treat yourself to some.
+
+ antigen bundle robbyrussell/oh-my-zsh plugins/ruby
+ # Or for the lazy,
+ antigen bundle git
+
+There are lots of plugins out there in the wild and people are writing zsh
+utilities as small scripts all the time. Antigen is compatible with all of them.
+The plugins and scripts don't need any special handling to be compatible with
+antigen.
+
+Another example, [kennethreitz's autoenv][autoenv] (or [my fork][f-autoenv] of
+it). Just a bundle command away.
+
+ antigen bundle sharat87/autoenv
+
+And boom! you have all the autoenv goodness. Just remember how you used to do
+these before antigen, clone it, modify your zshrc to source it, load a new
+terminal, all just to test it out. Duh!
+
+A subtle aspect of this is that you can tell antigen to grab just about anything
+from anyone's `dotfiles` repo, as long as it is in a directory under any repo on
+github.
+
+And themes? How would you like a fancy new prompt for yourself?
+
+ antigen theme funky
+
+No? Not your taste? There are many themes available to you, check out the
+oh-my-zsh's [page on themes][].
+
+You can install themes from unofficial repos too!
+
+ antigen theme XsErG/zsh-themes themes/lazyuser
+
+See? It's easy! To see how that works, refer to [the section on the
+`antigen theme` command further down](#antigen-theme).
+
+Note: Many of those plugins and especially themes, assume you have the core
+library of oh-my-zsh loaded. So, if you want to experiment further, issue a
+
+ antigen use oh-my-zsh
+
+and continue until you're tired. At which point you can come back to this page
+;)
+
+## Usage
+
+So, now that you're here, I suppose you are convinced and want antigen running
+your shell all the time. Sweet. Let's do it.
+
+First, clone this repo, probably as a submodule if you have your dotfiles in a
+git repo,
+
+ git clone https://github.com/zsh-users/antigen.git
+
+The usage should be very familiar to you if you use Vundle. A typical `.zshrc`
+might look like this
+
+ source /path-to-antigen-clone/antigen.zsh
+
+ # Load the oh-my-zsh's library.
+ antigen use oh-my-zsh
+
+ # Bundles from the default repo (robbyrussell's oh-my-zsh).
+ antigen bundle git
+ antigen bundle heroku
+ antigen bundle pip
+ antigen bundle lein
+ antigen bundle command-not-found
+
+ # Syntax highlighting bundle.
+ antigen bundle zsh-users/zsh-syntax-highlighting
+
+ # Load the theme.
+ antigen theme robbyrussell
+
+ # Tell antigen that you're done.
+ antigen apply
+
+Open your zsh with this zshrc and you should see all the bundles you defined
+here, getting installed. Once its done, you are ready to roll. The complete
+syntax for the `antigen bundle` command is discussed further down on this page.
+
+You can find more examples in the wiki: [Antigen in the wild][wild].
+
+## Motivation
+
+If you use zsh and [oh-my-zsh][], you know that having many different plugins
+that are developed by many different authors in a single (sub)repo is not very
+easy to maintain. There are some really fantastic plugins and utilities in
+oh-my-zsh, but having them all in a single repo doesn't really scale well. And I
+admire robbyrussell's efforts for reviewing and merging the gigantic number of
+pull requests the project gets. We need a better way of plugin management.
+
+This was discussed on [a][1] [few][2] [issues][3], but it doesn't look like
+there was any progress made. So, I'm trying to start this off with antigen,
+hoping to better this situation. Please note that I'm by no means a zsh or any
+shell script expert (far from it).
+
+[1]: https://github.com/robbyrussell/oh-my-zsh/issues/465
+[2]: https://github.com/robbyrussell/oh-my-zsh/issues/377
+[3]: https://github.com/robbyrussell/oh-my-zsh/issues/1014
+
+Inspired by vundle, antigen can pull oh-my-zsh style plugins from various github
+repositories. You are not limited to use plugins from the oh-my-zsh repository
+only and you don't need to maintain your own fork and pull from upstream every
+now and then. I actually encourage you to grab plugins and scripts from various
+sources, straight from the authors, before they even submit it to oh-my-zsh as a
+pull request.
+
+Antigen also lets you switch the prompt theme with one command, just like that
+
+ antigen theme candy
+
+and your prompt is changed, just for this session of course (unless you put this
+line in your `.zshrc`).
+
+## Commands
+
+### antigen bundle
+
+This command tells antigen to install (if not already installed) and load the
+given plugin. The simplest usage follows the following syntax.
+
+ antigen bundle
+
+This will install and load the `plugins/` directory from [robbyrussell's
+oh-my-zsh][oh-my-zsh] (can be changed by setting `ANTIGEN_DEFAULT_REPO_URL`).
+
+However, the above is just syntax sugar for the extended syntax of the
+`antigen bundle` command.
+
+ antigen bundle [ []]
+
+where `` is the repository url and it defaults to [robbyrussell's
+oh-my-zsh][oh-my-zsh] repo (can be changed by setting `ANTIGEN_DEFAULT_REPO_URL`
+discussed further down). `` is the path under this repository which has the
+zsh plugin. This is typically the directory that contains a `*.plugin.zsh` file,
+but it could contain a completion file or just many `*.zsh` files to be sourced,
+or it could simply be a file (with any extension) that you want to source.
+`` defaults to `/`, which indicates the repository itself is a plugin.
+
+An example invocation would be
+
+ # The following is the same as `antigen bundle ant`. But for demonstration
+ # purposes, we use the extended syntax here.
+ antigen bundle https://github.com/robbyrussell/oh-my-zsh.git plugins/ant
+
+This would install the ant plugin from robbyrussell's oh-my-zsh repo. Of course,
+github url's can be shortened.
+
+ antigen bundle robbyrussell/oh-my-zsh plugins/ant
+
+And since this repo is the default, even that isn't necessary. But we can't
+specify the `loc` without giving the first argument.
+
+For this and a few other reasons, `antigen bundle` also supports a simple
+keyword argument syntax, using which we can rewrite the above as
+
+ antigen bundle --loc=plugins/ant
+
+Which picks up the default for the `url` argument, and uses the `loc` given to
+it.
+
+*Note* that you can mix and match positional and keyword arguments. But you
+can't have positional arguments after keyword arguments.
+
+ antigen bundle robbyrussell/oh-my-zsh --loc=plugins/ant
+
+And keyword arguments don't care about the order in which the arguments are
+specified. The following is perfectly valid.
+
+ antigen bundle --loc=plugins/ant --url=robbyrussell/oh-my-zsh
+
+You can also specify a local directory on your file system as a bundle. In this
+case, make sure the path you give is the absolute path (i.e., starts with a
+`/`). Relative paths are not supported. If the repo you gave is a local
+directory path, then it is not necessary that this path is a git repo. Please
+refer to the notes on `--no-local-clone` below.
+
+This command can also be used from your shell environment. This allows you to
+install plugins on the fly and try them out. Of course if you want a bundle to
+be available every time you open a shell, put it in your `.zshrc`.
+
+Other keyword-only arguments accepted:
+
+`--branch={git-branch-name}` — Specify the branch of the git repo to be
+used for this bundle (without the braces of course). The default is whatever
+branch the clone comes with, which is usually `master`. For example,
+
+ antigen bundle github-user/repo --branch=develop
+
+This will get the plugin as in the branch `develop`.
+
+Note that if you specify two plugins to be loaded from the same git repo, but
+different branches, then two separate clones of this repo will be maintained.
+This is a small implementation detail and shouldn't influence you in any way.
+
+`--no-local-clone` — This command can be useful if you are developing a
+plugin and already have a clone on your local file system. If this argument is
+not given, even if the given repo url is a local path, a clone is made in the
+`$ADOTDIR/repos`, and the plugin is loaded from that clone. But, if you give
+this argument, the plugin is sourced straight from the repo location, without
+creating a clone. For example,
+
+ antigen bundle /absolute/path/to/the/plugin --no-local-clone
+
+Note that if the repo url is *not* an absolute local path or a branch has been
+specified with the `--branch` option, this argument has no effect. That is,
+for this option to have any affect, the repo url must be an absolute local path
+and no `--branch` should be specified.
+
+Also, if the local path given as the url is not a git repo, then this
+argument is forced as it doesn't makes sense to *clone* something that's not a
+git repo. This property can be used to load any utility scripts you have in your
+dotfiles repo. For example,
+
+ antigen bundle $HOME/dotfiles/oh-my-zsh/custom
+
+In addition to the above discussed arguments, `antigen bundle` also takes a
+`btype` keyword-only argument, that is used internally. You shouldn't be
+concerned with this argument, its only used internally and will probably go away
+in the future. It indicates whether the bundle is a theme or a simple plugin.
+
+### antigen bundles
+
+If you have a fair number of bundles, using the `antigen bundle` command can
+look cumbersome. You can use the `antigen bundles` command to *bulk* define
+bundles instead of individual calls to `antigen bundle`.
+
+Usage is pretty straightforward. Just pipe the bundle specifications, just as
+you would give to the `antigen bundle` command, one per line, into the
+`antigen bundles` command. The easiest way to do this, is using the heredoc
+syntax.
+
+ antigen bundles <α
+
+Reverts the state of all your plugins to how they were before the last
+`antigen update`. This command is currently experimental, so don't rely too much
+on it. There is a test for it, and it passes, so it should work fine though.
+
+Takes no options.
+
+Insider detail: The information for reverting is stored in
+`$ADOTDIR/revert-info` file. If its not present, reverting is not possible.
+
+### antigen list
+
+Use this command to list out the currently *loaded* plugins. Keep in mind that
+this includes any bundles installed on-the-fly.
+
+Takes no arguments. Gives out four entries per line of output, denoting the
+following fields of each bundle.
+
+
+
+The `btype` field is an internal detail, that specifies if the bundle is a
+`plugin` or a `theme`.
+
+The final field is `true` or `false` reflecting whether there is a local clone
+for this bundle.
+
+### antigen cleanup
+
+Used to clean up the clones of repos which are not used by any plugins currently
+loaded. It takes no arguments. When run, it lists out the repo-clones that are
+available but are not used by any plugin *currently loaded*.
+
+This command, by default asks for confirmation before deleting the unused
+clones. If the `--force` argument is given, then this confirmation is not asked.
+It straight away deletes all the unused clones. This option makes this command
+usable in a non-interactive fashion.
+
+### antigen use
+
+This command lets you load any (supported) zsh pre-packaged framework, like
+oh-my-zsh. Usage is
+
+ antigen use oh-my-zsh
+
+Additional arguments may be present depending on the framework you are
+`use`-ing. Here are the supported frameworks.
+
+#### oh-my-zsh
+
+This is (almost) the same as
+
+ antigen bundle --loc=lib
+
+So, it basically installs the oh-my-zsh's library as a bundle.
+
+One other thing it does is that some oh-my-zsh plugins expect a `$ZSH` set to
+the full path of the oh-my-zsh clone being used. This is also set to the
+correct path, if not already set to something else.
+
+Please note that this assumes that the `ANTIGEN_DEFAULT_REPO_URL` is set to the
+oh-my-zsh repo or a fork of that repo. If you want to specify the `url` too,
+then you can't use the `antigen use oh-my-zsh` short cut. You have to do that
+directly with the `antigen bundle` command.
+
+Use
+
+ antigen use oh-my-zsh
+
+in your `.zshrc`, before any `antigen bundle` declarations. It takes no further
+arguments.
+
+#### prezto
+
+This is (almost, but not quite) the same as doing,
+
+ antigen bundle sorin-ionescu/prezto
+
+That is, initializes the canonical repo of the prezto framework. Please note
+that prezto support is very new and experimental in antigen. If you find any
+bugs, please report over on github issues.
+
+Takes no further arguments.
+
+### antigen theme
+
+Used for switching the prompt theme. Invoke it with the name of the theme you
+want to use.
+
+ antigen theme fox
+
+This will get the theme file located at `themes/fox.zsh-theme` in the repo
+specified by `ANTIGEN_DEFAULT_REPO_URL`.
+
+To pull themes from other repositories, use `antigen theme` just like
+`antigen bundle`. Exactly the same, just make sure the `url` and `loc`
+combination point to a theme file, having a `.zsh-theme` extension.
+
+For example,
+
+ antigen theme robbyrussell/oh-my-zsh themes/apple
+
+Will pull the apple theme from the canonical oh-my-zsh repo. Also, note that the
+`.zsh-theme` extension is not present. It can be given, its optional.
+
+To get themes from arbitrary git repos (such as gists) use,
+
+ antigen theme https://gist.github.com/3750104.git agnoster
+
+in which case there is a file called `agnoster.zsh-theme` present in the gist at
+https://gist.github.com/3750104.
+
+You can use this command to change your theme on the fly in your shell. Go on,
+try out a few themes in your shell before you set it in your `.zshrc`.
+
+**Note**: Some themes use functions that are loaded by `antigen use oh-my-zsh`.
+So, to avoid any trouble, run `antigen use oh-my-zsh` if you haven't already
+before experimenting with themes. If you have `antigen use oh-my-zsh` in your
+`.zshrc`, you're covered.
+
+**Note**: Do *not* provide the `--btype` argument to `antigen theme`. Its an
+internal argument.
+
+*For the interested, you can read more details on the purpose & workings of the
+`theme` command on the comments of issue #78.*
+
+### antigen apply
+
+You have to add this command after defining all bundles you need, in your zshrc.
+The completions defined by your bundles will be loaded at this step.
+
+It is possible to load completions as and when a bundle is specified with the
+bundle command, in which case this command would not be necessary. But loading
+the completions is a time-consuming process, so if the completions were loaded
+at every call to `antigen bundle`, your shell will start noticeably slow when
+you have a good number of bundle specifications.
+
+However, if you can suggest a way so that this would not be necessary, I am very
+interested in discussing it. Please open up an issue with your details. Thanks.
+
+### antigen snapshot α
+
+Creates a snapshot of all the clones you currently have *active* including the
+git version hash they are at and save it to a snapshot file. *Active* means, the
+clones for those listed by `antigen cleanup` are not included in the snapshot.
+
+Takes one optional argument, the file name in which the snapshot is to be saved.
+Defaults to `antigen snapshot`.
+
+**Note**: The snapshot currently *only* contains the details of those bundles
+that have a clone. That is, bundles that have `--no-local-clone` set or are
+directly sourced from your file system (without a git repo), are not recorded
+in the snapshot file.
+
+### antigen restore α
+
+Restore the bundles state as specified in the snapshot. Takes one required
+argument, the snapshot file name to read.
+
+Although it restores the clones of the repos specified in the snapshot file, any
+other clones present in your environment are not touched. This behavior may
+change in the future.
+
+### antigen selfupdate
+
+Use this command to update your copy of antigen. It basically does a `git pull`
+on your antigen's clone, *if* it is a git clone. Otherwise, it doesn't do
+anything.
+
+Takes no options.
+
+### antigen help
+
+This exists so that there can be some help right in the command line. Currently
+it doesn't provide much help other than redirecting you to the project page for
+documentation. It is intended to provide more meaning and sub-command specific
+help in the future.
+
+I could use some help here as I'm not that good at writing documentation that
+looks good as output on the command line.
+
+## Configuration
+
+The following environment variables can be set to customize the behavior of
+antigen. Make sure you set them *before* source-ing `antigen.zsh`.
+
+`ANTIGEN_DEFAULT_REPO_URL` — This is the default repository url that is
+used for `bundle` commands. The default value is robbyrussell's oh-my-zsh repo,
+but you can set this to the fork url of your own fork.
+
+`ADOTDIR` — This directory is used to store all the repo clones, your
+bundles, themes, caches and everything else antigen requires to run smoothly.
+Defaults to `$HOME/.antigen`.
+
+**Note**: `ANTIGEN_REPO_CACHE` & `ANTIGEN_BUNDLE_DIR` — These variables
+were used previously but are now removed. Please use `ADOTDIR` instead, as
+mentioned above.
+
+## Running the tests
+
+All the tests are in the `tests` folder and are run using the [cram][] test
+system. The latest version on that website, as of today is v0.5, which does not
+have the `--shell` argument which is required to run our tests. So, to get the
+correct version of cram, run
+
+ pip install -r requirements.txt
+
+With that, once you have cram installed, you can run the tests as
+
+ make
+
+If you are making a feature addition, I'd really appreciate if you can add a
+test for your feature. Even if you can add a test for an existing feature, that
+would be great as the tests are currently seriously lagging behind the full
+functionality of antigen.
+
+## Notes on writing plugins
+
+Most shell utilities/plugins are made up of just one file. For a plugin called
+`awesomeness`, create a `awesomeness.plugin.zsh` and code away.
+
+That said, even if you write a single file as a `.sh` file with the goodness you
+want to create, antigen will work just fine with it. The `*.plugin.zsh` way is
+recommended by antigen, because it is widely used because of the [oh-my-zsh][]
+project.
+
+If you want to know how antigen loads the plugins, do continue.
+
+Firstly, antigen looks for a `*.plugin.zsh` file in the plugin directory. If
+present, it will source *only* this script. Nothing else is sourced. This is for
+oh-my-zsh style plugins.
+
+Secondly, it looks for a `init.zsh` file in the plugin directory. If present, it
+will source *only* this script. Nothing else is sourced. This is for prezto
+style modules.
+
+Otherwise, it looks for `*.zsh` files and if there are any, *all* of them are
+sourced. The order in which they are sourced is not currently defined. Please
+don't rely on this order. Nothing else is sourced after all the `*.zsh` scripts.
+
+If no `*.zsh` files are present, it finally looks for any `*.sh` files and
+sources *all* of them. Again, the order in which they are sourced in not
+currently defined.
+
+No matter which (or none) of the above happen to be sourced, this plugin
+directory is added to the zsh's function path (`$fpath`) so that any completions
+in it are loaded.
+
+One exception to this rule is that if this plugin is a theme. In which case the
+theme script is just sourced and nothing else is done. Not even adding to
+`$fpath`.
+
+## A note on external zsh plugins
+
+Antigen downloads zsh scripts and sources them, according to your
+specifications. As such, these scripts are capable of doing some *real* damage
+to your system. If you are only downloading scripts from oh-my-zsh and/or
+prezto, you're probably fine, since there is a second level of manual checking
+before a script gets into the framework.
+
+But, if you are adding a script from any other source, please check the source
+code of the plugin to see its not doing anything malicious, before adding it to
+your `.zshrc`.
+
+## Meta
+
+### Helping out
+
+Antigen is licensed with the [MIT License][license].
+
+To contribute, please read the [contributing wiki page][contributing] before
+sending pull requests. If its a long/complicated change, please consider opening
+an [issue][] first so we can discuss it out. Thanks!
+
+You may also wish to [donate to the project](https://gum.co/antigen). Thank you
+so much!
+
+### Feedback please
+
+Any comments/suggestions/feedback welcome. Please say hello to me
+([@sharat87][twitter]) on twitter. Or open an issue to discuss something
+(anything!) about the project ;).
+
+### Alternatives to antigen
+
+ * [antigen-hs] - An antigen-inspired zsh plugin manager that tries to do work statically and only on manual invocation, minimizing the zsh startup time. Antigen-hs is much more minimalistic and convention over configuration than antigen.
+
+
+[Vundle]: https://github.com/gmarik/vundle
+[page on themes]: https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
+[wild]: https://github.com/zsh-users/antigen/wiki/In-the-wild
+[syntax highlighting plugin]: https://github.com/zsh-users/zsh-syntax-highlighting
+[autoenv]: https://github.com/kennethreitz/autoenv
+[f-autoenv]: https://github.com/sharat87/autoenv
+[oh-my-zsh]: https://github.com/robbyrussell/oh-my-zsh
+[cram]: https://bitheap.org/cram/
+[issue]: https://github.com/zsh-users/antigen/issues
+[license]: http://mit.sharats.me
+[contributing]: https://github.com/zsh-users/antigen/wiki/Contributing
+[twitter]: http://twitter.com/sharat87
+[antigen-hs]: https://github.com/Tarrasch/antigen-hs
diff --git a/antigen.zsh b/antigen.zsh
new file mode 100644
index 0000000..ceacad8
--- /dev/null
+++ b/antigen.zsh
@@ -0,0 +1,753 @@
+# Antigen: A simple plugin manager for zsh
+# Authors: Shrikant Sharat Kandula
+# and Contributors
+# Homepage: http://antigen.sharats.me
+# License: MIT License
+
+# Each line in this string has the following entries separated by a space
+# character.
+# , , ,
+# FIXME: Is not kept local by zsh!
+local _ANTIGEN_BUNDLE_RECORD=""
+local _ANTIGEN_INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
+
+# Used to defer compinit/compdef
+typeset -a __deferred_compdefs
+compdef () { __deferred_compdefs=($__deferred_compdefs "$*") }
+
+# Syntaxes
+# antigen-bundle [=/]
+# Keyword only arguments:
+# branch - The branch of the repo to use for this bundle.
+antigen-bundle () {
+
+ # Bundle spec arguments' default values.
+ local url="$ANTIGEN_DEFAULT_REPO_URL"
+ local loc=/
+ local branch=
+ local no_local_clone=false
+ local btype=plugin
+
+ # Parse the given arguments. (Will overwrite the above values).
+ eval "$(-antigen-parse-args \
+ 'url?, loc? ; branch:?, no-local-clone?, btype:?' \
+ "$@")"
+
+ # Check if url is just the plugin name. Super short syntax.
+ if [[ "$url" != */* ]]; then
+ loc="plugins/$url"
+ url="$ANTIGEN_DEFAULT_REPO_URL"
+ fi
+
+ # Resolve the url.
+ url="$(-antigen-resolve-bundle-url "$url")"
+
+ # Add the branch information to the url.
+ if [[ ! -z $branch ]]; then
+ url="$url|$branch"
+ fi
+
+ # The `make_local_clone` variable better represents whether there should be
+ # a local clone made. For cloning to be avoided, firstly, the `$url` should
+ # be an absolute local path and `$branch` should be empty. In addition to
+ # these two conditions, either the `--no-local-clone` option should be
+ # given, or `$url` should not a git repo.
+ local make_local_clone=true
+ if [[ $url == /* && -z $branch &&
+ ( $no_local_clone == true || ! -d $url/.git ) ]]; then
+ make_local_clone=false
+ fi
+
+ # Add the theme extension to `loc`, if this is a theme.
+ if [[ $btype == theme && $loc != *.zsh-theme ]]; then
+ loc="$loc.zsh-theme"
+ fi
+
+ # Add it to the record.
+ _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD\n$url $loc $btype"
+ _ANTIGEN_BUNDLE_RECORD="$_ANTIGEN_BUNDLE_RECORD $make_local_clone"
+
+ # Ensure a clone exists for this repo, if needed.
+ if $make_local_clone; then
+ -antigen-ensure-repo "$url"
+ fi
+
+ # Load the plugin.
+ -antigen-load "$url" "$loc" "$make_local_clone"
+
+}
+
+-antigen-resolve-bundle-url () {
+ # Given an acceptable short/full form of a bundle's repo url, this function
+ # echoes the full form of the repo's clone url.
+
+ local url="$1"
+
+ # Expand short github url syntax: `username/reponame`.
+ if [[ $url != git://* &&
+ $url != https://* &&
+ $url != http://* &&
+ $url != ssh://* &&
+ $url != /* &&
+ $url != git@github.com:*/*
+ ]]; then
+ url="https://github.com/${url%.git}.git"
+ fi
+
+ echo "$url"
+}
+
+antigen-bundles () {
+ # Bulk add many bundles at one go. Empty lines and lines starting with a `#`
+ # are ignored. Everything else is given to `antigen-bundle` as is, no
+ # quoting rules applied.
+
+ local line
+
+ grep '^[[:space:]]*[^[:space:]#]' | while read line; do
+ # Using `eval` so that we can use the shell-style quoting in each line
+ # piped to `antigen-bundles`.
+ eval "antigen-bundle $line"
+ done
+}
+
+antigen-update () {
+ # Update your bundles, i.e., `git pull` in all the plugin repos.
+
+ date > $ADOTDIR/revert-info
+
+ -antigen-echo-record |
+ awk '$4 == "true" {print $1}' |
+ sort -u |
+ while read url; do
+ echo "**** Pulling $url"
+
+ local clone_dir="$(-antigen-get-clone-dir "$url")"
+ if [[ -d "$clone_dir" ]]; then
+ (echo -n "$clone_dir:"
+ cd "$clone_dir"
+ git rev-parse HEAD) >> $ADOTDIR/revert-info
+ fi
+
+ -antigen-ensure-repo "$url" --update --verbose
+
+ echo
+ done
+}
+
+antigen-revert () {
+ if [[ -f $ADOTDIR/revert-info ]]; then
+ cat $ADOTDIR/revert-info | sed '1!p' | while read line; do
+ dir="$(echo "$line" | cut -d: -f1)"
+ git --git-dir="$dir/.git" --work-tree="$dir" \
+ checkout "$(echo "$line" | cut -d: -f2)" 2> /dev/null
+
+ done
+
+ echo "Reverted to state before running -update on $(
+ cat $ADOTDIR/revert-info | sed -n 1p)."
+
+ else
+ echo 'No revert information available. Cannot revert.' >&2
+ fi
+
+
+}
+
+-antigen-get-clone-dir () {
+ # Takes a repo url and gives out the path that this url needs to be cloned
+ # to. Doesn't actually clone anything.
+ echo -n $ADOTDIR/repos/
+
+ if [[ "$1" == "https://github.com/sorin-ionescu/prezto.git" ]]; then
+ # Prezto's directory *has* to be `.zprezto`.
+ echo .zprezto
+
+ else
+ echo "$1" | sed \
+ -e 's./.-SLASH-.g' \
+ -e 's.:.-COLON-.g' \
+ -e 's.|.-PIPE-.g'
+
+ fi
+}
+
+-antigen-get-clone-url () {
+ # Takes a repo's clone dir and gives out the repo's original url that was
+ # used to create the given directory path.
+
+ if [[ "$1" == ".zprezto" ]]; then
+ # Prezto's (in `.zprezto`), is assumed to be from `sorin-ionescu`'s
+ # remote.
+ echo https://github.com/sorin-ionescu/prezto.git
+
+ else
+ echo "$1" | sed \
+ -e "s:^$ADOTDIR/repos/::" \
+ -e 's.-SLASH-./.g' \
+ -e 's.-COLON-.:.g' \
+ -e 's.-PIPE-.|.g'
+
+ fi
+}
+
+-antigen-ensure-repo () {
+
+ # Ensure that a clone exists for the given repo url and branch. If the first
+ # argument is `--update` and if a clone already exists for the given repo
+ # and branch, it is pull-ed, i.e., updated.
+
+ # Argument defaults.
+ # The url. No sane default for this, so just empty.
+ local url=
+ # Check if we have to update.
+ local update=false
+ # Verbose output.
+ local verbose=false
+
+ eval "$(-antigen-parse-args 'url ; update?, verbose?' "$@")"
+ shift $#
+
+ # Get the clone's directory as per the given repo url and branch.
+ local clone_dir="$(-antigen-get-clone-dir $url)"
+
+ # A temporary function wrapping the `git` command with repeated arguments.
+ --plugin-git () {
+ (cd "$clone_dir" && git --no-pager "$@")
+ }
+
+ # Clone if it doesn't already exist.
+ if [[ ! -d $clone_dir ]]; then
+ git clone --recursive "${url%|*}" "$clone_dir"
+ elif $update; then
+ # Save current revision.
+ local old_rev="$(--plugin-git rev-parse HEAD)"
+ # Pull changes if update requested.
+ --plugin-git pull
+ # Update submodules.
+ --plugin-git submodule update --recursive
+ # Get the new revision.
+ local new_rev="$(--plugin-git rev-parse HEAD)"
+ fi
+
+ # If its a specific branch that we want, checkout that branch.
+ if [[ $url == *\|* ]]; then
+ local current_branch=${$(--plugin-git symbolic-ref HEAD)##refs/heads/}
+ local requested_branch="${url#*|}"
+ # Only do the checkout when we are not already on the branch.
+ [[ $requested_branch != $current_branch ]] &&
+ --plugin-git checkout $requested_branch
+ fi
+
+ if [[ -n $old_rev && $old_rev != $new_rev ]]; then
+ echo Updated from ${old_rev:0:7} to ${new_rev:0:7}.
+ if $verbose; then
+ --plugin-git log --oneline --reverse --no-merges --stat '@{1}..'
+ fi
+ fi
+
+ # Remove the temporary git wrapper function.
+ unfunction -- --plugin-git
+
+}
+
+-antigen-load () {
+
+ local url="$1"
+ local loc="$2"
+ local make_local_clone="$3"
+
+ # The full location where the plugin is located.
+ local location
+ if $make_local_clone; then
+ location="$(-antigen-get-clone-dir "$url")/$loc"
+ else
+ location="$url/$loc"
+ fi
+
+ if [[ -f "$location" ]]; then
+ source "$location"
+
+ else
+
+ # Source the plugin script.
+ # FIXME: I don't know. Looks very very ugly. Needs a better
+ # implementation once tests are ready.
+ local script_loc="$(ls "$location" | grep '\.plugin\.zsh$' | head -n1)"
+
+ if [[ -f $location/$script_loc ]]; then
+ # If we have a `*.plugin.zsh`, source it.
+ source "$location/$script_loc"
+
+ elif [[ -f $location/init.zsh ]]; then
+ # If we have a `init.zsh`
+ if (( $+functions[pmodload] )); then
+ # If pmodload is defined pmodload the module. Remove `modules/`
+ # from loc to find module name.
+ pmodload "${loc#modules/}"
+ else
+ # Otherwise source it.
+ source "$location/init.zsh"
+ fi
+
+ elif ls "$location" | grep -l '\.zsh$' &> /dev/null; then
+ # If there is no `*.plugin.zsh` file, source *all* the `*.zsh`
+ # files.
+ for script ($location/*.zsh(N)) source "$script"
+
+ elif ls "$location" | grep -l '\.sh$' &> /dev/null; then
+ # If there are no `*.zsh` files either, we look for and source any
+ # `*.sh` files instead.
+ for script ($location/*.sh(N)) source "$script"
+
+ fi
+
+ # Add to $fpath, for completion(s).
+ fpath=($location $fpath)
+
+ fi
+
+}
+
+# Update (with `git pull`) antigen itself.
+# TODO: Once update is finished, show a summary of the new commits, as a kind of
+# "what's new" message.
+antigen-selfupdate () {
+ ( cd $_ANTIGEN_INSTALL_DIR
+ if [[ ! ( -d .git || -f .git ) ]]; then
+ echo "Your copy of antigen doesn't appear to be a git clone. " \
+ "The 'selfupdate' command cannot work in this case."
+ return 1
+ fi
+ local head="$(git rev-parse --abbrev-ref HEAD)"
+ if [[ $head == "HEAD" ]]; then
+ # If current head is detached HEAD, checkout to master branch.
+ git checkout master
+ fi
+ git pull
+ )
+}
+
+antigen-cleanup () {
+
+ # Cleanup unused repositories.
+
+ local force=false
+ if [[ $1 == --force ]]; then
+ force=true
+ fi
+
+ if [[ ! -d "$ADOTDIR/repos" || -z "$(ls "$ADOTDIR/repos/")" ]]; then
+ echo "You don't have any bundles."
+ return 0
+ fi
+
+ # Find directores in ADOTDIR/repos, that are not in the bundles record.
+ local unused_clones="$(comm -13 \
+ <(-antigen-echo-record |
+ awk '$4 == "true" {print $1}' |
+ while read line; do
+ -antigen-get-clone-dir "$line"
+ done |
+ sort -u) \
+ <(ls -d "$ADOTDIR/repos/"* | sort -u))"
+
+ if [[ -z $unused_clones ]]; then
+ echo "You don't have any unidentified bundles."
+ return 0
+ fi
+
+ echo 'You have clones for the following repos, but are not used.'
+ echo "$unused_clones" |
+ while read line; do
+ -antigen-get-clone-url "$line"
+ done |
+ sed -e 's/^/ /' -e 's/|/, branch /'
+
+ if $force || (echo -n '\nDelete them all? [y/N] '; read -q); then
+ echo
+ echo
+ echo "$unused_clones" | while read line; do
+ echo -n "Deleting clone for $(-antigen-get-clone-url "$line")..."
+ rm -rf "$line"
+ echo ' done.'
+ done
+ else
+ echo
+ echo Nothing deleted.
+ fi
+}
+
+antigen-use () {
+ if [[ $1 == oh-my-zsh ]]; then
+ -antigen-use-oh-my-zsh
+ elif [[ $1 == prezto ]]; then
+ -antigen-use-prezto
+ else
+ echo 'Usage: antigen-use ' >&2
+ echo 'Where is any one of the following:' >&2
+ echo ' * oh-my-zsh' >&2
+ echo ' * prezto' >&2
+ return 1
+ fi
+}
+
+-antigen-use-oh-my-zsh () {
+ if [[ -z "$ZSH" ]]; then
+ export ZSH="$(-antigen-get-clone-dir "$ANTIGEN_DEFAULT_REPO_URL")"
+ fi
+ antigen-bundle --loc=lib
+}
+
+-antigen-use-prezto () {
+ antigen-bundle sorin-ionescu/prezto
+ export ZDOTDIR=$ADOTDIR/repos/
+}
+
+# For backwards compatibility.
+antigen-lib () {
+ -antigen-use-oh-my-zsh
+ echo '`antigen-lib` is deprecated and will soon be removed.'
+ echo 'Use `antigen-use oh-my-zsh` instead.'
+}
+
+# For backwards compatibility.
+antigen-prezto-lib () {
+ -antigen-use-prezto
+ echo '`antigen-prezto-lib` is deprecated and will soon be removed.'
+ echo 'Use `antigen-use prezto` instead.'
+}
+
+antigen-theme () {
+
+ if [[ "$1" != */* && "$1" != --* ]]; then
+ # The first argument is just a name of the plugin, to be picked up from
+ # the default repo.
+ local name="${1:-robbyrussell}"
+ antigen-bundle --loc=themes/$name --btype=theme
+
+ else
+ antigen-bundle "$@" --btype=theme
+
+ fi
+
+}
+
+antigen-apply () {
+
+ # Initialize completion.
+ local cdef
+
+ # Load the compinit module. This will readefine the `compdef` function to
+ # the one that actually initializes completions.
+ autoload -U compinit
+ compinit -i
+
+ # Apply all `compinit`s that have been deferred.
+ eval "$(for cdef in $__deferred_compdefs; do
+ echo compdef $cdef
+ done)"
+
+ unset __deferred_compdefs
+
+}
+
+antigen-list () {
+ # List all currently installed bundles.
+ if [[ -z "$_ANTIGEN_BUNDLE_RECORD" ]]; then
+ echo "You don't have any bundles." >&2
+ return 1
+ else
+ -antigen-echo-record | sort -u
+ fi
+}
+
+antigen-snapshot () {
+
+ local snapshot_file="${1:-antigen-shapshot}"
+
+ # The snapshot content lines are pairs of repo-url and git version hash, in
+ # the form:
+ #
+ local snapshot_content="$(-antigen-echo-record |
+ grep 'true$' |
+ sed 's/ .*$//' |
+ sort -u |
+ while read url; do
+ local dir="$(-antigen-get-clone-dir "$url")"
+ local version_hash="$(cd "$dir" && git rev-parse HEAD)"
+ echo "$version_hash $url"
+ done)"
+
+ {
+ # The first line in the snapshot file is for metadata, in the form:
+ # key='value'; key='value'; key='value';
+ # Where `key`s are valid shell variable names.
+
+ # Snapshot version. Has no relation to antigen version. If the snapshot
+ # file format changes, this number can be incremented.
+ echo -n "version='1';"
+
+ # Snapshot creation date+time.
+ echo -n " created_on='$(date)';"
+
+ # Add a checksum with the md5 checksum of all the snapshot lines.
+ chksum() { (md5sum; test $? = 127 && md5) 2>/dev/null | cut -d' ' -f1 }
+ local checksum="$(echo "$snapshot_content" | chksum)"
+ unset -f chksum;
+ echo -n " checksum='${checksum%% *}';"
+
+ # A newline after the metadata and then the snapshot lines.
+ echo "\n$snapshot_content"
+
+ } > "$snapshot_file"
+
+}
+
+antigen-restore () {
+
+ if [[ $# == 0 ]]; then
+ echo 'Please provide a snapshot file to restore from.' >&2
+ return 1
+ fi
+
+ local snapshot_file="$1"
+
+ # TODO: Before doing anything with the snapshot file, verify its checksum.
+ # If it fails, notify this to the user and confirm if restore should
+ # proceed.
+
+ echo -n "Restoring from $snapshot_file..."
+
+ sed -n '1!p' "$snapshot_file" |
+ while read line; do
+
+ local version_hash="${line%% *}"
+ local url="${line##* }"
+ local clone_dir="$(-antigen-get-clone-dir "$url")"
+
+ if [[ ! -d $clone_dir ]]; then
+ git clone "$url" "$clone_dir" &> /dev/null
+ fi
+
+ (cd "$clone_dir" && git checkout $version_hash) &> /dev/null
+
+ done
+
+ echo ' done.'
+ echo 'Please open a new shell to get the restored changes.'
+}
+
+antigen-help () {
+ cat <&2
+ return 1
+ fi
+ shift
+
+ if functions "antigen-$cmd" > /dev/null; then
+ "antigen-$cmd" "$@"
+ else
+ echo "Antigen: Unknown command: $cmd" >&2
+ fi
+}
+
+-antigen-parse-args () {
+ # An argument parsing functionality to parse arguments the *antigen* way :).
+ # Takes one first argument (called spec), which dictates how to parse and
+ # the rest of the arguments are parsed. Outputs a piece of valid shell code
+ # that can be passed to `eval` inside a function which creates the arguments
+ # and their values as local variables. Suggested use is to set the defaults
+ # to all arguments first and then eval the output of this function.
+
+ # Spec: Only long argument supported. No support for parsing short options.
+ # The spec must have two sections, separated by a `;`.
+ # ';'
+ # Positional arguments are passed as just values, like `command a b`.
+ # Keyword arguments are passed as a `--name=value` pair, like `command
+ # --arg1=a --arg2=b`.
+
+ # Each argument in the spec is separated by a `,`. Each keyword argument can
+ # end in a `:` to specifiy that this argument wants a value, otherwise it
+ # doesn't take a value. (The value in the output when the keyword argument
+ # doesn't have a `:` is `true`).
+
+ # Arguments in either section can end with a `?` (should come after `:`, if
+ # both are present), means optional. FIXME: Not yet implemented.
+
+ # See the test file, tests/arg-parser.t for (working) examples.
+
+ local spec="$1"
+ shift
+
+ # Sanitize the spec
+ spec="$(echo "$spec" | tr '\n' ' ' | sed 's/[[:space:]]//g')"
+
+ local code=''
+
+ --add-var () {
+ test -z "$code" || code="$code\n"
+ code="${code}local $1='$2'"
+ }
+
+ local positional_args="$(echo "$spec" | cut -d\; -f1)"
+ local positional_args_count="$(echo $positional_args |
+ awk -F, '{print NF}')"
+
+ # Set spec values based on the positional arguments.
+ local i=1
+ while [[ -n $1 && $1 != --* ]]; do
+
+ if (( $i > $positional_args_count )); then
+ echo "Only $positional_args_count positional arguments allowed." >&2
+ echo "Found at least one more: '$1'" >&2
+ return
+ fi
+
+ local name_spec="$(echo "$positional_args" | cut -d, -f$i)"
+ local name="${${name_spec%\?}%:}"
+ local value="$1"
+
+ if echo "$code" | grep -l "^local $name=" &> /dev/null; then
+ echo "Argument '$name' repeated with the value '$value'". >&2
+ return
+ fi
+
+ --add-var $name "$value"
+
+ shift
+ i=$(($i + 1))
+ done
+
+ local keyword_args="$(
+ # Positional arguments can double up as keyword arguments too.
+ echo "$positional_args" | tr , '\n' |
+ while read line; do
+ if [[ $line == *\? ]]; then
+ echo "${line%?}:?"
+ else
+ echo "$line:"
+ fi
+ done
+
+ # Specified keyword arguments.
+ echo "$spec" | cut -d\; -f2 | tr , '\n'
+ )"
+ local keyword_args_count="$(echo $keyword_args | awk -F, '{print NF}')"
+
+ # Set spec values from keyword arguments, if any. The remaining arguments
+ # are all assumed to be keyword arguments.
+ while [[ $1 == --* ]]; do
+ # Remove the `--` at the start.
+ local arg="${1#--}"
+
+ # Get the argument name and value.
+ if [[ $arg != *=* ]]; then
+ local name="$arg"
+ local value=''
+ else
+ local name="${arg%\=*}"
+ local value="${arg#*=}"
+ fi
+
+ if echo "$code" | grep -l "^local $name=" &> /dev/null; then
+ echo "Argument '$name' repeated with the value '$value'". >&2
+ return
+ fi
+
+ # The specification for this argument, used for validations.
+ local arg_line="$(echo "$keyword_args" |
+ egrep "^$name:?\??" | head -n1)"
+
+ # Validate argument and value.
+ if [[ -z $arg_line ]]; then
+ # This argument is not known to us.
+ echo "Unknown argument '$name'." >&2
+ return
+
+ elif (echo "$arg_line" | grep -l ':' &> /dev/null) &&
+ [[ -z $value ]]; then
+ # This argument needs a value, but is not provided.
+ echo "Required argument for '$name' not provided." >&2
+ return
+
+ elif (echo "$arg_line" | grep -vl ':' &> /dev/null) &&
+ [[ -n $value ]]; then
+ # This argument doesn't need a value, but is provided.
+ echo "No argument required for '$name', but provided '$value'." >&2
+ return
+
+ fi
+
+ if [[ -z $value ]]; then
+ value=true
+ fi
+
+ --add-var "${name//-/_}" "$value"
+ shift
+ done
+
+ echo "$code"
+
+ unfunction -- --add-var
+
+}
+
+# Echo the bundle specs as in the record. The first line is not echoed since it
+# is a blank line.
+-antigen-echo-record () {
+ echo "$_ANTIGEN_BUNDLE_RECORD" | sed -n '1!p'
+}
+
+-antigen-env-setup () {
+
+ # Helper function: Same as `export $1=$2`, but will only happen if the name
+ # specified by `$1` is not already set.
+ -set-default () {
+ local arg_name="$1"
+ local arg_value="$2"
+ eval "test -z \"\$$arg_name\" && export $arg_name='$arg_value'"
+ }
+
+ # Pre-startup initializations.
+ -set-default ANTIGEN_DEFAULT_REPO_URL \
+ https://github.com/robbyrussell/oh-my-zsh.git
+ -set-default ADOTDIR $HOME/.antigen
+
+ # Setup antigen's own completion.
+ compdef _antigen antigen
+
+ # Remove private functions.
+ unfunction -- -set-default
+}
+
+# Setup antigen's autocompletion
+_antigen () {
+ compadd \
+ bundle \
+ bundles \
+ update \
+ revert \
+ list \
+ cleanup \
+ use \
+ selfupdate \
+ theme \
+ apply \
+ snapshot \
+ restore \
+ help
+}
+
+-antigen-env-setup
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..61c8e0e
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+cram==0.6
diff --git a/tests/.zshenv b/tests/.zshenv
new file mode 100644
index 0000000..c3af528
--- /dev/null
+++ b/tests/.zshenv
@@ -0,0 +1,43 @@
+# zshrc file written for antigen's tests. Might not be a good one for daily use.
+
+# See cram's documentation for some of the variables used below.
+
+export ADOTDIR="$PWD/dot-antigen"
+
+test -f "$TESTDIR/.zcompdump" && rm "$TESTDIR/.zcompdump"
+
+source "$TESTDIR/../antigen.zsh"
+
+# A test plugin repository to test out antigen with.
+
+export PLUGIN_DIR="$PWD/test-plugin"
+mkdir "$PLUGIN_DIR"
+
+# A wrapper function over `git` to work with the test plugin repo.
+alias pg='git --git-dir "$PLUGIN_DIR/.git" --work-tree "$PLUGIN_DIR"'
+
+echo 'alias hehe="echo hehe"' > "$PLUGIN_DIR"/aliases.zsh
+echo 'export PS1="prompt>"' > "$PLUGIN_DIR"/silly.zsh-theme
+
+{
+ pg init
+ pg add .
+ pg commit -m 'Initial commit'
+} > /dev/null
+
+# Another test plugin.
+
+export PLUGIN_DIR2="$PWD/test-plugin2"
+mkdir "$PLUGIN_DIR2"
+
+# A wrapper function over `git` to work with the test plugin repo.
+alias pg2='git --git-dir "$PLUGIN_DIR2/.git" --work-tree "$PLUGIN_DIR2"'
+
+echo 'alias hehe2="echo hehe2"' > "$PLUGIN_DIR2"/init.zsh
+echo 'alias unsourced-alias="echo unsourced-alias"' > "$PLUGIN_DIR2"/aliases.zsh
+
+{
+ pg2 init
+ pg2 add .
+ pg2 commit -m 'Initial commit'
+} > /dev/null
diff --git a/tests/antigen-wrapper.t b/tests/antigen-wrapper.t
new file mode 100644
index 0000000..a88f59f
--- /dev/null
+++ b/tests/antigen-wrapper.t
@@ -0,0 +1,21 @@
+Create a dummy antigen command.
+
+ $ antigen-dummy () {
+ > echo me dummy
+ > }
+
+Check the normal way of calling it
+
+ $ antigen-dummy
+ me dummy
+
+Call with the wrapper syntax.
+
+ $ antigen dummy
+ me dummy
+
+Call with an alias
+
+ $ alias a=antigen
+ $ a dummy
+ me dummy
diff --git a/tests/arg-parser.t b/tests/arg-parser.t
new file mode 100644
index 0000000..b1f58e5
--- /dev/null
+++ b/tests/arg-parser.t
@@ -0,0 +1,64 @@
+Helper alias.
+
+ $ alias parse='-antigen-parse-args "url?, loc?;
+ > btype:?, no-local-clone?"'
+
+No arguments (since all are specified as optional).
+
+ $ parse
+ (glob)
+
+One positional argument.
+
+ $ parse name
+ local url='name'
+
+Two arguments.
+
+ $ parse url location
+ local url='url'
+ local loc='location'
+
+Three arguments.
+
+ $ parse url location crap
+ Only 2 positional arguments allowed.
+ Found at least one more: 'crap'
+
+Keywordo magic.
+
+ $ parse url location --btype=1 --no-local-clone
+ local url='url'
+ local loc='location'
+ local btype='1'
+ local no_local_clone='true'
+
+Unknown keyword argument.
+
+ $ parse --me=genius
+ Unknown argument 'me'.
+
+Missed value for keyword argument.
+
+ $ parse --btype
+ Required argument for 'btype' not provided.
+
+Provide value for keyword argument, that shouldn't be there.
+
+ $ parse --no-local-clone=yes
+ No argument required for 'no-local-clone', but provided 'yes'.
+
+Positional argument as a keyword argument.
+
+ $ parse --url=some-url
+ local url='some-url'
+
+Repeated keyword arguments.
+
+ $ parse --url=url1 --url=url2
+ Argument 'url' repeated with the value 'url2'.
+
+Repeated, once as positional and once more as keyword.
+
+ $ parse url1 --url=url2
+ Argument 'url' repeated with the value 'url2'.
diff --git a/tests/branch-bundle.t b/tests/branch-bundle.t
new file mode 100644
index 0000000..12deca1
--- /dev/null
+++ b/tests/branch-bundle.t
@@ -0,0 +1,32 @@
+Branch b1.
+
+ $ pg branch b1
+ $ pg checkout b1
+ Switched to branch 'b1'
+ $ cat > $PLUGIN_DIR/aliases.zsh < alias hehe='echo hehe from b1'
+ > EOF
+ $ pg commit -am 'Change for b1'
+ \[b1 [a-f0-9]{7}\] Change for b1 (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Go back to master.
+
+ $ pg checkout master
+ Switched to branch 'master'
+
+Load plugin from b1.
+
+ $ antigen-bundle $PLUGIN_DIR --branch=b1 &> /dev/null
+ $ hehe
+ hehe from b1
+
+Does not say 'Already on b1' on each session startup.
+
+ $ antigen-bundle $PLUGIN_DIR --branch=b1
+
+Load plugin from master.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ hehe
+ hehe
diff --git a/tests/bundle-syntaxes.t b/tests/bundle-syntaxes.t
new file mode 100644
index 0000000..983e692
--- /dev/null
+++ b/tests/bundle-syntaxes.t
@@ -0,0 +1,94 @@
+Test helper and mock functions.
+
+ $ ANTIGEN_DEFAULT_REPO_URL=gh-user/repo
+
+ $ b () {
+ > antigen-bundle "$@"
+ > }
+
+ $ -antigen-ensure-repo () {}
+
+ $ -antigen-load () {
+ > echo "url: $1"
+ > echo "dir: $2"
+ > echo "clone?: $3"
+ > }
+
+Short and sweet.
+
+ $ b lol
+ url: https://github.com/gh-user/repo.git
+ dir: plugins/lol
+ clone?: true
+
+Short repo url.
+
+ $ b github-username/repo-name
+ url: https://github.com/github-username/repo-name.git
+ dir: /
+ clone?: true
+
+Short repo url with `.git` suffix.
+
+ $ b github-username/repo-name.git
+ url: https://github.com/github-username/repo-name.git
+ dir: /
+ clone?: true
+
+Long repo url.
+
+ $ b https://github.com/user/repo.git
+ url: https://github.com/user/repo.git
+ dir: /
+ clone?: true
+
+Long repo url with missing `.git` suffix (should'nt add the suffix).
+
+ $ b https://github.com/user/repo
+ url: https://github.com/user/repo
+ dir: /
+ clone?: true
+
+Short repo with location.
+
+ $ b user/plugin path/to/plugin
+ url: https://github.com/user/plugin.git
+ dir: path/to/plugin
+ clone?: true
+
+Keyword arguments, in respective places.
+
+ $ b --url=user/repo --loc=path/of/plugin
+ url: https://github.com/user/repo.git
+ dir: path/of/plugin
+ clone?: true
+
+Keyword arguments, in respective places, with full repo url.
+
+ $ b --url=https://github.com/user/repo.git --loc=plugin/path
+ url: https://github.com/user/repo.git
+ dir: plugin/path
+ clone?: true
+
+Keyword arguments, in reversed order.
+
+ $ b --loc=path/of/plugin --url=user/repo
+ url: https://github.com/user/repo.git
+ dir: path/of/plugin
+ clone?: true
+
+Mixed positional and keyword arguments, and skip `loc`.
+
+ $ b user/repo --loc=plugin/loc
+ url: https://github.com/user/repo.git
+ dir: plugin/loc
+ clone?: true
+
+Just `loc`, using keyword arguments.
+
+ $ b --loc=plugin/path
+ url: https://github.com/gh-user/repo.git
+ dir: plugin/path
+ clone?: true
+
+TODO: Error reporting with erroneous arguments or usage with incorrect syntax.
diff --git a/tests/bundle.t b/tests/bundle.t
new file mode 100644
index 0000000..3a69b95
--- /dev/null
+++ b/tests/bundle.t
@@ -0,0 +1,29 @@
+Load plugin from master.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ hehe
+ hehe
+
+Load the plugin again. Just to see nothing happens.
+
+ $ antigen-bundle $PLUGIN_DIR
+ $ hehe
+ hehe
+
+Confirm there is still only one repository.
+
+ $ ls $ADOTDIR/repos | wc -l
+ 1
+
+Load a prezto style module. Should only source the `init.zsh` present in the
+module.
+
+ $ antigen-bundle $PLUGIN_DIR2 &> /dev/null
+ $ hehe2
+ hehe2
+
+The alias defined in the other zsh file should not be available.
+
+ $ unsourced-alias
+ zsh: command not found: unsourced-alias
+ [127]
diff --git a/tests/bundles.t b/tests/bundles.t
new file mode 100644
index 0000000..696cc6f
--- /dev/null
+++ b/tests/bundles.t
@@ -0,0 +1,26 @@
+Add multiple bundles.
+
+ $ echo "$PLUGIN_DIR\n$PLUGIN_DIR2" | antigen-bundles &> /dev/null
+
+Check if they are both applied.
+
+ $ hehe
+ hehe
+ $ hehe2
+ hehe2
+
+Clean it all up.
+
+ $ export _ANTIGEN_BUNDLE_RECORD=""
+ $ antigen-cleanup --force &> /dev/null
+
+Specify with indentation.
+
+ $ echo " $PLUGIN_DIR\n $PLUGIN_DIR2" | antigen-bundles &> /dev/null
+
+Again, check if they are both applied.
+
+ $ hehe
+ hehe
+ $ hehe2
+ hehe2
diff --git a/tests/cleanup.t b/tests/cleanup.t
new file mode 100644
index 0000000..d53dc7a
--- /dev/null
+++ b/tests/cleanup.t
@@ -0,0 +1,57 @@
+Firstly, no plugins, nothing to cleanup.
+
+ $ antigen-cleanup --force
+ You don't have any bundles.
+
+Load the plugins.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ antigen-bundle $PLUGIN_DIR2 &> /dev/null
+
+Check the listing.
+
+ $ antigen-list
+ */test-plugin / plugin true (glob)
+ */test-plugin2 / plugin true (glob)
+
+Nothing should be available for cleanup.
+
+ $ antigen-cleanup --force
+ You don't have any unidentified bundles.
+
+Clear out the bundles record.
+
+ $ _ANTIGEN_BUNDLE_RECORD=""
+
+Check the listing, after clearing the record.
+
+ $ antigen-list
+ You don't have any bundles.
+ [1]
+
+Confirm the plugin directory exists.
+
+ $ ls dot-antigen/repos | wc -l
+ 2
+
+Do the cleanup.
+
+ $ antigen-cleanup --force
+ You have clones for the following repos, but are not used.
+ */test-plugin (glob)
+ */test-plugin2 (glob)
+
+
+ Deleting clone for */test-plugin... done. (glob)
+ Deleting clone for */test-plugin2... done. (glob)
+
+Check the listing, after cleanup.
+
+ $ antigen-list
+ You don't have any bundles.
+ [1]
+
+Confirm the plugin directory does not exist after cleanup.
+
+ $ ls dot-antigen/repos | wc -l
+ 0
diff --git a/tests/list.t b/tests/list.t
new file mode 100644
index 0000000..7b8af1e
--- /dev/null
+++ b/tests/list.t
@@ -0,0 +1,24 @@
+Empty initial listing.
+
+ $ antigen-list
+ You don't have any bundles.
+ [1]
+
+Add a bundle.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ antigen-list
+ */test-plugin / plugin true (glob)
+
+Add same bundle and check uniqueness.
+
+ $ antigen-bundle $PLUGIN_DIR
+ $ antigen-list
+ */test-plugin / plugin true (glob)
+
+Add another bundle.
+
+ $ antigen-bundle $PLUGIN_DIR2 &> /dev/null
+ $ antigen-list
+ */test-plugin / plugin true (glob)
+ */test-plugin2 / plugin true (glob)
diff --git a/tests/no_local_clone.t b/tests/no_local_clone.t
new file mode 100644
index 0000000..8ec41d8
--- /dev/null
+++ b/tests/no_local_clone.t
@@ -0,0 +1,34 @@
+Load the plugin with no local clone.
+
+ $ antigen-bundle $PLUGIN_DIR --no-local-clone
+
+Check if the plugin is loaded correctly.
+
+ $ hehe
+ hehe
+
+Confirm no clone is made.
+
+ $ test -d dot-antigen
+ [1]
+
+Load the plugin with a clone.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+
+Empty the record.
+
+ $ _ANTIGEN_BUNDLE_RECORD=
+
+Load the plugin again with no local clone.
+
+ $ antigen-bundle $PLUGIN_DIR --no-local-clone
+
+The cleanup should list the bundle's clone.
+
+ $ antigen-cleanup --force
+ You have clones for the following repos, but are not used.
+ */test-plugin (glob)
+
+
+ Deleting clone for */test-plugin... done. (glob)
diff --git a/tests/revert-update.t b/tests/revert-update.t
new file mode 100644
index 0000000..f4763bc
--- /dev/null
+++ b/tests/revert-update.t
@@ -0,0 +1,59 @@
+Load and test plugin.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ hehe
+ hehe
+
+Save the current HEAD of the plugin.
+
+ $ old_version="$(pg rev-parse HEAD)"
+
+Modify the plugin.
+
+ $ cat > $PLUGIN_DIR/aliases.zsh < alias hehe='echo hehe, updated'
+ > EOF
+ $ pg commit -am 'Updated message'
+ \[master [a-f0-9]{7}\] Updated message (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Save the new HEAD of the plugin.
+
+ $ new_version="$(pg rev-parse HEAD)"
+
+Define a convenience function to get the current version.
+
+ $ current-version () {(cd dot-antigen/repos/* && git rev-parse HEAD)}
+
+Confirm we currently have the old version.
+
+ $ [[ $(current-version) == $old_version ]]
+
+Run antigen's update.
+
+ $ antigen-update
+ **** Pulling */test-plugin (glob)
+ From */test-plugin (glob)
+ ???????..??????? master -> origin/master (glob)
+ Updating ???????..??????? (glob)
+ Fast-forward
+ aliases.zsh |\s+2 \+- (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+ Updated from ??????? to ???????. (glob)
+ ??????? Updated message (glob)
+ aliases.zsh |\s+2 +- (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+
+Confirm we have the new version.
+
+ $ [[ $(current-version) == $new_version ]]
+
+Run update again, with no changes in the origin repo.
+
+ $ antigen-revert
+ Reverted to state before running -update on *. (glob)
+
+Confirm we have the old version again.
+
+ $ [[ $(current-version) == $old_version ]]
diff --git a/tests/selfupdate.t b/tests/selfupdate.t
new file mode 100644
index 0000000..b8fc970
--- /dev/null
+++ b/tests/selfupdate.t
@@ -0,0 +1,69 @@
+Set environment variables for this test case
+
+ $ export TEST_DIR=$PWD
+ $ export TEST_HOST=$TEST_DIR/host
+ $ export TEST_NORMAL=$TEST_DIR/client
+ $ export TEST_SUBMODULE=$TEST_DIR/submodule
+
+Create fake host repository
+
+ $ mkdir -p $TEST_HOST
+ $ cd $TEST_HOST
+ $ git init
+ Initialized empty Git repository in * (glob)
+ $ echo 1 > ver
+ $ git add ver
+ $ git commit -m "1"
+ [master (root-commit) ???????] 1 (glob)
+ 1 file changed, 1 insertion(+)
+ create mode 100644 ver
+
+Create a normal repository cloning from host
+
+ $ git clone $TEST_HOST $TEST_NORMAL &> /dev/null
+
+Create a submodule repository cloning from host
+
+ $ mkdir -p $TEST_SUBMODULE
+ $ cd $TEST_SUBMODULE
+ $ git init
+ Initialized empty Git repository in * (glob)
+ $ git submodule add $TEST_HOST antigen &> /dev/null
+ $ git commit -m "1"
+ [master (root-commit) ???????] 1 (glob)
+ 2 files changed, 4 insertions(+)
+ create mode 100644 .gitmodules
+ create mode 160000 antigen
+
+Update host repository
+
+ $ cd $TEST_HOST
+ $ echo 2 > ver
+ $ git add ver
+ $ git commit -m "2"
+ [master ???????] 2 (glob)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Use selfupdate from normal repository
+
+ $ _ANTIGEN_INSTALL_DIR=$TEST_NORMAL antigen-selfupdate
+ From * (glob)
+ ???????..??????? master -> origin/master (glob)
+ Updating ???????..??????? (glob)
+ Fast-forward
+ ver | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+ $ _ANTIGEN_INSTALL_DIR=$TEST_NORMAL antigen-selfupdate
+ Already up-to-date.
+
+Use selfupdate from submodule repository
+
+ $ _ANTIGEN_INSTALL_DIR=$TEST_SUBMODULE/antigen antigen-selfupdate
+ From * (glob)
+ ???????..??????? master -> origin/master (glob)
+ Updating ???????..??????? (glob)
+ Fast-forward
+ ver | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+ $ _ANTIGEN_INSTALL_DIR=$TEST_SUBMODULE/antigen antigen-selfupdate
+ Already up-to-date.
diff --git a/tests/snapshots.t b/tests/snapshots.t
new file mode 100644
index 0000000..2bb066b
--- /dev/null
+++ b/tests/snapshots.t
@@ -0,0 +1,34 @@
+Load a couple of plugins.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ antigen-bundle $PLUGIN_DIR2 &> /dev/null
+
+Create a snapshot file.
+
+ $ test -f snapshot-file
+ [1]
+ $ antigen-snapshot snapshot-file
+ $ test -f snapshot-file
+
+See the contents of the snapshot file.
+
+ $ cat snapshot-file
+ version='1'; created_on='*'; checksum='*'; (glob)
+ .{40} .*/test-plugin (re)
+ .{40} .*/test-plugin2 (re)
+
+Reset the antigen's bundle record and run cleanup.
+
+ $ unset _ANTIGEN_BUNDLE_RECORD
+ $ antigen-cleanup --force | grep '^Deleting' | wc -l
+ 2
+
+Restore from the snapshot.
+
+ $ ls dot-antigen/repos | wc -l
+ 0
+ $ antigen-restore snapshot-file
+ Restoring from snapshot-file... done.
+ Please open a new shell to get the restored changes.
+ $ ls dot-antigen/repos | wc -l
+ 2
diff --git a/tests/theme.t b/tests/theme.t
new file mode 100644
index 0000000..dfdc6d2
--- /dev/null
+++ b/tests/theme.t
@@ -0,0 +1,5 @@
+Load the theme explicitly.
+
+ $ antigen-theme $PLUGIN_DIR silly &> /dev/null
+ $ echo "$PS1"
+ prompt>
diff --git a/tests/update.t b/tests/update.t
new file mode 100644
index 0000000..df94b04
--- /dev/null
+++ b/tests/update.t
@@ -0,0 +1,47 @@
+Load plugin.
+
+ $ antigen-bundle $PLUGIN_DIR &> /dev/null
+ $ hehe
+ hehe
+
+Update the plugin.
+
+ $ cat > $PLUGIN_DIR/aliases.zsh < alias hehe='echo hehe, updated'
+ > EOF
+ $ pg commit -am 'Updated message'
+ \[master [a-f0-9]{7}\] Updated message (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Run antigen's update.
+
+ $ antigen-update
+ **** Pulling */test-plugin (glob)
+ From */test-plugin (glob)
+ ???????..??????? master -> origin/master (glob)
+ Updating ???????..??????? (glob)
+ Fast-forward
+ aliases.zsh |\s+2 \+- (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+ Updated from ??????? to ???????. (glob)
+ ??????? Updated message (glob)
+ aliases.zsh |\s+2 \+- (re)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+
+Confirm there is still only one repository.
+
+ $ ls $ADOTDIR/repos | wc -l
+ 1
+
+The new alias should not activate.
+
+ $ hehe
+ hehe
+
+Run update again, with no changes in the origin repo.
+
+ $ antigen-update
+ **** Pulling */test-plugin (glob)
+ Already up-to-date.
+
diff --git a/tests/url-resolver.t b/tests/url-resolver.t
new file mode 100644
index 0000000..a4f4436
--- /dev/null
+++ b/tests/url-resolver.t
@@ -0,0 +1,33 @@
+Helper alias.
+
+ $ alias resolve=-antigen-resolve-bundle-url
+
+Complete urls.
+
+ $ resolve https://github.com/zsh-users/antigen.git
+ https://github.com/zsh-users/antigen.git
+ $ resolve git://github.com/zsh-users/antigen.git
+ git://github.com/zsh-users/antigen.git
+ $ resolve git@github.com:zsh-users/antigen.git
+ git@github.com:zsh-users/antigen.git
+
+Complete github urls, missing the `.git` suffix.
+
+ $ resolve https://github.com/zsh-users/antigen
+ https://github.com/zsh-users/antigen
+ $ resolve git://github.com/zsh-users/antigen
+ git://github.com/zsh-users/antigen
+ $ resolve git@github.com:zsh-users/antigen
+ git@github.com:zsh-users/antigen
+
+Just username and repo name.
+
+ $ resolve zsh-users/antigen
+ https://github.com/zsh-users/antigen.git
+ $ resolve zsh-users/antigen.git
+ https://github.com/zsh-users/antigen.git
+
+Local absolute file path.
+
+ $ resolve /path/to/a/local/git/repo
+ /path/to/a/local/git/repo
diff --git a/tests/use.t b/tests/use.t
new file mode 100644
index 0000000..2231e8c
--- /dev/null
+++ b/tests/use.t
@@ -0,0 +1,35 @@
+Use unknown library.
+
+ $ antigen-use unknown
+ Usage: antigen-use
+ Where is any one of the following:
+ * oh-my-zsh
+ * prezto
+ [1]
+
+Missing argument.
+
+ $ antigen-use
+ Usage: antigen-use
+ Where is any one of the following:
+ * oh-my-zsh
+ * prezto
+ [1]
+
+Mock out the library loading functions.
+
+ $ -antigen-use-oh-my-zsh () { echo Using oh-my-zsh. }
+ $ -antigen-use-prezto () { echo Using prezto. }
+
+Note: We lack tests for these internal functions. I'm not sure how feasible
+testing them is given they most certainly use the network.
+
+Use oh-my-zsh library.
+
+ $ antigen-use oh-my-zsh
+ Using oh-my-zsh.
+
+Use prezto library.
+
+ $ antigen-use prezto
+ Using prezto.
diff --git a/travis-ppa.sh b/travis-ppa.sh
new file mode 100755
index 0000000..bc34d70
--- /dev/null
+++ b/travis-ppa.sh
@@ -0,0 +1,5 @@
+#! /bin/sh
+if [ $PPA != 'none' ];then
+ sudo apt-add-repository -y $PPA;
+ sudo apt-get update -qq;
+fi