#  -*-cperl-*-
#
#	Psh Programmable Completion Example
#
#		by hiroo.hayashi@computer.org

#
# Some nice stuff
#

complete -W '-daystart -depth -follow -help -mount -cnewer -ctime -gid -name -iname -newer -path -regex -type -exec -print' find

#
# Emulation of bash-2.04-beta5/examples/complete/complete-examples
#

#
# Completion examples
#

#
# This encapsulates the default bash completion code
# call with the word to be completed as $1
#
# Since programmable completion does not use the bash default completions
# or the readline default of filename completion when the compspec does
# not generate any matches, this may be used as a 'last resort' in a ##''
# completion function to mimic the default bash completion behavior.
#
sub _psh_def_completion {
    my ($cur, $line, $start, $cmd) = @_;

    # command substitution
    if ($cur =~ /\s*`\s*(\S*)/) {
	return compgen('-c', '-P', '`', $1);
    }
    # scalar variables with a leading '$' ##''
    if ($cur =~ /^\$(.*)/) {
	return compgen('-v', '-P', '$', $1);
    }
    # array variables or hostname with a leading '@' ##''
    if ($cur =~ /^@(.*)/) {
	if (substr($line, 0, $start) =~ /\S$/) {
	    return compgen('-A', 'hostname', '-P', '@', $1);
	} else {
	    return compgen('-A', 'arrayvar', '-P', '@', $1);
	}
    }
    # hash variables with a leading '%' ##''
    if ($cur =~ /^%(.*)/) {
	return compgen('-A', 'hashvar', '-P', '%', $1);
    }
    # perl function with a leading '&' ##''
    if ($cur =~ /^&(.*)/) {
	return compgen('-A', 'function', '-P', '&', $1);
    }
    # username expansion
    if ($cur =~ m|^~([^/]*)|) {
	return compgen('-u', '-P', '~', $1);
    }
    # glob pattern
    if (# sh-style glob pattern
	$cur =~ /[*?[]/
	# ksh-style extended glob pattern - must be complete
	|| $cur =~ /[?*+\!@]\(.*\)/) {
	return compgen('-G', $cur);
    }
    # final default is filename completion
    return compgen('-f', $cur);
}

#
# Easy ones for the shell builtins
#
# nothing for: alias, break, continue, dirs, echo, eval, exit, getopts,
# let, logout, popd, printf, pwd, return, shift, suspend, test, times,
# umask
#

#complete -f -- . source
#complete -A enabled builtin
#complete -d cd

# this isn't exactly right yet -- needs to skip shell functions and ##'
# do $PATH lookup (or do compgen -c and filter out matches that also
# appear in compgen -A function)
complete -c command

# could add -S '=', but that currently screws up because readline appends
# a space unconditionally

#complete -v export local readonly
#complete -A helptopic help	# currently same as builtins

complete -c type which

complete -a unalias
#complete -v unset 

#
# Job control builtins: fg, bg, disown, kill, wait
# kill not done yet
#

# I need to know how these commands of psh work more.  FIXIT!!!
complete -A stopped -P % bg
complete -j -P % fg jobs disown

# this is not quite right at this point
# need a way to get output of builtin --- FIXIT!!!
sub _wait_func {
    my ($cur, $line, $start, $cmd) = @_;

    if ($cur =~ /^%/) {
  	return compgen(qw(-A running -P %), substr($cur,1));
    } elsif ($cur =~ /^[0-9]/) {
  	return grep(/^$cur/, `jobs -p`);
    } else {
  	return compgen(qw(-A running -P %), `jobs -p`);
    }
}
complete -F _wait_func wait

#
# some completions for shell reserved words
#
#complete -c -k time do if then else elif '{'

#
# external commands
#

complete -e printenv

complete -c nohup exec nice eval trace truss strace sotruss gdb

sub _make_targets {
    my ($cur, $line, $start, $cmd) = @_;
    
    # if prev argument is -f, return possible filename completions.
    # we could be a little smarter here and return matches against
    # 'makefile Makefile *.mk', whatever exists ##''
    my ($prev) = substr($line, 0, $start) =~ /(\S+)\s+$/;
    if ($prev =~ /^-.*f$/) {
	return compgen('-f', $cur);
    }
    
    # if we want an option, return the possible posix options
    if ($cur eq '-') {
	return qw(-e -f -i -k -n -p -q -r -S -s -t);
    }
    
    # before we scan for targets, see if a makefile name was specified
    # with -f
    my ($makef) = $line =~ /\s+-\S*f\s+(\S+)/;
    
    if (! defined $makef) {
	# make reads 'makefile' before 'Makefile'
	if (-f 'GNUmakefile') {
	    $makef = 'GNUmakefile';
	} elsif (-f 'makefile') {
	    $makef = 'makefile';
	} elsif (-f 'Makefile') {
	    $makef = 'Makefile';
	}
    }
    
    # return empty list unless Makefile exists
    return () unless -f $makef;
    
    open(MAKEFILE, $makef) or (warn("cannot open $makef:$!\n"), return ());
    my @COMPREPLY;
    while (<MAKEFILE>) {
	chomp;
	if (s/\\$//) {
	    $_ .= <MAKEFILE>;
	    redo;
	}
	if (/^([^#\s][^=:]*):/) {
	    push(@COMPREPLY, split(' ', $1)); # multi target
	}
    }
    close(MAKEFILE);
    return @COMPREPLY;
}
complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake

sub _umount_func {
#    return map { chomp, $_ } `mount|awk \'{print \$1}\'`;
    open(MOUNT, "mount |") or (warn("cannot exec mount:$!\n"), return ());
    my @COMPREPLY;
    while(<MOUNT>) {
	push(@COMPREPLY, (split(' '))[0]);
    }
    close(MOUNT);
    return @COMPREPLY;
}
complete -F _umount_func umount mount

sub _configure_func {
    my ($cur, $line, $start, $cmd) = @_;

    return () unless $cur =~ /^-/;

    ($cmd) = $line =~ /^\s*(\S+)/;
    return map { chomp, $_ } `"$cmd" --help | awk \'{if (\$1 ~ /--.*/) print \$1}\' | grep ^"$cur" | sort -u`;
}
complete -F _configure_func configure

#complete -W '"${GROUPS[@]}"' newgrp
#complete -W `id --groups --name` newgrp
sub _groups_func {
    return split ' ', `id --groups --name`;
}
complete -F _groups_func newgrp

complete -f chown ln more cat
complete -d mkdir rmdir
complete -f strip

complete -f -x '*.gz' gzip
complete -f -x '*.Z' compress
complete -f -x '!*.+(gz|tgz|Gz)' gunzip gzcat zcat zmore
complete -f -x '!*.Z' uncompress zmore zcat

complete -f -x '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' xv

#complete -f -x '!*.pl' perl perl5

complete -A hostname rxterm rxterm3 rxvt2

complete -u su

complete -f -x '!*.+(ps|PS)' gs gv ghostview psselect pswrap
complete -f -x '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype
complete -f -x '!*.+(pdf|PDF)' acroread
complete -f -x '!*.texi*' makeinfo texi2dvi texi2html
complete -f -x '!*.+(tex|TEX)' tex latex slitex
