[Home] Zsh logo

compctl-examples

Zsh Wizard

Download compctl-examples Return to Examples
  1. #
  2. # This file gives examples of possible programmable completions (compctl).
  3. # You can either put the compctl commands in your .zshrc file, or put them
  4. # in a separate file (say .zcompctl) and source it from your .zshrc file.
  5. #
  6. # These are just examples. Use and modify to personal taste. Copying
  7. # this file without thought will needlessly increase zsh's memory usage
  8. # and startup time.
  9. #
  10. # For a detailed description of how these work, check the zshcompctl man
  11. # page.
  12. #
  13. #------------------------------------------------------------------------------
  14. hosts=( ${(s: :)${(ps:\t:)${${(f)"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}} )
  15. ports=( "${(@)${(@)${(@f)$(</etc/services)}:#\#*}%%[ ]*}" )
  16. # groups=( $(cut -d: -f1 /etc/group) )
  17. # groups=( $(ypcat group.byname | cut -d: -f1) ) # if you use NIS
  18. # It can be done without forking, but it used too much memory in old zsh's:
  19. groups=( ${${(s: :)$(</etc/group)}%%:*} )
  20. #groups=( ${${(s: :)$(ypcat groups)}%%:*} ) # if you use NIS
  21. # Completion for zsh builtins.
  22. compctl -z -P '%' bg
  23. compctl -j -P '%' fg jobs disown
  24. compctl -j -P '%' + -s '`ps -x | tail +2 | cut -c1-5`' wait
  25. compctl -A shift
  26. compctl -c type whence where which
  27. compctl -m -x 'W[1,-*d*]' -n - 'W[1,-*a*]' -a - 'W[1,-*f*]' -F -- unhash
  28. compctl -m -q -S '=' -x 'W[1,-*d*] n[1,=]' -/ - \
  29. 'W[1,-*d*]' -n -q -S '=' - 'n[1,=]' -/g '*(*)' -- hash
  30. compctl -F functions unfunction
  31. compctl -k '(al dc dl do le up al bl cd ce cl cr
  32. dc dl do ho is le ma nd nl se so up)' echotc
  33. compctl -a unalias
  34. compctl -v getln getopts read unset vared
  35. compctl -v -S '=' -q declare export integer local readonly typeset
  36. compctl -eB -x 'p[1] s[-]' -k '(a f m r)' - \
  37. 'C[1,-*a*]' -ea - 'C[1,-*f*]' -eF - 'C[-1,-*r*]' -ew -- disable
  38. compctl -dB -x 'p[1] s[-]' -k '(a f m r)' - \
  39. 'C[1,-*a*]' -da - 'C[1,-*f*]' -dF - 'C[-1,-*r*]' -dw -- enable
  40. compctl -k "(${(j: :)${(f)$(limit)}%% *})" limit unlimit
  41. compctl -l '' -x 'p[1]' -f -- . source
  42. # Redirection below makes zsh silent when completing unsetopt xtrace
  43. compctl -s '$({ unsetopt kshoptionprint; setopt } 2>/dev/null)' + -o + -x 's[no]' -o -- unsetopt
  44. compctl -s '$({ unsetopt kshoptionprint; unsetopt } 2>/dev/null)' + -o + -x 's[no]' -o -- setopt
  45. compctl -s '${^fpath}/*(N:t)' autoload
  46. compctl -b -x 'W[1,-*[DAN]*],C[-1,-*M]' -s '$(bindkey -l)' -- bindkey
  47. compctl -c -x 'C[-1,-*k]' -A - 'C[-1,-*K]' -F -- compctl
  48. compctl -x 'C[-1,-*e]' -c - 'C[-1,-[ARWI]##]' -f -- fc
  49. compctl -x 'p[1]' - 'p[2,-1]' -l '' -- sched
  50. compctl -x 'C[-1,[+-]o]' -o - 'c[-1,-A]' -A -- set
  51. compctl -b -x 'w[1,-N] p[3]' -F -- zle
  52. compctl -s '${^module_path}/*(N:t:r)' -x \
  53. 'W[1,-*(a*u|u*a)*],W[1,-*a*]p[3,-1]' -B - \
  54. 'W[1,-*u*]' -s '$(zmodload)' -- zmodload
  55. # Anything after nohup is a command by itself with its own completion
  56. compctl -l '' nohup noglob exec nice eval - time rusage
  57. compctl -l '' -x 'p[1]' -eB -- builtin
  58. compctl -l '' -x 'p[1]' -em -- command
  59. compctl -x 'p[1]' -c - 'p[2,-1]' -k signals -- trap
  60. #------------------------------------------------------------------------------
  61. # kill takes signal names as the first argument after -, but job names after %
  62. # or PIDs as a last resort
  63. compctl -j -P '%' + -s '`ps -x | tail +2 | cut -c1-5`' + \
  64. -x 's[-] p[1]' -k "($signals[1,-3])" -- kill
  65. #------------------------------------------------------------------------------
  66. compctl -s '$(groups)' + -k groups newgrp
  67. compctl -f -x 'p[1], p[2] C[-1,-*]' -k groups -- chgrp
  68. compctl -f -x 'p[1] n[-1,.], p[2] C[-1,-*] n[-1,.]' -k groups - \
  69. 'p[1], p[2] C[-1,-*]' -u -S '.' -q -- chown
  70. compctl -/g '*.x' rpcgen
  71. compctl -u -x 's[+] c[-1,-f],s[-f+]' -W ~/Mail -f - \
  72. 's[-f],c[-1,-f]' -f -- mail elm
  73. compctl -x 'c[-1,-f]' -W ~/Mail -f -- pine
  74. #------------------------------------------------------------------------------
  75. compctl -s "\$(awk '/^[a-zA-Z0-9][^ ]+:/ {print \$1}' FS=: [mM]akefile)" -x \
  76. 'c[-1,-f]' -f -- make gmake pmake
  77. #------------------------------------------------------------------------------
  78. # tar
  79. tarnames () {
  80. # Completion function for use with tar:
  81. # get the names of files in the tar archive to extract.
  82. #
  83. # The main claim to fame of this particular function is that it
  84. # completes directories in the tar-file in a manner very roughly
  85. # consistent with `compctl -f'. There are two bugs: first, the whole
  86. # path prefix up to the present is listed with ^D, not just the new
  87. # part to add; second, after a unique completion a space is always
  88. # inserted, even if the completion ends with a slash. These are
  89. # currently limitations of zsh.
  90. #
  91. # This only works for the (fairly common) tar argument style where
  92. # the arguments are bunched into the first argument, and the second
  93. # argument is the name of the tarfile. For example,
  94. # tar xvzf zsh-3.1.2.tar.gz ...
  95. # You can only use compressed/gzipped files if tar is GNU tar,
  96. # although the correct name for the tar programme will be inferred.
  97. local line list=tf
  98. read -cA line
  99. # $line[2] is the first argument: check for possible compression args.
  100. # (This is harmless when used with non-GNU tar, but then the file must
  101. # be uncompressed to be able to use it with tar anyway.)
  102. [[ $line[2] = *[Zz]* ]] && list=tfz
  103. # $line[1] is the command name: something like tar or gnutar.
  104. # $line[3] is the name of the tar archive.
  105. # cache contents for multiple completion: note tar_cache_name
  106. # and tar_cache_list are not local. Assumes all files with the
  107. # same name are the same file, even if in different directories:
  108. # you can trick it with $PWD/file on the command line.
  109. if [[ $line[3] != $tar_cache_name ]]; then
  110. tar_cache_list=($($line[1] $list $line[3]))
  111. tar_cache_name=$line[3]
  112. fi
  113. # Now prune the list to include only appropriate directories.
  114. local file new
  115. reply=()
  116. if [[ $1 = */* ]]; then
  117. local sofar=${1%/*}/
  118. for file in $tar_cache_list; do
  119. if [[ $file = $sofar* ]]; then
  120. new=${file#$sofar}
  121. if [[ $new = */* ]]; then
  122. new=$sofar${new%%/*}/
  123. else
  124. new=$file
  125. fi
  126. if [[ $1 != */ || $new != $1 ]]; then
  127. reply=($reply $new)
  128. fi
  129. fi
  130. done
  131. else
  132. for file in $tar_cache_list; do
  133. if [[ $file = */* ]]; then
  134. new=${file%%/*}/
  135. else
  136. new=$file
  137. fi
  138. reply=($reply $new)
  139. done
  140. fi
  141. }
  142. compctl -f \
  143. -x 'p[2] C[-1,*(z*f|f*z)*]' -/g '*.(taz|tar.(gz|z|Z)|tgz)' \
  144. - 'p[2] C[-1,*(Z*f|f*Z)*]' -/g '*.(tar.Z|taz)' \
  145. - 'p[2] C[-1,*f*]' -/g '*.tar' \
  146. - 'p[1] N[-1,ctxvzZ]' -k "(v z f)" \
  147. - 'p[1] s[]' -k "(c t x)" -S '' \
  148. - 'p[3,-1] W[1,*x*]' -K tarnames \
  149. -- tar gtar gnutar
  150. #------------------------------------------------------------------------------
  151. # rmdir only real directories
  152. compctl -/g '*(/)' rmdir dircmp
  153. #------------------------------------------------------------------------------
  154. # cd/pushd only directories or symbolic links to directories
  155. compctl -/ cd chdir dirs pushd
  156. # Another possibility for cd/pushd is to use it in conjunction with the
  157. # cdmatch function (in the Functions subdirectory of zsh distribution).
  158. compctl -K cdmatch -S '/' -q -x 'p[2]' -Q -K cdmatch2 - \
  159. 'S[/][~][./][../]' -g '*(-/)' + -g '*(-/D)' - \
  160. 'n[-1,/]' -K cdmatch -S '/' -q -- cd chdir pushd
  161. #------------------------------------------------------------------------------
  162. # If the command is rsh, make the first argument complete to hosts and treat the
  163. # rest of the line as a command on its own.
  164. compctl -k hosts -x 'p[2,-1]' -l '' -- rsh
  165. # rlogin takes hosts and users after `-l'
  166. compctl -k hosts -x 'c[-1,-l]' -u -- rlogin
  167. # rcp: match users, hosts and files initially. Match files after a :, or hosts
  168. # after an @. If one argument contains a : then the other matches files only.
  169. # Not quite perfect; compctl just isn't up to it yet.
  170. compctl -u -k hosts -f -x 'n[1,:]' -f - 'n[1,@]' -k hosts -S ':' - \
  171. 'p[1] W[2,*:*]' -f - 'p[1] W[2,*?*]' -u -k hosts -S ':' - \
  172. 'p[2] W[1,*:*]' -f - 'p[2] W[1,*?*]' -u -k hosts -S ':' -- rcp
  173. compctl -k hosts host rup rusers ping
  174. #------------------------------------------------------------------------------
  175. # strip, profile, and debug only executables. The compctls for the
  176. # debuggers could be better, of course.
  177. compctl -/g '*(*)' strip gprof adb dbx xdbx ups
  178. compctl -/g '*.[ao]' -/g '*(*)' nm
  179. #------------------------------------------------------------------------------
  180. # shells: compctl needs some more enhancement to do -c properly.
  181. compctl -f -x 'C[-1,-*c]' -c - 'C[-1,[-+]*o]' -o -- bash ksh sh zsh
  182. #------------------------------------------------------------------------------
  183. # su takes a username and args for the shell.
  184. compctl -u -x 'w[1,-]p[3,-1]' -l sh - 'w[1,-]' -u - 'p[2,-1]' -l sh -- su
  185. #------------------------------------------------------------------------------
  186. # Run ghostscript on postscript files, but if no postscript file matches what
  187. # we already typed, complete directories as the postscript file may not be in
  188. # the current directory.
  189. compctl -/g '*.(e|E|)(ps|PS)' \
  190. gs ghostview nup psps pstops psmulti psnup psselect
  191. #------------------------------------------------------------------------------
  192. # Similar things for tex, texinfo and dvi files.
  193. compctl -/g '*.tex*' {,la,gla,ams{la,},{g,}sli}tex texi2dvi
  194. compctl -/g '*.dvi' xdvi dvips
  195. #------------------------------------------------------------------------------
  196. # For rcs users, co and rlog from the RCS directory. We don't want to see
  197. # the RCS and ,v though.
  198. compctl -g 'RCS/*(:s@RCS/@@:s/,v//)' co rlog rcs rcsdiff
  199. #------------------------------------------------------------------------------
  200. # gzip uncompressed files, but gzip -d only gzipped or compressed files
  201. compctl -x 'R[-*[dt],^*]' -/g '*.(gz|z|Z|t[agp]z|tarZ|tz)' + -f - \
  202. 's[]' -/g '^*(.(tz|gz|t[agp]z|tarZ|zip|ZIP|jpg|JPG|gif|GIF|[zZ])|[~#])' \
  203. + -f -- gzip
  204. compctl -/g '*.(gz|z|Z|t[agp]z|tarZ|tz)' gunzip gzcat zcat
  205. compctl -/g '*.Z' uncompress zmore
  206. compctl -/g '*.F' melt fcat
  207. #------------------------------------------------------------------------------
  208. # ftp takes hostnames
  209. ftphosts=(prep.ai.mit.edu wuarchive.wustl.edu ftp.uu.net ftp.math.gatech.edu)
  210. compctl -k ftphosts ftp
  211. # Some systems have directories containing indices of ftp servers.
  212. # For example: we have the directory /home/ftp/index/INDEX containing
  213. # files of the form `<name>-INDEX.Z', this leads to:
  214. #compctl -g '/home/ftp/index/INDEX/*-INDEX.Z(:t:r:s/-INDEX//)' ftp tftp
  215. #------------------------------------------------------------------------------
  216. # Change default completion (see the multicomp function in the Function
  217. # subdirectory of the zsh distribution).
  218. #compctl -D -f + -U -K multicomp
  219. # If completion of usernames is slow for you, you may want to add something
  220. # like
  221. # -x 'C[0,*/*]' -f - 's[~]' -S/ -k users + -u
  222. # where `users' contains the names of the users you want to complete often.
  223. # If you want to use this and to be able to complete named directories after
  224. # the `~' you should add `+ -n' at the end
  225. #------------------------------------------------------------------------------
  226. # This is to complete all directories under /home, even those that are not
  227. # yet mounted (if you use the automounter).
  228. # This is for NIS+ (e.g. Solaris 2.x)
  229. #compctl -Tx 's[/home/] C[0,^/home/*/*]' -S '/' -s '$(niscat auto_home.org_dir | \
  230. # awk '\''/export\/[a-zA-Z]*$/ {print $NF}'\'' FS=/)'
  231. # And this is for YP (e.g. SunOS4.x)
  232. #compctl -Tx 's[/home/] C[0,^/home/*/*]' -S '/' -s '$(ypcat auto.home | \
  233. # awk '\''/export\/[a-zA-Z]*$/ {print $NF}'\'' FS=/)'
  234. #------------------------------------------------------------------------------
  235. # Find is very system dependent, this one is for GNU find.
  236. # Note that 'r[-exec,;]' must come first
  237. if [[ -r /proc/filesystems ]]; then
  238. # Linux
  239. filesystems='"${(@)${(@f)$(</proc/filesystems)}#* }"'
  240. else
  241. filesystems='ufs 4.2 4.3 nfs tmp mfs S51K S52K'
  242. fi
  243. compctl -x 'r[-exec,;][-ok,;]' -l '' - \
  244. 's[-]' -s 'daystart {max,min,}depth follow noleaf version xdev
  245. {a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links
  246. {i,}{l,}name {no,}{user,group} path perm regex size true uid used
  247. exec {f,}print{f,0,} ok prune ls' - \
  248. 'p[1]' -g '. .. *(-/)' - \
  249. 'C[-1,-((a|c|)newer|fprint(|0|f))]' -f - \
  250. 'c[-1,-fstype]' -s $filesystems - \
  251. 'c[-1,-group]' -k groups - \
  252. 'c[-1,-user]' -u -- find
  253. #------------------------------------------------------------------------------
  254. # Generic completion for C compiler.
  255. compctl -/g "*.[cCoa]" -x 's[-I]' -/ - \
  256. 's[-l]' -s '${(s.:.)^LD_LIBRARY_PATH}/lib*.a(:t:r:s/lib//)' -- cc
  257. #------------------------------------------------------------------------------
  258. # GCC completion, by Andrew Main
  259. # completes to filenames (*.c, *.C, *.o, etc.); to miscellaneous options after
  260. # a -; to various -f options after -f (and similarly -W, -g and -m); and to a
  261. # couple of other things at different points.
  262. # The -l completion is nicked from the cc compctl above.
  263. # The -m completion should be tailored to each system; the one below is i386.
  264. compctl -/g '*.([cCmisSoak]|cc|cxx|ii|k[ih])' -x \
  265. 's[-l]' -s '${(s.:.)^LD_LIBRARY_PATH}/lib*.a(:t:r:s/lib//)' - \
  266. 'c[-1,-x]' -k '(none c objective-c c-header c++ cpp-output
  267. assembler assembler-with-cpp)' - \
  268. 'c[-1,-o]' -f - \
  269. 'C[-1,-i(nclude|macros)]' -/g '*.h' - \
  270. 'C[-1,-i(dirafter|prefix)]' -/ - \
  271. 's[-B][-I][-L]' -/ - \
  272. 's[-fno-],s[-f]' -k '(all-virtual cond-mismatch dollars-in-identifiers
  273. enum-int-equiv external-templates asm builtin strict-prototype
  274. signed-bitfields signd-char this-is-variable unsigned-bitfields
  275. unsigned-char writable-strings syntax-only pretend-float caller-saves
  276. cse-follow-jumps cse-skip-blocks delayed-branch elide-constructors
  277. expensive-optimizations fast-math float-store force-addr force-mem
  278. inline-functions keep-inline-functions memoize-lookups default-inline
  279. defer-pop function-cse inline peephole omit-frame-pointer
  280. rerun-cse-after-loop schedule-insns schedule-insns2 strength-reduce
  281. thread-jumps unroll-all-loops unroll-loops)' - \
  282. 's[-g]' -k '(coff xcoff xcoff+ dwarf dwarf+ stabs stabs+ gdb)' - \
  283. 's[-mno-][-mno][-m]' -k '(486 soft-float fp-ret-in-387)' - \
  284. 's[-Wno-][-W]' -k '(all aggregate-return cast-align cast-qual
  285. char-subscript comment conversion enum-clash error format id-clash-6
  286. implicit inline missing-prototypes missing-declarations nested-externs
  287. import parentheses pointer-arith redundant-decls return-type shadow
  288. strict-prototypes switch template-debugging traditional trigraphs
  289. uninitialized unused write-strings)' - \
  290. 's[-]' -k '(pipe ansi traditional traditional-cpp trigraphs pedantic
  291. pedantic-errors nostartfiles nostdlib static shared symbolic include
  292. imacros idirafter iprefix iwithprefix nostdinc nostdinc++ undef)' \
  293. -X 'Use "-f", "-g", "-m" or "-W" for more options' -- gcc g++
  294. #------------------------------------------------------------------------------
  295. # There are (at least) two ways to complete manual pages. This one is
  296. # extremely memory expensive if you have lots of man pages
  297. man_var() {
  298. man_pages=( ${^manpath}/man*/*(N:t:r) )
  299. compctl -k man_pages -x 'C[-1,-P]' -m - \
  300. 'R[-*l*,;]' -/g '*.(man|[0-9](|[a-z]))' -- man
  301. reply=( $man_pages )
  302. }
  303. compctl -K man_var -x 'C[-1,-P]' -m - \
  304. 'R[-*l*,;]' -/g '*.(man|[0-9](|[a-z]))' -- man
  305. # This one isn't that expensive but somewhat slower
  306. man_glob () {
  307. local a
  308. read -cA a
  309. if [[ $a[2] = -s ]] then # Or [[ $a[2] = [0-9]* ]] for BSD
  310. reply=( ${^manpath}/man$a[3]/$1*$2(N:t:r) )
  311. else
  312. reply=( ${^manpath}/man*/$1*$2(N:t:r) )
  313. fi
  314. }
  315. #compctl -K man_glob -x 'C[-1,-P]' -m - \
  316. # 'R[-*l*,;]' -/g '*.(man|[0-9nlpo](|[a-z]))' -- man
  317. #------------------------------------------------------------------------------
  318. # xsetroot: gets possible colours, cursors and bitmaps from wherever.
  319. # Uses two auxiliary functions. You might need to change the path names.
  320. Xcolours() {
  321. reply=( ${(L)$(awk '{ if (NF = 4) print $4 }' \
  322. < /usr/openwin/lib/X11/rgb.txt)} )
  323. }
  324. Xcursor() {
  325. reply=( $(sed -n 's/^#define[ ][ ]*XC_\([^ ]*\)[ ].*$/\1/p' \
  326. < /usr/include/X11/cursorfont.h) )
  327. }
  328. compctl -k '(-help -def -display -cursor -cursor_name -bitmap -mod -fg -bg
  329. -grey -rv -solid -name)' -x \
  330. 'c[-1,-display]' -s '$DISPLAY' -k hosts -S ':0' - \
  331. 'c[-1,-cursor]' -f - 'c[-2,-cursor]' -f - \
  332. 'c[-1,-bitmap]' -g '/usr/include/X11/bitmaps/*' - \
  333. 'c[-1,-cursor_name]' -K Xcursor - \
  334. 'C[-1,-(solid|fg|bg)]' -K Xcolours -- xsetroot
  335. #------------------------------------------------------------------------------
  336. # dd
  337. compctl -k '(if of conv ibs obs bs cbs files skip file seek count)' \
  338. -S '=' -x 's[if=], s[of=]' -f - 'C[0,conv=*,*] n[-1,,], s[conv=]' \
  339. -k '(ascii ebcdic ibm block unblock lcase ucase swap noerror sync)' \
  340. -q -S ',' - 'n[-1,=]' -X '<number>' -- dd
  341. #------------------------------------------------------------------------------
  342. # Various MH completions by Peter Stephenson
  343. # You may need to edit where it says *Edit Me*.
  344. # The following three functions are best autoloaded.
  345. # mhcomp completes folders (including subfolders),
  346. # mhfseq completes sequence names and message numbers,
  347. # mhfile completes files in standard MH locations.
  348. function mhcomp {
  349. # Completion function for MH folders.
  350. # Works with both + (rel. to top) and @ (rel. to current).
  351. local nword args pref char mhpath
  352. read -nc nword
  353. read -cA args
  354. pref=$args[$nword]
  355. char=$pref[1]
  356. pref=$pref[2,-1]
  357. # The $(...) here accounts for most of the time spent in this function.
  358. if [[ $char = + ]]; then
  359. # mhpath=$(mhpath +)
  360. # *Edit Me*: use a hard wired value here: it's faster.
  361. mhpath=~/Mail
  362. elif [[ $char = @ ]]; then
  363. mhpath=$(mhpath)
  364. fi
  365. eval "reply=($mhpath/$pref*(N-/))"
  366. # I'm frankly amazed that this next step works, but it does.
  367. reply=(${reply#$mhpath/})
  368. }
  369. mhfseq() {
  370. # Extract MH message names and numbers for completion. Use of the
  371. # correct folder, if it is not the current one, requires that it
  372. # should be the previous command line argument. If the previous
  373. # argument is `-draftmessage', a hard wired draft folder name is used.
  374. local folder foldpath words pos nums
  375. read -cA words
  376. read -cn pos
  377. # Look for a folder name.
  378. # First try the previous word.
  379. if [[ $words[$pos-1] = [@+]* ]]; then
  380. folder=$words[$pos-1]
  381. # Next look and see if we're looking for a draftmessage
  382. elif [[ $words[$pos-1] = -draftmessage ]]; then
  383. # *Edit Me*: shortcut -- hard-wire draftfolder here
  384. # Should really look for a +draftfolder argument.
  385. folder=+drafts
  386. fi
  387. # Else use the current folder ($folder empty)
  388. if [[ $folder = +* ]]; then
  389. # *Edit Me*: use hard-wired path with + for speed.
  390. foldpath=~/Mail/$folder[2,-1]
  391. else
  392. foldpath=$(mhpath $folder)
  393. fi
  394. # Extract all existing message numbers from the folder.
  395. nums=($foldpath/<->(N:t))
  396. # If that worked, look for marked sequences.
  397. # *Edit Me*: if you never use non-standard sequences, comment out
  398. # or delete the next three lines.
  399. if (( $#nums )); then
  400. nums=($nums $(mark $folder | awk -F: '{print $1}'))
  401. fi
  402. # *Edit Me*: `unseen' is the value of Unseen-Sequence, if it exists;
  403. set -A reply next cur prev first last all unseen $nums
  404. }
  405. mhfile () {
  406. # Find an MH file; for use with -form arguments and the like.
  407. # Use with compctl -K mhfile.
  408. local mhfpath file
  409. # *Edit Me*: Array containing all the places MH will look for templates etc.
  410. mhfpath=(~/Mail /usr/local/lib/MH)
  411. # Emulate completeinword behaviour as appropriate
  412. local wordstr
  413. if [[ -o completeinword ]]; then
  414. wordstr='$1*$2'
  415. else
  416. wordstr='$1$2*'
  417. fi
  418. if [[ $1$2 = */* ]]; then
  419. # path given: don't search MH locations
  420. eval "reply=($wordstr(.N))"
  421. else
  422. # no path: only search MH locations.
  423. eval "reply=(\$mhfpath/$wordstr(.N:t))"
  424. fi
  425. }
  426. # Note: you must type the initial + or @ of a folder name to get
  427. # completion, even in places where only folder names are allowed.
  428. # Abbreviations for options are not recognised. Hit tab to complete
  429. # the option name first.
  430. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  431. 's[-]' -k "(all fast nofast header noheader help list nolist \
  432. pack nopack pop push recurse norecurse total nototal)" -- folder
  433. compctl -K mhfseq -x 's[+][@],c[-1,-draftfolder] s[+][@]' \
  434. -K mhcomp -S / -q - 'c[-1,-draftmessage]' -K mhfseq - \
  435. 'C[-1,-(editor|whatnowproc)]' -c - \
  436. 's[-]' -k "(draftfolder draftmessage nodraftfolder editor noedit \
  437. file form use nouse whatnowproc nowhatnowproc help)" - \
  438. 'c[-1,-form]' -K mhfile -- comp
  439. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  440. 's[-]' -k "(audit noaudit changecur nochangecur form format \
  441. file silent nosilent truncate notruncate width help)" - \
  442. 'C[-1,-(audit|form)]' -K mhfile - 'c[-1,-file]' -f + -- inc
  443. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  444. 's[-]' -k "(sequence add delete list public nopublic zero nozero help)" -- \
  445. mark
  446. compctl -K mhfseq -x 's[+][@]' \
  447. -K mhcomp -S / -q - 'c[-1,-file]' -f - 'c[-1,-rmmprov]' -c - \
  448. 's[-]' -k "(draft link nolink preserve nopreserve src file \
  449. rmmproc normmproc help)" -- refile
  450. compctl -K mhfseq -x 's[+][@]' \
  451. -K mhcomp -S / -q - 'c[-1,-draftmessage]' -K mhfseq -\
  452. 's[-]' -k "(annotate noannotate cc nocc draftfolder nodraftfolder \
  453. draftmessage editor noedit fcc filter form inplace noinplace query \
  454. noquery width whatnowproc nowhatnowproc help)" - 'c[-1,(cc|nocc)]' \
  455. -k "(all to cc me)" - 'C[-1,-(filter|form)]' -K mhfile - \
  456. 'C[-1,-(editor|whatnowproc)]' -c -- repl
  457. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  458. 's[-]' -k "(clear noclear form format header noheader reverse noreverse \
  459. file help width)" - 'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile -- scan
  460. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  461. 's[-]' -k "(draft form moreproc nomoreproc header noheader \
  462. showproc noshowproc length width help)" - 'C[-1,-(show|more)proc]' -c - \
  463. 'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile - \
  464. 'c[-1,-length]' -s '$LINES' - 'c[-1,-width]' -s '$COLUMNS' -- show next prev
  465. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
  466. -k "(help)" -- rmm
  467. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  468. 's[-]' -k "(after before cc date datefield from help list nolist \
  469. public nopublic search sequence subject to zero nozero not or and \
  470. lbrace rbrace)" -- pick
  471. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
  472. -k "(alias check draft draftfolder draftmessage help nocheck \
  473. nodraftfolder)" -- whom
  474. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
  475. -k "(file part type list headers noheaders realsize norealsize nolist \
  476. show serialonly noserialonly form pause nopause noshow store auto noauto \
  477. nostore cache nocache rcache wcache check nocheck ebcdicsafe noebcdicsafe \
  478. rfc934mode norfc934mode verbose noverbose help)" - \
  479. 'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile - \
  480. 'C[-1,-[rw]cache]' -k '(public private never ask)' -- mhn
  481. compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' -k '(help)' -- mhpath
  482. #------------------------------------------------------------------------------
  483. # CVS
  484. #
  485. cvscmds=(add admin rcs checkout commit diff rdiff export history import log rlog
  486. release remove status tag rtag update annotate)
  487. cvsignore="*~ *# .#* *.o *.a CVS . .."
  488. compctl -k cvscmds \
  489. -x "c[-1,-D]" -k '(today yesterday 1\ week\ ago)' \
  490. - "c[-1,-m]" -k '(bugfix cosmetic\ fix ... added\ functionality foo)' \
  491. - "c[-1,-F]" -f \
  492. - "c[-1,-r]" -K cvsrevisions \
  493. - "c[-1,-I]" -f \
  494. - "R[add,;]" -K cvsaddp \
  495. - "R[(admin|rcs),;]" -/K cvstargets \
  496. - "R[(checkout|co),;]" -K cvsrepositories \
  497. - "R[(commit|ci),;]" -/K cvstargets \
  498. - "R[(r|)diff,;]" -/K cvstargets \
  499. - "R[export,;]" -f \
  500. - "R[history,;]" -/K cvstargets \
  501. - "R[history,;] c[-1,-u]" -u \
  502. - "R[import,;]" -K cvsrepositories \
  503. - "R[(r|)log,;]" -/K cvstargets \
  504. - 'R[(r|)log,;] s[-w] n[-1,,],s[-w]' -u -S , -q \
  505. - "R[rel(|ease),;]" -f \
  506. - "R[(remove|rm),;] R[-f,;]" -/K cvstargets \
  507. - "R[(remove|rm),;]" -K cvsremovep \
  508. - "R[status,;]" -/K cvstargets \
  509. - "R[(r|)tag,;]" -/K cvstargets \
  510. - "R[up(|date),;]" -/K cvstargets \
  511. - "R[annotate,;]" -/K cvstargets \
  512. -- cvs
  513. compctl -/K cvstargets cvstest
  514. cvsprefix() {
  515. local nword args f
  516. read -nc nword; read -Ac args
  517. pref=$args[$nword]
  518. if [[ -d $pref:h && ! -d $pref ]]; then
  519. pref=$pref:h
  520. elif [[ $pref != */* ]]; then
  521. pref=
  522. fi
  523. [[ -n "$pref" && "$pref" != */ ]] && pref=$pref/
  524. }
  525. cvsentries() {
  526. setopt localoptions nullglob unset
  527. if [[ -f ${pref}CVS/Entries ]]; then
  528. reply=( "${pref}${(@)^${(@)${(@)${(f@)$(<${pref}CVS/Entries)}:#D*}#/}%%/*}" )
  529. fi
  530. }
  531. cvstargets() {
  532. local pref
  533. cvsprefix
  534. cvsentries
  535. }
  536. cvsrevisions() {
  537. reply=( "${(@)${(@)${(@M)${(@f)$(cvs -q status -vl .)}:# *}##[ ]##}%%[ ]*}" )
  538. }
  539. cvsrepositories() {
  540. local root=$CVSROOT
  541. [[ -f CVS/Root ]] && root=$(<CVS/Root)
  542. reply=(
  543. $root/^CVSROOT(:t)
  544. "${(@)${(@M)${(@f)$(<$root/CVSROOT/modules)}:#[^#]*}%%[ ]*}"
  545. )
  546. }
  547. cvsremovep() {
  548. local pref
  549. cvsprefix
  550. cvsentries
  551. setopt localoptions unset
  552. local omit
  553. omit=( ${pref}*(D) )
  554. eval 'reply=( ${reply:#('${(j:|:)omit}')} )'
  555. }
  556. cvsaddp() {
  557. local pref
  558. cvsprefix
  559. cvsentries
  560. setopt localoptions unset
  561. local all omit
  562. all=( ${pref}*(D) )
  563. omit=( $reply ${pref}${^${=cvsignore}} )
  564. [[ -r ~/.cvsignore ]] && omit=( $omit ${pref}${^$(<~/.cvsignore)} )
  565. [[ -r ${pref}.cvsignore ]] && omit=( $omit ${pref}${^$(<${pref}.cvsignore)} )
  566. eval 'reply=( ${all:#('${(j:|:)omit}')} )'
  567. }
  568. #------------------------------------------------------------------------------
  569. # RedHat Linux rpm utility
  570. #
  571. compctl -s '$(rpm -qa)' \
  572. -x 's[--]' -s 'oldpackage percent replacefiles replacepkgs noscripts
  573. root excludedocs includedocs test upgrade test clean
  574. short-circuit sign recompile rebuild resign querytags
  575. queryformat version help quiet rcfile force hash' - \
  576. 's[ftp:]' -P '//' -s '$(</u/zsh/ftphosts)' -S '/' - \
  577. 'c[-1,--root]' -/ - \
  578. 'c[-1,--rcfile]' -f - \
  579. 'p[1] s[-b]' -k '(p l c i b a)' - \
  580. 'c[-1,--queryformat] N[-1,{]' \
  581. -s '"${(@)${(@f)$(rpm --querytags)}#RPMTAG_}"' -S '}' - \
  582. 'W[1,-q*] C[-1,-([^-]*|)f*]' -f - \
  583. 'W[1,-i*], W[1,-q*] C[-1,-([^-]*|)p*]' \
  584. -/g '*.rpm' + -f -- rpm
  585. #------------------------------------------------------------------------------
  586. compctl -u -x 'c[-1,-w]' -f -- ac
  587. compctl -/g '*.m(.)' mira
  588. #------------------------------------------------------------------------------
  589. # talk completion: complete local users, or users at hosts listed via rwho
  590. compctl -K talkmatch talk ytalk ytalk3
  591. function talkmatch {
  592. local u
  593. reply=($(users))
  594. for u in "${(@)${(@f)$(rwho 2>/dev/null)}%%:*}"; do
  595. reply=($reply ${u%% *}@${u##* })
  596. done
  597. }
  598. #------------------------------------------------------------------------------
  599. # Linux mount
  600. comp_fsmount () {
  601. local tmp; if [[ $UID = 0 ]]; then tmp=""; else tmp="user"; fi
  602. sed -n -e "s|^[^# ][^ ]*[ ][ ]*\(/[^ ]*\)[ ].*$tmp.*|\1|p" /etc/fstab
  603. }
  604. comp_nfsmount () {
  605. local cmd args host
  606. read -Ac cmd; read -cn where
  607. host=${${cmd[$where]}%%:*}
  608. reply=("${(@f)$(showmount -e $host | sed -n -e "s|^/\([^ ]*\) .*|$host:/\1|p")}")
  609. }
  610. compctl -s '$(mount | \
  611. sed -e "s/^[^ ]* on \\([^ ]*\\) type.*/\\1/"'"$(
  612. if [[ ! $UID = 0 ]]; then
  613. echo ' | egrep "^${(j:|:)$(comp_fsmount)}\$"'
  614. fi)"')' umount
  615. compctl -s '$(comp_fsmount)' + \
  616. -x 'S[/]' -f -- + \
  617. -x 'C[0,*:*]' -K comp_nfsmount -- + \
  618. -s '$(< /etc/hosts)' \
  619. mount
  620. #------------------------------------------------------------------------------
  621. # Lynx (web browser)
  622. compctl -k '(http:// file: ftp:// gopher:// news://)' -S '' \
  623. -x 's[ftp://]' -k ftphosts -S/ \
  624. - 'n[1,://]' -k hosts -S/ \
  625. - 's[file:/]' -/g '*.html' -W/ \
  626. - 's[file:]' -s '~+' -S '/' \
  627. - 's[-]' -k '(anonymous auth base book buried_news cache case
  628. cfg child cookies crawl display dump editor emacskeys
  629. enable_scrollback error_file fileversions force_html
  630. from ftp get_data head help historical homepage
  631. image_links index link localhost locexec mime_header
  632. minimal newschunksize newsmaxchunk nobrowse noexec
  633. nofilereferer nofilereferer nolist nolog nopause
  634. noprint noredir noreferer nosocks nostatus number_links
  635. popup post_data print pseudo_inlines raw realm reload
  636. restrictions resubmit_posts rlogin selective show_cursor
  637. source startfile_ok telnet term trace traversal underscore
  638. validate version vikeys)' \
  639. -- lynx
  640. #------------------------------------------------------------------------------
  641. # ssh (secure shell)
  642. compctl -k hosts \
  643. -x "c[-1,-l]" -u \
  644. - "c[-1,-i]" -f \
  645. - "c[-1,-e]" -k "(~ none)" \
  646. - "c[-1,-c]" -k "(idea des 3des tss arcfour none)" \
  647. - "c[-1,-p]" -k ports \
  648. - "c[-1,-L] c[-1,-R] c[-1,-o]" -k "()" \
  649. -- ssh
  650. #------------------------------------------------------------------------------
  651. # network stuff
  652. compctl -k hosts \
  653. -x "s[-class=]" -k "(any in chaos hesiod)" \
  654. - "s[-query=]" -k "(a cname hinfo md mx mb mg minfo ns ptr soa txt uinfo wks any)" \
  655. - "s[-]" -Q -S '' -k "(query= all\ class= d2\ nod2\ debug\ nodebug\ defname\ nodefname\ domain= ignoretc\ noignoretc\ )" \
  656. -- nslookup
  657. compctl -k hosts \
  658. -x "C[-1,[^-]*] p[2,-1]" -k ports \
  659. -- telnet
  660. compctl -x 'N[-1,@]' -k hosts - 's[]' -u -qS '@' -- finger
  661. #------------------------------------------------------------------------------
  662. # gdb
  663. compctl -/g "*(*)" \
  664. -x "s[-]" -k "(help nx q batch cd f b tty exec se core symbols c x d)" \
  665. - "C[-1,(-cd|-directory)]" -/ \
  666. - "C[-1,(-core|-c)]" -/g 'core*' \
  667. - "C[-1,(-se|-exec)]" -f \
  668. - "C[-1,(-symbols|-command|-x)]" -f \
  669. - "p[2,-1] C[-1,[^-]*]" -/g "core*" \
  670. -- gdb