blob: 8d49e218097bf17ab6c1f3a1d588c745d10c0c2b [file] [log] [blame]
# bash completion support for StGIT -*- shell-script -*-
#
# Copyright (C) 2006, Karl Hasselström <kha@treskal.com>
# Based on git-completion.sh
#
# To use these routines:
#
# 1. Copy this file to somewhere (e.g. ~/.stgit-completion.bash).
#
# 2. Add the following line to your .bashrc:
# . ~/.stgit-completion.bash
_stg_commands="
add
applied
branch
delete
diff
clean
clone
commit
cp
edit
export
files
float
fold
goto
hide
id
import
init
log
mail
new
patches
pick
pop
pull
push
rebase
refresh
rename
repair
resolved
rm
series
show
sink
status
sync
top
unapplied
uncommit
unhide
"
# The path to .git, or empty if we're not in a repository.
_gitdir ()
{
echo "$(git rev-parse --git-dir 2>/dev/null)"
}
# Name of the current branch, or empty if there isn't one.
_current_branch ()
{
local b=$(git symbolic-ref HEAD 2>/dev/null)
echo ${b#refs/heads/}
}
# List of all applied patches.
_applied_patches ()
{
local g=$(_gitdir)
[ "$g" ] && cat "$g/patches/$(_current_branch)/applied"
}
# List of all unapplied patches.
_unapplied_patches ()
{
local g=$(_gitdir)
[ "$g" ] && cat "$g/patches/$(_current_branch)/unapplied"
}
# List of all applied patches.
_hidden_patches ()
{
local g=$(_gitdir)
[ "$g" ] && cat "$g/patches/$(_current_branch)/hidden"
}
# List of all patches.
_all_patches ()
{
local b=$(_current_branch)
local g=$(_gitdir)
[ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied"
}
# List of all patches except the current patch.
_all_other_patches ()
{
local b=$(_current_branch)
local g=$(_gitdir)
[ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied" \
| grep -v "^$(cat $g/patches/$b/current 2> /dev/null)$"
}
_all_branches ()
{
local g=$(_gitdir)
[ "$g" ] && (cd $g/patches/ && echo *)
}
_conflicting_files ()
{
local g=$(_gitdir)
[ "$g" ] && stg status --conflict
}
_dirty_files ()
{
local g=$(_gitdir)
[ "$g" ] && stg status --modified --new --deleted
}
_unknown_files ()
{
local g=$(_gitdir)
[ "$g" ] && stg status --unknown
}
_known_files ()
{
local g=$(_gitdir)
[ "$g" ] && git ls-files
}
# List the command options
_cmd_options ()
{
stg $1 --help 2>/dev/null | grep -e " --[A-Za-z]" | sed -e "s/.*\(--[^ =]\+\).*/\1/"
}
# Generate completions for patches and patch ranges from the given
# patch list function, and options from the given list.
_complete_patch_range ()
{
local patchlist="$1" options="$2"
local pfx cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
*..*)
pfx="${cur%..*}.."
cur="${cur#*..}"
COMPREPLY=($(compgen -P "$pfx" -W "$($patchlist)" -- "$cur"))
;;
*)
COMPREPLY=($(compgen -W "$options $($patchlist)" -- "$cur"))
;;
esac
}
_complete_patch_range_options ()
{
local patchlist="$1" options="$2" patch_options="$3"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local cur="${COMP_WORDS[COMP_CWORD]}"
local popt
for popt in $patch_options; do
if [ $prev == $popt ]; then
_complete_patch_range $patchlist
return
fi
done
COMPREPLY=($(compgen -W "$options" -- "$cur"))
}
_complete_branch ()
{
COMPREPLY=($(compgen -W "$(_cmd_options $1) $($2)" -- "${COMP_WORDS[COMP_CWORD]}"))
}
# Generate completions for options from the given list.
_complete_options ()
{
local options="$1"
COMPREPLY=($(compgen -W "$options" -- "${COMP_WORDS[COMP_CWORD]}"))
}
_complete_files ()
{
COMPREPLY=($(compgen -W "$(_cmd_options $1) $2" -- "${COMP_WORDS[COMP_CWORD]}"))
}
_stg_common ()
{
_complete_options "$(_cmd_options $1)"
}
_stg_patches ()
{
_complete_patch_range "$2" "$(_cmd_options $1)"
}
_stg_patches_options ()
{
_complete_patch_range_options "$2" "$(_cmd_options $1)" "$3"
}
_stg_help ()
{
_complete_options "$_stg_commands"
}
_stg ()
{
local i c=1 command
while [ $c -lt $COMP_CWORD ]; do
if [ $c == 1 ]; then
command="${COMP_WORDS[c]}"
fi
c=$((++c))
done
# Complete name of subcommand.
if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
COMPREPLY=($(compgen \
-W "--help --version copyright help $_stg_commands" \
-- "${COMP_WORDS[COMP_CWORD]}"))
return;
fi
# Complete arguments to subcommands.
case "$command" in
# generic commands
help) _stg_help ;;
# repository commands
id) _stg_patches $command _all_patches ;;
# stack commands
float) _stg_patches $command _all_patches ;;
goto) _stg_patches $command _all_other_patches ;;
hide) _stg_patches $command _unapplied_patches ;;
pop) _stg_patches $command _applied_patches ;;
push) _stg_patches $command _unapplied_patches ;;
series) _stg_patches $command _all_patches ;;
sink) _stg_patches $command _all_patches ;;
unhide) _stg_patches $command _hidden_patches ;;
# patch commands
delete) _stg_patches $command _all_patches ;;
edit) _stg_patches $command _applied_patches ;;
export) _stg_patches $command _all_patches ;;
files) _stg_patches $command _all_patches ;;
log) _stg_patches $command _all_patches ;;
mail) _stg_patches $command _all_patches ;;
pick) _stg_patches $command _unapplied_patches ;;
# refresh)_stg_patches_options $command _applied_patches "-p --patch" ;;
refresh) _complete_files $command "$(_dirty_files)" ;;
rename) _stg_patches $command _all_patches ;;
show) _stg_patches $command _all_patches ;;
sync) _stg_patches $command _applied_patches ;;
# working-copy commands
diff) _stg_patches_options $command _applied_patches "-r --range" ;;
resolved) _complete_files $command "$(_conflicting_files)" ;;
add) _complete_files $command "$(_unknown_files)" ;;
# rm) _complete_files $command "$(_known_files)" ;;
# commands that usually raher accept branches
branch) _complete_branch $command _all_branches ;;
rebase) _complete_branch $command _all_branches ;;
# all the other commands
*) _stg_common $command ;;
esac
}
complete -o default -F _stg stg