diff --git a/modules/completion/external b/modules/completion/external index 68c94947..fb1bf123 160000 --- a/modules/completion/external +++ b/modules/completion/external @@ -1 +1 @@ -Subproject commit 68c949470eaa87c5d67080d32fb2b69c8b837eb4 +Subproject commit fb1bf123198bef4710aafc7d59cce4e2e0a3dd20 diff --git a/modules/completion/hub/_hub b/modules/completion/hub/_hub new file mode 100644 index 00000000..df09ace1 --- /dev/null +++ b/modules/completion/hub/_hub @@ -0,0 +1,160 @@ +#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]' \ + - 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/modules/completion/init.zsh b/modules/completion/init.zsh index 023a90e7..e1b72fca 100644 --- a/modules/completion/init.zsh +++ b/modules/completion/init.zsh @@ -13,6 +13,7 @@ fi # Add zsh-completions to $fpath. fpath=("${0:h}/external/src" $fpath) +fpath=("${0:h}/hub" $fpath) # Load and initialize the completion system ignoring insecure directories. autoload -Uz compinit && compinit -i diff --git a/modules/prompt/functions/prompt_epiloque_setup b/modules/prompt/functions/prompt_epiloque_setup new file mode 100644 index 00000000..37967066 --- /dev/null +++ b/modules/prompt/functions/prompt_epiloque_setup @@ -0,0 +1,92 @@ +# +# A simple theme that displays only relevant information. +# +# Authors: +# Julien Nicoulaud +# Sorin Ionescu +# Mark Milstein +# +# Features: +# - One line. +# - VCS information in the right prompt. +# - Only shows the path on the left prompt by default. +# - Crops the path to a defined length and only shows the path relative to +# the current VCS repository root. +# - Uses a different color depending on if the last command succeeded/failed. +# - Shows user@hostname if connected through SSH. +# - Shows if logged in as root or not. +# +# Screenshots: +# http://i.imgur.com/Xe1bu.png +# +# 16 Terminal Colors +# -- --------------- +# 0 black +# 1 red +# 2 green +# 3 yellow +# 4 blue +# 5 magenta +# 6 cyan +# 7 white +# 8 bright black +# 9 bright red +# 10 bright green +# 11 bright yellow +# 12 bright blue +# 13 bright magenta +# 14 bright cyan +# 15 bright white +# +function prompt_epiloque_pwd { + local pwd="${PWD/#$HOME/~}" + + if [[ "$pwd" == (#m)[/~] ]]; then + _prompt_epiloque_pwd="$MATCH" + unset MATCH + else + _prompt_epiloque_pwd="${${${${(@j:/:M)${(@s:/:)pwd}##.#?}:h}%/}//\%/%%}/${${pwd:t}//\%/%%} " + fi +} + +function prompt_epiloque_precmd { + prompt_epiloque_pwd + vcs_info +} + +function prompt_epiloque_setup { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + prompt_opts=(cr percent subst) + + # Load required functions. + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + # Add hook for calling vcs_info before each command. + add-zsh-hook precmd prompt_epiloque_precmd + + # Customizable parameters. + local max_path_chars=30 + local user_char='%F{11}❯❯❯' + local root_char='%F{11}❯❯❯❯' + local success_color='%F{15}' + local failure_color='%F{8}' + local vcs_info_color='%F{15}' + + # Set vcs_info parameters. + zstyle ':vcs_info:*' enable bzr git hg svn + zstyle ':vcs_info:*' check-for-changes true + zstyle ':vcs_info:*' unstagedstr '!' + zstyle ':vcs_info:*' stagedstr '+' + zstyle ':vcs_info:*' actionformats "%S" "%r/%s/%b %u%c (%a)" + zstyle ':vcs_info:*' formats "%S" "%r/%s/%b %u%c" + zstyle ':vcs_info:*' nvcsformats "%~" "" + + # Define prompts. + PROMPT="%(?.${success_color}.${failure_color})${SSH_TTY:+%n@%m }%B%${max_path_chars}<...<"'${_prompt_epiloque_pwd}'"%<<%(!.${root_char}.${user_char})%b%f " + RPROMPT="${vcs_info_color}"'${vcs_info_msg_1_}'"%f" + SPROMPT='zsh: correct %F{1}%R%f to %F{2}%r%f [nyae]? ' +} + +prompt_epiloque_setup "$@"