# multicomp() { # Completes all manner of files given prefixes for each path segment. # e.g. s/z/s -> src/zsh-2.4/src # # Usage: e.g. # compctl -D -f + -U -K multicomp # # Note that exactly matched directories are not expanded, e.g. # s/zsh-2.4/s will not expand to src/zsh-2.4old/src. # Will expand glob patterns already in the word, but use complete-word, # not TAB (expand-or-complete), or you will get ordinary glob expansion. # Requires the -U option to compctl. # Menucompletion is highly recommended for ambiguous matches. # Liable to screw up escaped metacharacters royally. # $fignore is not used: feel free to add your own bit. local pref head sofar origtop newtop globdir="(-/)" wild setopt localoptions nullglob rcexpandparam globdots unsetopt markdirs globsubst shwordsplit pref="${1}$2" # Hack to allow programmable completion to select multicomp after a : # (e.g. # compctl -D -f -x 's[:]' -U -K multicomp # ) pref="${pref#:}" sofar=('') reply=('') if [[ "$pref" = \~* ]]; then # If the string started with ~, save the head and what it will become. origtop="${pref%%/*}" newtop=${~origtop} # Save the expansion as the bit matched already sofar=($newtop) pref="${pref#$origtop}" fi while [[ -n "$pref" ]]; do [[ "$pref" = /* ]] && sofar=(${sofar}/) && pref="${pref#/}" head="${pref%%/*}" pref="${pref#$head}" if [[ -n "$pref" && -z $sofar[2] && -d "${sofar}$head" ]]; then # Exactly matched directory: don't try to glob reply=("${sofar}$head") else [[ -z "$pref" ]] && globdir= # if path segment contains wildcards, don't add another. if [[ "$head" = *[\*\?]* ]]; then wild= else wild='*' fi reply=(${sofar}"${head}${wild}${globdir}") reply=(${~reply}) fi [[ -z $reply[1] ]] && reply=() && break [[ -n $pref ]] && sofar=($reply) done # Restore ~'s in front if there were any. # There had better not be anything funny in $newtop. [[ -n "$origtop" ]] && reply=("$origtop"${reply#$newtop}) # }