[Home] Zsh logo

multicomp

Zsh Wizard

Download multicomp Return to Examples
  1. # multicomp() {
  2. # Completes all manner of files given prefixes for each path segment.
  3. # e.g. s/z/s -> src/zsh-2.4/src
  4. #
  5. # Usage: e.g.
  6. # compctl -D -f + -U -K multicomp
  7. #
  8. # Note that exactly matched directories are not expanded, e.g.
  9. # s/zsh-2.4/s<TAB> will not expand to src/zsh-2.4old/src.
  10. # Will expand glob patterns already in the word, but use complete-word,
  11. # not TAB (expand-or-complete), or you will get ordinary glob expansion.
  12. # Requires the -U option to compctl.
  13. # Menucompletion is highly recommended for ambiguous matches.
  14. # Liable to screw up escaped metacharacters royally.
  15. # $fignore is not used: feel free to add your own bit.
  16. local pref head sofar origtop newtop globdir="(-/)" wild
  17. setopt localoptions nullglob rcexpandparam globdots
  18. unsetopt markdirs globsubst shwordsplit
  19. pref="${1}$2"
  20. # Hack to allow programmable completion to select multicomp after a :
  21. # (e.g.
  22. # compctl -D -f -x 's[:]' -U -K multicomp
  23. # )
  24. pref="${pref#:}"
  25. sofar=('')
  26. reply=('')
  27. if [[ "$pref" = \~* ]]; then
  28. # If the string started with ~, save the head and what it will become.
  29. origtop="${pref%%/*}"
  30. newtop=${~origtop}
  31. # Save the expansion as the bit matched already
  32. sofar=($newtop)
  33. pref="${pref#$origtop}"
  34. fi
  35. while [[ -n "$pref" ]]; do
  36. [[ "$pref" = /* ]] && sofar=(${sofar}/) && pref="${pref#/}"
  37. head="${pref%%/*}"
  38. pref="${pref#$head}"
  39. if [[ -n "$pref" && -z $sofar[2] && -d "${sofar}$head" ]]; then
  40. # Exactly matched directory: don't try to glob
  41. reply=("${sofar}$head")
  42. else
  43. [[ -z "$pref" ]] && globdir=
  44. # if path segment contains wildcards, don't add another.
  45. if [[ "$head" = *[\*\?]* ]]; then
  46. wild=
  47. else
  48. wild='*'
  49. fi
  50. reply=(${sofar}"${head}${wild}${globdir}")
  51. reply=(${~reply})
  52. fi
  53. [[ -z $reply[1] ]] && reply=() && break
  54. [[ -n $pref ]] && sofar=($reply)
  55. done
  56. # Restore ~'s in front if there were any.
  57. # There had better not be anything funny in $newtop.
  58. [[ -n "$origtop" ]] && reply=("$origtop"${reply#$newtop})
  59. # }