From 1978fdad423e1843239d64ed5cbf6d3be495eec2 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sun, 8 Mar 2015 16:14:28 -0500 Subject: [PATCH] Trying out antigen for zsh --- antigen.zsh | 753 ++++++++++++++++++++++++++++++++++++++++++++++++++++ zshrc | 24 +- 2 files changed, 772 insertions(+), 5 deletions(-) create mode 100644 antigen.zsh 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/zshrc b/zshrc index 9cb9019..c2ff7a9 100644 --- a/zshrc +++ b/zshrc @@ -1,3 +1,9 @@ +source ~/dotfiles/antigen.zsh +antigen use oh-my-zsh +antigen bundle zsh-users/zsh-syntax-highlighting +antigen bundle git +antigen theme S1cK94/minimal minimal-path-git + bindkey -e alias vi=vim @@ -6,7 +12,7 @@ alias tmux="tmux -2" alias ta="tmux attach -d" alias dustinswan="mosh dustinswan@dustinswan.org" alias kill_offlineimap="ps aux | grep offlineimap | awk '{ print $2 }' | xargs kill -9" -alias em='emacsclient -a "" -t' +alias e='emacsclient -a "" -t' export EDITOR="emacsclient -a "" -t" export TERM="screen-256color" export MOSH_TITLE_NOPREFIX=1 @@ -26,6 +32,16 @@ alias dswan="ssh root@dswan.insors.net" alias er='rm -rf logs; unzip -o' # PATH + +export PATH=$HOME/depot_tools:$PATH +#export GYP_CROSSCOMPILE=1 +#export GYP_GENERATORS="ninja,xcode-ninja" +#export GYP_DEFINES="OS=ios target_arch=arm64 target_subarch=arm64 build_with_chromium=0" +#export GYP_GENERATOR_FLAGS="xcode_project_version=3.2 xcode_ninja_target_pattern=All_iOS xcode_ninja_executable_target_pattern=AppRTCDemo|libjingle_peerconnection_unittest|libjingle_peerconnection_objc_test output_dir=out_ios64" +export GYP_DEFINES="OS=ios target_arch=armv64 target_subarch=64" +export GYP_CROSSCOMPILE=1 +export GYP_GENERATOR_FLAGS="output_dir=out_ios" + export PATH=/usr/local/bin:/usr/local/sbin:$PATH # Homebrew export PATH=/Applications/Postgres.app/Contents/MacOS/bin:$PATH export PATH=/usr/local/share/python:$PATH @@ -37,7 +53,8 @@ export NODE_PATH=/usr/local/lib/node:/usr/local/share/npm/lib/node_modules export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages # Nix -. $HOME/.nix-profile/etc/profile.d/nix.sh +# . $HOME/.nix-profile/etc/profile.d/nix.sh +# export NIX_PATH=$HOME/nixpkgs:nixpkgs=$HOME/nixpkgs # Chruby source /usr/local/share/chruby/chruby.sh @@ -48,9 +65,6 @@ source /usr/local/share/chruby/auto.sh export NVM_DIR=~/.nvm source $(brew --prefix nvm)/nvm.sh -#autoload predict-on -#predict-on - eval `keychain --eval id_rsa` HISTSIZE=1000