#Stacked git bash completion. #TODO: # My opinion about bash completion is that they're excessively slow, especially # when the system is under load. # # So: # - save the list of stg commands in a file, created at install moment; on an # idle Athlon 64 laptop at 800MHz, stg help takes 0.22 seconds of CPU time, # without disk I/O. # # - read .git/patches/$branch/{applied,unapplied} directly instead of invoking # stg. # #XXX: must test for bash version, done in generic bash-completion and the #generic value can be seen from here, if we are included by the loop at the end #of /etc/bash_completion, i.e. if we're installed in /etc/bash-completion.d. # #Gentoo should be fixed to allow this. bashdefault="-o bashdefault" default="-o default" #XXX: not StGit specific, valid for git too. __git_refs() { for i in $(echo .git/refs/heads/*); do echo ${i#.git/refs/heads/} done for i in $(echo .git/refs/tags/*); do echo ${i#.git/refs/tags/} done echo HEAD } __stg_unapplied() { stg unapplied 2>/dev/null $@ } __stg_applied() { stg applied 2>/dev/null $@ } __stg_all_patches() { __stg_applied $@; __stg_unapplied $@ } #XXX: Find a better name for this. # __stg_all_patch_ranges() { __stg_all_patches $@|while read i; do echo $i/; done } __stg_top() { stg top 2>/dev/null $@ } __stg_branches() { #for i in $(compgen -f .git/patches/); do for i in $(echo .git/patches/*); do echo ${i#.git/patches/} done } _stg_range() { #Ugly - should return the result rather than set COMPREPLY. local cur=$1 patches=$2 if [ "${cur#*:}" != "${cur}" ]; then # Complete the 2nd range component, after ':'. COMPREPLY=( $(compgen -W "${patches}" -- ${cur#*:}) ) else COMPREPLY=( $(compgen -W "${patches}" -- $cur) ) fi } _stg () { local cur cmd cmds opts cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=() if [ $COMP_CWORD -eq 1 ]; then cmds=$(stg help|tail +4|awk '{print $1}') COMPREPLY=( $(compgen -W "${cmds}" -- $cur) ) else local cmd=${COMP_WORDS[1]} local prev=${COMP_WORDS[COMP_CWORD-1]} local o_help="-h --help" local o_branch="-b --branch" #XXX: Add -b support - pass "-b branch" to unapplied and applied. #This can be done by calling __stg_unapplied directly below #instead of setting patches here. #But: how to look for -b? I'm scared about looping over opts #(I don't like completions when they take so much time). case $cmd in push) if [ "$prev" = "-t" -o "$prev" = "--to" ]; then _stg_range "$cur" "$(__stg_unapplied)" # if [ "${cur#*:}" != "${cur}" ]; then # COMPREPLY=( $(compgen -W "$(__stg_unapplied)" -- ${cur#*:}) ) # else # COMPREPLY=( $(compgen -W "$(__stg_unapplied)" -- $cur) ) # fi else opts="-a --all -n --number -t --to --reverse --undo $o_help" COMPREPLY=( $(compgen -W "${opts} $(__stg_unapplied)" -- $cur) ) fi ;; pop) if [ "$prev" = "-t" -o "$prev" = "--to" ]; then COMPREPLY=( $(compgen -W "$(__stg_applied)" -- $cur) ) else opts="-a --all -n --number -t --to $o_help" COMPREPLY=( $(compgen -W "${opts}" -- $cur) ) fi ;; export) if [ "$prev" = "-r" -o "$prev" = "--range" ]; then _stg_range "$cur" "$(__stg_applied)" else opts="-n --numbered -d --diff -t --template -r --range \ $o_branch $o_help" COMPREPLY=( $(compgen $default -W "${opts}" -- $cur) ) fi ;; mail) if [ "$prev" = "-r" -o "$prev" = "--range" ]; then _stg_range "$cur" "$(__stg_applied)" # if [ "${cur#*:}" != "${cur}" ]; then # COMPREPLY=( $(compgen -W "$(__stg_applied)" -- ${cur#*:}) ) # else # COMPREPLY=( $(compgen -W "$(__stg_applied)" -- $cur) ) # fi else opts="-a --all -r --range --to --cc --bcc -v --version \ -t --template -f --first -s --sleep --refid -u --smtp-user \ -p --smtp-password $o_branch $o_help" COMPREPLY=( $(compgen $bashdefault -W "${opts} \ $(__stg_applied)" -- $cur) ) fi ;; diff) if [ "$prev" = "-r" ]; then if [ "${cur#*:}" != "${cur}" ]; then COMPREPLY=( $(compgen -W "$(__stg_all_patch_ranges)" -- \ ${cur#*:}) ) else COMPREPLY=( $(compgen -W "$(__stg_all_patch_ranges)" -- \ $cur) ) fi else opts="-r -s --stat $o_help" COMPREPLY=( $(compgen -W "${opts}" -- $cur) ) fi ;; id) if [ "$prev" = "-b" -o "$prev" = "--branch" ]; then COMPREPLY=( $(compgen -W "$(__stg_branches)" -- $cur) ) else opts="$o_branch $o_help" #there's a lot of possible id's to complete COMPREPLY=( $(compgen -W "${opts} $(__stg_all_patch_ranges) \ $(__git_refs)" -- $cur) ) fi ;; rename) if [ "$prev" = "-b" -o "$prev" = "--branch" ]; then COMPREPLY=( $(compgen -W "$(__stg_branches)" -- $cur) ) else COMPREPLY=( $(compgen -W "$(__stg_all_patches)" -- $cur) ) fi ;; delete) opts="${o_help}" COMPREPLY=( $(compgen -W "${opts} $(__stg_unapplied; __stg_top)" \ -- $cur) ) ;; series|unapplied|applied) if [ "$prev" = "-b" -o "$prev" = "--branch" ]; then COMPREPLY=( $(compgen -W "$(__stg_branches)" -- $cur) ) else opts="$o_branch $o_help" [ "$cmd" = "series" ] && \ opts="$opts -e --empty" COMPREPLY=( $(compgen -W "${opts}" -- $cur) ) fi ;; refresh) opts="-f --force -e --edit -s --showpatch -m --message \ -a --author --authname --authemail --authdate --commname --commemail $o_help" COMPREPLY=( $(compgen $bashdefault -W "${opts}" -- $cur) ) ;; *) COMPREPLY=( $(compgen $bashdefault -W "${o_help}" -f -- $cur) ) ;; esac fi } complete $default -F _stg stg # vi: set ft=sh sw=4: