Hi,
I’m attaching a bash completion script which performs completion for many, but
not all options and commands.
Specifically, it autocompletes the most common subcommands, but only provides
arguments autocompletion for only two of them, import-dsc and rpush, for
practical reasons.
For dgit options, it provides two-level completion for the most popular options,
excluding rarely used or dangerous ("use when you know what you’re doing")
options.
The two-levels work in a way to not overwhelm the user with options when they
Tab
twice, so only some but not all arguments to e.g. --quilt= are shown:
$ dgit --
--baredebian --force-import-gitapply-no-absurd
--baredebian+git --force-reusing-version
--baredebian+tarball --force-unrepresentable
--build-products-dir= --force-unsupported-source-format
--clean --force-uploading-binaries
--clean=dpkg-source --force-uploading-source-only
--clean=git --gbp
--clean=git-ff --include-dirty
--damp-run --new
--delayed= --no-rm-on-error
--deliberately-fresh-repo --no-sign
--deliberately-include-questionable-history --overwrite
--deliberately-not-fast-forward --package
--dep14tag --quilt
--distro= --quilt=auto
--dpm --quilt=linear
--dry-run --rm-old-changes
--force-changes-origs-exactly --save-dgit-view=
--force-dsc-changes-mismatch --split-view=
--force-import-dsc-with-dgit-field --upstream-commitish=
--force-import-gitapply-absurd
However, when the user types --quilt=, the rest of them is shown:
$ dgit --quilt=
auto baredebian+git dpm linear nofix unapplied
baredebian baredebian+tarball gbp nocheck smash
For --upstream-commitish= the script autocompletes some tags, starting with tags
with the matching version, and the rest sorted by version:
$ dgit --upstream-commitish=upstream/1.
upstream/1.11.0 upstream/1.6.0
For options accepting both = and space (--quilt, --clean, --package) the
completion
is performed for both versions; the list of all options above shows the
"spaced" (--clean)
version and a couple of commonly used versions with = and an argument. For
options
only accepting =, the option ends with = to allow the user to start typing the
argument
directly after that.
--
Cheers,
Andrej
# /usr/share/bash-completion/completions/dgit
# Bash command completion for ‘dgit(1)’.
# Documentation: ‘bash(1)’, section “Programmable Completion”.
# Author: Andrej Shadura <[email protected]>
# This file is in public domain when available or, alternatively,
# can be redistributed under the terms of CC0 1.0 Universal license.
# On Debian systems, the text of CC0 1.0 Universal can be found at
# /usr/share/common-licenses/CC0-1.0
_dgit()
{
local cur prev words cword i _options special _prefix
_init_completion -n = || return
local clean_opts=(git{,\,always} git-ff{,\,always} check{,\,ignores} none
dpkg-source{,\,no-check,\,all-check}
dpkg-source-d{,\,no-check,\,all-check})
local clean_popular_opts=(git git-ff dpkg-source)
local standalone_quilt_opts=(gbp dpm baredebian{,+git,+tarball})
local quilt_opts=(linear auto smash nofix nocheck unapplied
${standalone_quilt_opts[@]})
local quilt_popular_opts=(auto linear)
local force_opts=(unrepresentable unsupported-source-format
dsc-changes-mismatch
changes-origs-exactly uploading-binaries uploading-source-only
reusing-version import-gitapply-absurd import-gitapply-no-absurd
import-dsc-with-dgit-field)
local buildcommands="build sbuild gbp-build build-source pbuilder
cowbuilder"
local subcommands="clone fetch pull $buildcommands
push push-source rpush setup-new-tree setup-useremail
setup-mergechangelogs setup-gitattributes import-dsc update-vcs-git"
for word in ${words[@]}
do
if [[ $word == @(${subcommands// /|}) ]]
then
special=$word
break
fi
done
if [ -n "$special" ] && [[ $special == @(${buildcommands// /|}) ]]
then
COMPREPLY=()
return 0
fi
case "$prev" in
--clean)
COMPREPLY=($(compgen -W "${clean_opts[*]}" -- "$cur"))
return 0
;;
--quilt)
COMPREPLY=($(compgen -W "${quilt_opts[*]}" -- "$cur"))
return 0
;;
--build-products-dir)
COMPREPLY=($(compgen -o filenames -d -- "$cur"))
return 0
;;
-p|--package)
COMPREPLY=()
return 0
;;
-k)
COMPREPLY=($(compgen -W "$(gpg --list-secret-keys --with-colons |
grep ^sec | cut -d: -f5)" -- "$cur"))
return 0
;;
import-dsc)
COMPREPLY=($(compgen -o filenames -f -G '../*.dsc' -- "$cur"))
return 0
;;
rpush)
_known_hosts_real -c -a -- "$cur"
compopt -o nospace
return 0
;;
esac
case "$cur" in
--clean=*)
COMPREPLY=($(compgen -W "${clean_opts[*]}" -- "${cur#*=}"))
return 0
;;
--quilt=*)
COMPREPLY=($(compgen -W "${quilt_opts[*]}" -- "${cur#*=}"))
return 0
;;
--split-view=*)
COMPREPLY=($(compgen -W "auto always never" -- "${cur#*=}"))
return 0
;;
--build-products-dir=*)
COMPREPLY=($(compgen -o filenames -d -- "${cur#*=}"))
return 0
;;
--upstream-commitish=*)
local version=$( (dpkg-parsechangelog -SVersion 2>/dev/null ||
true) | sed -e 's/-[^-]*$//' -e 's/^[0-9]*://')
local thesetags=$([ -n "$version" ] && git tag --list "$version"
"v$version" "upstream/$version" 2>/dev/null || true)
local othertags=$( (git tag --list --sort version:refname '[0-9]*'
'v[0-9]*' 'upstream/[0-9]*' 2>/dev/null || true) | grep -v -F "$version")
COMPREPLY=($(compgen -W "$thesetags $othertags" -- "${cur#*=}"))
compopt -o nosort
return 0
;;
--*=*)
COMPREPLY=()
return 0
;;
esac
if [[ "$cur" == -* ]]; then
_options="--dry-run --damp-run --no-sign --new --include-dirty"
_options+=" --overwrite --delayed= --save-dgit-view="
_options+=" --deliberately-not-fast-forward"
_options+=" --deliberately-include-questionable-history"
_options+=" --deliberately-fresh-repo"
_options+=" --distro= --split-view= --upstream-commitish="
_options+=" --rm-old-changes --build-products-dir="
_options+=" --package -p --dep14tag --no-rm-on-error -k"
_options+=" --clean ${clean_popular_opts[*]/#/--clean=}"
_options+=" ${standalone_quilt_opts[*]/#/--}"
_options+=" --quilt ${quilt_popular_opts[*]/#/--quilt=}"
_options+=" ${force_opts[*]/#/--force-}"
COMPREPLY=($(compgen -W "${_options}" -- "$cur"))
# tell bash to not put a space afrer options ending with =
# so that the user can type the argument directly after it
if [ ${#COMPREPLY[@]} = 1 ] && [[ "${COMPREPLY[0]}" == *= ]]
then
compopt -o nospace
fi
else
if [ -z "$special" ]
then
COMPREPLY=($(compgen -W "$subcommands" -- "$cur"))
else
# if nothing explicitly handled these commands above,
# just don’t autocomplete at all
COMPREPLY=()
fi
fi
return 0
} &&
complete -F _dgit dgit
# vim: fileencoding=utf-8 filetype=sh expandtab shiftwidth=4 :