# -*-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 () { chomp; if (s/\\$//) { $_ .= ; 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() { 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