summaryrefslogtreecommitdiff
path: root/plugins/github
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/github')
-rw-r--r--plugins/github/README.md46
-rw-r--r--plugins/github/_github40
-rw-r--r--plugins/github/_hub163
-rw-r--r--plugins/github/github.plugin.zsh101
4 files changed, 250 insertions, 100 deletions
diff --git a/plugins/github/README.md b/plugins/github/README.md
new file mode 100644
index 000000000..fea607876
--- /dev/null
+++ b/plugins/github/README.md
@@ -0,0 +1,46 @@
+# github
+
+This plugin supports working with GitHub from the command line. It provides a few things:
+
+* Sets up the `hub` wrapper and completions for the `git` command if you have `hub` installed.
+* Completion for the `github` Ruby gem.
+* Convenience functions for working with repos and URLs.
+
+### Functions
+
+* `empty_gh` - Creates a new empty repo (with a `README.md`) and pushes it to GitHub
+* `new_gh` - Initializes an existing directory as a repo and pushes it to GitHub
+* `exist_gh` - Takes an existing repo and pushes it to GitHub
+* `git.io` - Shortens a URL using [git.io](http://git.io)
+
+
+## Installation
+
+[Hub](http://github.com/github/hub) needs to be installed if you want to use it. On OS X with Homebrew, this can be done with `brew install hub`. The `hub` completion definition needs to be added to your `$FPATH` before initializing OMZ.
+
+The [`github` Ruby gem](http://github.com/defunkt/github-gem) needs to be installed if you want to use it.
+
+### Configuration
+
+These settings affect `github`'s behavior.
+
+#### Environment variables
+
+* `$GITHUB_USER`
+* `$GITHUB_PASSWORD`
+
+#### Git configuration options
+
+* `github.user` - GitHub username for repo operations
+
+See `man hub` for more details.
+
+### Homebrew installation note
+
+If you have installed `hub` using Homebrew, its completions may not be on your `$FPATH` if you are using the system `zsh`. Homebrew installs `zsh` completion definitions to `/usr/local/share/zsh/site-functions`, which will be on `$FPATH` for the Homebrew-installed `zsh`, but not for the system `zsh`. If you want it to work with the system `zsh`, add this to your `~/.zshrc` before it sources `oh-my-zsh.sh`.
+
+```zsh
+if (( ! ${fpath[(I)/usr/local/share/zsh/site-functions]} )); then
+ FPATH=/usr/local/share/zsh/site-functions:$FPATH
+fi
+```
diff --git a/plugins/github/_github b/plugins/github/_github
deleted file mode 100644
index 83e1713c7..000000000
--- a/plugins/github/_github
+++ /dev/null
@@ -1,40 +0,0 @@
-#compdef github
-#autoload
-
-# in order to make this work, you will need to have the github gem installed
-# http://github.com/defunkt/github-gem
-
-# github zsh completion, based on homebrew completion
-
-local -a _1st_arguments
-_1st_arguments=(
- 'browse:Open this repo in a web browser'
- 'clone:Clone a repo'
- 'config:Automatically set configuration info, or pass args to specify'
- 'create-from-local:Create a new GitHub repository from the current local repository'
- 'create:Create a new empty GitHub repository'
- 'fetch:Fetch from a remote to a local branch'
- 'fetch_all:Fetch all refs from a user'
- 'fork:Forks a GitHub repository'
- 'home:Open this repos master branch in a web browser'
- 'ignore:Ignore a SHA from github network commits'
- 'info:Info about this project'
- 'issues:Project issues tools'
- 'network:Project network tools - sub-commands : web [user], list, fetch, commits'
- 'open:Open the given user/project in a web browser'
- 'pull-request:Generate the text for a pull request'
- 'pull:Pull from a remote'
- 'search:Search GitHub for the given repository name'
- 'track:Track another users repository'
-)
-
-local expl
-local -a pkgs installed_pkgs
-
-_arguments \
- '*:: :->subcmds' && return 0
-
-if (( CURRENT == 1 )); then
- _describe -t commands "github subcommand" _1st_arguments
- return
-fi
diff --git a/plugins/github/_hub b/plugins/github/_hub
new file mode 100644
index 000000000..3a6493878
--- /dev/null
+++ b/plugins/github/_hub
@@ -0,0 +1,163 @@
+#compdef hub
+
+# Zsh will source this file when attempting to autoload the "_hub" function,
+# typically on the first attempt to complete the hub command. We define two new
+# setup helper routines (one for the zsh-distributed version, one for the
+# git-distributed, bash-based version). Then we redefine the "_hub" function to
+# call "_git" after some other interception.
+#
+# This is pretty fragile, if you think about it. Any number of implementation
+# changes in the "_git" scripts could cause problems down the road. It would be
+# better if the stock git completions were just a bit more permissive about how
+# it allowed third-party commands to be added.
+
+(( $+functions[__hub_setup_zsh_fns] )) ||
+__hub_setup_zsh_fns () {
+ (( $+functions[_git-alias] )) ||
+ _git-alias () {
+ _arguments \
+ '-s[output shell script suitable for eval]' \
+ '1::shell:(zsh bash csh)'
+ }
+
+ (( $+functions[_git-browse] )) ||
+ _git-browse () {
+ _arguments \
+ '-u[output the URL]' \
+ '2::subpage:(wiki commits issues)'
+ }
+
+ (( $+functions[_git-compare] )) ||
+ _git-compare () {
+ _arguments \
+ '-u[output the URL]' \
+ ':[start...]end range:'
+ }
+
+ (( $+functions[_git-create] )) ||
+ _git-create () {
+ _arguments \
+ '::name (REPOSITORY or ORGANIZATION/REPOSITORY):' \
+ '-p[make repository private]' \
+ '-d[description]:description' \
+ '-h[home page]:repository home page URL:_urls'
+ }
+
+ (( $+functions[_git-fork] )) ||
+ _git-fork () {
+ _arguments \
+ '--no-remote[do not add a remote for the new fork]'
+ }
+
+ (( $+functions[_git-pull-request] )) ||
+ _git-pull-request () {
+ _arguments \
+ '-f[force (skip check for local commits)]' \
+ '-b[base]:base ("branch", "owner\:branch", "owner/repo\:branch"):' \
+ '-h[head]:head ("branch", "owner\:branch", "owner/repo\:branch"):' \
+ - set1 \
+ '-m[message]' \
+ '-F[file]' \
+ '-a[user]' \
+ '-M[milestone]' \
+ '-l[labels]' \
+ - set2 \
+ '-i[issue]:issue number:' \
+ - set3 \
+ '::issue-url:_urls'
+ }
+
+ # stash the "real" command for later
+ functions[_hub_orig_git_commands]=$functions[_git_commands]
+
+ # Replace it with our own wrapper.
+ declare -f _git_commands >& /dev/null && unfunction _git_commands
+ _git_commands () {
+ local ret=1
+ # call the original routine
+ _call_function ret _hub_orig_git_commands
+
+ # Effectively "append" our hub commands to the behavior of the original
+ # _git_commands function. Using this wrapper function approach ensures
+ # that we only offer the user the hub subcommands when the user is
+ # actually trying to complete subcommands.
+ hub_commands=(
+ alias:'show shell instructions for wrapping git'
+ pull-request:'open a pull request on GitHub'
+ fork:'fork origin repo on GitHub'
+ create:'create new repo on GitHub for the current project'
+ browse:'browse the project on GitHub'
+ compare:'open GitHub compare view'
+ ci-status:'lookup commit in GitHub Status API'
+ )
+ _describe -t hub-commands 'hub command' hub_commands && ret=0
+
+ return ret
+ }
+}
+
+(( $+functions[__hub_setup_bash_fns] )) ||
+__hub_setup_bash_fns () {
+ # TODO more bash-style fns needed here to complete subcommand args. They take
+ # the form "_git_CMD" where "CMD" is something like "pull-request".
+
+ # Duplicate and rename the 'list_all_commands' function
+ eval "$(declare -f __git_list_all_commands | \
+ sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')"
+
+ # Wrap the 'list_all_commands' function with extra hub commands
+ __git_list_all_commands() {
+ cat <<-EOF
+alias
+pull-request
+fork
+create
+browse
+compare
+ci-status
+EOF
+ __git_list_all_commands_without_hub
+ }
+
+ # Ensure cached commands are cleared
+ __git_all_commands=""
+}
+
+# redefine _hub to a much smaller function in the steady state
+_hub () {
+ # only attempt to intercept the normal "_git" helper functions once
+ (( $+__hub_func_replacement_done )) ||
+ () {
+ # At this stage in the shell's execution the "_git" function has not yet
+ # been autoloaded, so the "_git_commands" or "__git_list_all_commands"
+ # functions will not be defined. Call it now (with a bogus no-op service
+ # to prevent premature completion) so that we can wrap them.
+ if declare -f _git >& /dev/null ; then
+ _hub_noop () { __hub_zsh_provided=1 } # zsh-provided will call this one
+ __hub_noop_main () { __hub_git_provided=1 } # git-provided will call this one
+ local service=hub_noop
+ _git
+ unfunction _hub_noop
+ unfunction __hub_noop_main
+ service=git
+ fi
+
+ if (( $__hub_zsh_provided )) ; then
+ __hub_setup_zsh_fns
+ elif (( $__hub_git_provided )) ; then
+ __hub_setup_bash_fns
+ fi
+
+ __hub_func_replacement_done=1
+ }
+
+ # Now perform the actual completion, allowing the "_git" function to call our
+ # replacement "_git_commands" function as needed. Both versions expect
+ # service=git or they will call nonexistent routines or end up in an infinite
+ # loop.
+ service=git
+ declare -f _git >& /dev/null && _git
+}
+
+# make sure we actually attempt to complete on the first "tab" from the user
+_hub
diff --git a/plugins/github/github.plugin.zsh b/plugins/github/github.plugin.zsh
index bd69b1bd5..ca19901fd 100644
--- a/plugins/github/github.plugin.zsh
+++ b/plugins/github/github.plugin.zsh
@@ -1,56 +1,25 @@
-# Setup hub function for git, if it is available; http://github.com/defunkt/hub
-if [ "$commands[(I)hub]" ] && [ "$commands[(I)ruby]" ]; then
- # Autoload _git completion functions
- if declare -f _git > /dev/null; then
- _git
- fi
-
- if declare -f _git_commands > /dev/null; then
- _hub_commands=(
- 'alias:show shell instructions for wrapping git'
- 'pull-request:open a pull request on GitHub'
- 'fork:fork origin repo on GitHub'
- 'create:create new repo on GitHub for the current project'
- 'browse:browse the project on GitHub'
- 'compare:open GitHub compare view'
- )
- # Extend the '_git_commands' function with hub commands
- eval "$(declare -f _git_commands | sed -e 's/base_commands=(/base_commands=(${_hub_commands} /')"
- fi
- # eval `hub alias -s zsh`
- function git(){
- if ! (( $+_has_working_hub )); then
- hub --version &> /dev/null
- _has_working_hub=$(($? == 0))
- fi
- if (( $_has_working_hub )) ; then
- hub "$@"
- else
- command git "$@"
- fi
- }
+# Set up hub wrapper for git, if it is available; http://github.com/github/hub
+if [ "$commands[(I)hub]" ]; then
+ if hub --version &>/dev/null; then
+ eval $(hub alias -s zsh)
+ fi
fi
# Functions #################################################################
-# https://github.com/dbb
+# Based on https://github.com/dbb/githome/blob/master/.config/zsh/functions
-
-# empty_gh [NAME_OF_REPO]
+# empty_gh <NAME_OF_REPO>
#
# Use this when creating a new repo from scratch.
+# Creates a new repo with a blank README.md in it and pushes it up to GitHub.
empty_gh() { # [NAME_OF_REPO]
- repo=$1
- ghuser=$( git config github.user )
+ emulate -L zsh
+ local repo=$1
- mkdir "$repo"
- cd "$repo"
- git init
- touch README
- git add README
- git commit -m 'Initial commit.'
- git remote add origin git@github.com:${ghuser}/${repo}.git
- git push -u origin master
+ mkdir "$repo"
+ touch "$repo/README.md"
+ new_gh "$repo"
}
# new_gh [DIRECTORY]
@@ -58,16 +27,25 @@ empty_gh() { # [NAME_OF_REPO]
# Use this when you have a directory that is not yet set up for git.
# This function will add all non-hidden files to git.
new_gh() { # [DIRECTORY]
- cd "$1"
- ghuser=$( git config github.user )
+ emulate -L zsh
+ local repo="$1"
+ cd "$repo" \
+ || return
- git init
- # add all non-dot files
- print '.*'"\n"'*~' >> .gitignore
- git add ^.*
- git commit -m 'Initial commit.'
- git remote add origin git@github.com:${ghuser}/${repo}.git
- git push -u origin master
+ git init \
+ || return
+ # add all non-dot files
+ print '.*'"\n"'*~' >> .gitignore
+ git add [^.]* \
+ || return
+ git add .gitignore \
+ || return
+ git commit -m 'Initial commit.' \
+ || return
+ hub create \
+ || return
+ git push -u origin master \
+ || return
}
# exist_gh [DIRECTORY]
@@ -75,13 +53,13 @@ new_gh() { # [DIRECTORY]
# Use this when you have a git repo that's ready to go and you want to add it
# to your GitHub.
exist_gh() { # [DIRECTORY]
- cd "$1"
- name=$( git config user.name )
- ghuser=$( git config github.user )
- repo=$1
+ emulate -L zsh
+ local repo=$1
+ cd "$repo"
- git remote add origin git@github.com:${ghuser}/${repo}.git
- git push -u origin master
+ hub create \
+ || return
+ git push -u origin master
}
# git.io "GitHub URL"
@@ -91,7 +69,10 @@ exist_gh() { # [DIRECTORY]
# source: https://github.com/nvogel/dotzsh
# documentation: https://github.com/blog/985-git-io-github-url-shortener
#
-git.io() {curl -i -s http://git.io -F "url=$1" | grep "Location" | cut -f 2 -d " "}
+git.io() {
+ emulate -L zsh
+ curl -i -s http://git.io -F "url=$1" | grep "Location" | cut -f 2 -d " "
+}
# End Functions #############################################################