[Bash-completion-devel] script to generate bash completions
Andreas Politz
politza at fh-trier.de
Tue Oct 28 03:29:06 UTC 2008
On Fri, 24 Oct 2008 19:12:01 +0200, Andreas Politz wrote:
> > David Paleino wrote:
>> > > On Mon, 20 Oct 2008 20:03:57 +0200, A.Politz wrote:
>>> > >> _dpkg_source contains a inappropriate exit statement, which forces
>>> > >> the shell to exit. I suppose this should be 'return' instead.
>>> > >>
>>> > >> Reproduce: Open a bash-shell , type '_dpkg_source<RET>'.
>> > >
>> > > Why are you calling _dpkg_source() directly?
>> > >
>> > > David
>> > >
> >
> > I have written a wrapper around bashs completion mechanism
> > in order to use it programatically.
Uhm, interesting. Would you please keep
<bash-completion-devel at lists.alioth.debian.org> informed?
It would be interesting to integrate what you're doing upstream. What are you
using to achieve that?
Hi, I am attaching the script here. It's working for my needs, but I doubt it
is fully compatible. Come to think about it, maybe it would be easier to
- patch bash so that it does not invalidate COMP_WORDS etc.
- or only wrap the -F argument and set them back up
I am not writing many shell scripts, this is probably painfull to read
for some people.
-ap
$ cat gencomp.bash
# if declare -f quote_readline > /dev/null; then
# quote_readline () { echo "$1" ; } ;
# fi;
gencomp ()
{
#gencomp 'apt-get ' | xargs -n1 -0
local IFS=$' \t\n';
COMPREPLY=();
COMP_LINE="$*";
COMP_POINT=${#COMP_LINE};
COMP_WORDS=($@);
COMP_CWORD=$((${#COMP_WORDS[@]} - 1));
local compfunc_args="";
local complete_cmd="";
local to_complete="";
local got_completion=0;
#complete options
local add_slash=0;
local f_arg=0;
local d_arg=0;
local plusdirs=0;
local prefix="";
local suffix="";
local filterpat="";
local psx_opts="";
local globpat="";
local action="";
local wordlist="";
local dirnames=0;
local default=0;
if [ $COMP_CWORD -ge 0 ] ;then
if [ "${COMP_LINE: -1:1}" == " " ] ;then
let ++COMP_CWORD ;
COMP_WORDS[$COMP_CWORD]="";
fi;
to_complete=${COMP_WORDS[@]: -1:1};
if [ $COMP_CWORD -gt 0 ] ;then
compfunc_args="${COMP_WORDS[0]} ${COMP_WORDS[$COMP_CWORD]}";
if [ $COMP_CWORD -gt 1 ];then
compfunc_args+=" ${COMP_WORDS[$(($COMP_CWORD - 1))]}";
fi;
complete_cmd=$(complete 2>/dev/null -p ${COMP_WORDS[0]});
fi;
fi;
if [ -n "$complete_cmd" ]; then
echo -ne "$complete_cmd\0";
eval "set $complete_cmd";
shift;
while [ $# -gt 1 ]; do
case $1 in
-F)
eval "$2 $compfunc_args";
shift ;;
-C)
shift ;;
-o)
case $2 in
filenames) add_slash=1 ;;
plusdirs) plusdirs=1 ;;
default|bashdefault) default=1;;
dirnames) dirnames=1;;
esac;
shift ;;
-A)
case $2 in
directory) d_arg=1 ;;
filenames) f_arg=1 ;;
*) action+="-A $2 ";
esac;
shift ;;
-[abceghjksouv])
action+="$1 " ;;
-f)
f_arg=1 ;;
-d)
d_arg=1;;
-G)
globpat="-G $2";
shift ;;
-W)
wordlist="-W $2";
shift ;;
-P)
prefix="-P $2 ";
shift ;;
-S)
suffix="-S $2 ";
shift ;;
-X)
filterpat="-X $2 ";
shift ;;
esac;
shift;
done;
psx_opts="$prefix$suffix$filterpat";
got_completion=${#COMPREPLY[*]};
eval "compgen $action $globpat $wordlist $suffix $prefix $filterpat -- \"$to_complete\"" | gencomp_echo $(test $add_slash -ne 0);
IFS=$'\n';
if [ -n "$psx_opts" ] ;then
eval "compgen -W'\${COMPREPLY[*]}' $suffix $prefix $filterpat" | gencomp_echo $(test $add_slash -ne 0);
else
echo "${COMPREPLY[*]}" | gencomp_echo $(test $add_slash -ne 0);
fi;
IFS=$' \t\n';
if [ $f_arg -ne 0 ] ; then
eval "compgen -f $suffix $prefix $filterpat -- \"$to_complete\"" | gencomp_echo "add_slash";
elif [ $d_arg -ne 0 ] ;then
eval "compgen -d $suffix $prefix $filterpat -- \"$to_complete\"" | gencomp_echo "add_slash";
fi;
if [ $plusdirs -ne 0 ] ;then
compgen -d -- "$to_complete" | gencomp_echo "add_slash" ;
fi;
if [ $got_completion -eq 0 ] ;then
if [ 0 -ne $dirnames ] ;then
compgen -d -- "$to_complete" | gencomp_echo "add_slash";
elif [ 0 -ne $default ] ;then
compgen -f -- "$to_complete" | gencomp_echo "add_slash" ;
fi;
fi;
else
echo -ne "no complete definition\0";
if [ 0 -eq $COMP_CWORD ]; then
compgen -A alias -A enabled -A command -A function -- "$to_complete" | gencomp_echo;
elif [ $COMP_CWORD -gt 0 ] && [ "${to_complete:0:1}" == "$" ]; then
compgen -P'$' -v -- "${to_complete:1}" | gencomp_echo;
elif [ $COMP_CWORD -gt 0 ]; then
compgen -f -- "$to_complete" | gencomp_echo "add_slash";
fi;
fi;
return 0;
} ;
gencomp_echo ()
{
while read comp; do
if $1 && [ -d "$comp" ] && [ "${comp: -1:1}" != "/" ] ; then
echo -ne "$comp/\0";
else
echo -ne "$comp\0";
fi;
got_completion=1;
done;
} ;
More information about the Bash-completion-devel
mailing list