diff --git a/README.md b/README.md index f29a6da..3b65aab 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,11 @@ The file format is as follows: ``` KEY COMPLETION :CMD +KEY COMPLETION |CMD KEY COMPLETION CMD ``` -If `CMD` contains a `:` prefix, the command will be prefixed with `git`. +If `CMD` contains a colon (`:`) prefix, the command will be prefixed with `git`. If +prefixed with a pipe (`|`), the command will be sent to `eval` (needed for +certain features like subshells). Commands without either prefix will be +executed normally. diff --git a/bash_completion b/bash_completion index a432cca..1575ae1 100644 --- a/bash_completion +++ b/bash_completion @@ -18,6 +18,9 @@ __git-short_docomplete () { + # ignore problem commands + grep -q '^-' <<< "$1" && return + complete -o bashdefault -o default -o nospace -F $2 $1 2>/dev/null \ || complete -o default -o nospace -F $2 $1 } @@ -32,21 +35,47 @@ __git-short_shortmap () $( awk "/^$1 / { print \$2 }" <<< "$__git_short_maps" ) } +__git-short_register_alias () +{ + # ignore invalid aliases (for which we define functions to handle them + # instead) + grep -q '^-' <<< "$1" && return + + alias $1="__git-short_shortalias $1" +} + __git-short_shortalias () { - cmd=$1 + shortcmd=$1 shift # if we're not within a git dir, fall back to an actual command of this name __gitdir >/dev/null || { - " $cmd $@" + " $shortcmd $@" return $? } # execute the command - $( grep "^$cmd" <<< "$__git_short_maps" | cut -d' ' -f3- ) "$@" + cmd="$( grep "^$shortcmd " <<< "$__git_short_maps" | cut -d' ' -f3- )" + if [ -z "$cmd" ]; then + return + elif [ "$( grep '^|' <<< "$cmd")" ]; then + eval "$( sed 's/^|//' <<< "$cmd" ) $@" + return $? + fi + + $cmd "$@" } +# functions that cannot be aliased +- () +{ + __git-short_shortalias - "$@" +} +-- () +{ + __git-short_shortalias -- "$@" +} # load shortmaps from cwd (or provided path) and home dir (if available) __git_short_maps=$( @@ -54,6 +83,7 @@ __git_short_maps=$( | sed 's/^\([^ ]\+ [^ ]\+\) :/\1 git /' ) + # register each shortmap IFS=$'\n' for line in $__git_short_maps; do @@ -63,5 +93,6 @@ for line in $__git_short_maps; do [ -z "$1" ] && continue __git-short_docomplete "$1" __git-short_shortmap - alias $1="__git-short_shortalias $1" + __git-short_docomplete "$1" __git-short_shortmap + __git-short_register_alias "$1" done diff --git a/shortmaps b/shortmaps index e98afbf..483f547 100644 --- a/shortmaps +++ b/shortmaps @@ -12,3 +12,5 @@ s _git_status :status S _git_stash :stash t void tig T _git_tag :tag +- void :checkout - +-- void |cd "$( git rev-parse --git-dir 2>/dev/null )/../"