--- /dev/null
+#
+# The following several shell functions and `compctl' commands
+# that will configure the programmable command completion of
+# the Z Shell (zsh) for the nmh mail system.
+#
+# You may need to edit where it says EDIT ME.
+# These were orginally written for MH by Peter Stephenson
+
+# The following three functions are best autoloaded.
+#
+# mhcomp completes folders (including subfolders).
+# mhfseq completes sequence names and message numbers.
+# mhfile completes files in standard nmh locations.
+
+#
+# Completion function for nmh folders. Works with
+# both + (relative to top) and @ (relative to current).
+#
+function mhcomp {
+ local nword args pref char mhpath
+ read -nc nword
+ read -cA args
+
+ pref=$args[$nword]
+ char=$pref[1]
+ pref=$pref[2,-1]
+
+ # The $(...) here accounts for most of the time spent in this function.
+ if [[ $char = + ]]; then
+ # mhpath=$(mhpath +)
+ # EDIT ME: use a hard wired value here: it's faster.
+ mhpath=~/Mail
+ elif [[ $char = @ ]]; then
+ mhpath=$(mhpath)
+ fi
+
+ eval "reply=($mhpath/$pref*(N-/))"
+
+ # I'm frankly amazed that this next step works, but it does.
+ reply=(${reply#$mhpath/})
+}
+
+#
+# Extract nmh message names and numbers for completion. Use of the
+# correct folder, if it is not the current one, requires that it
+# should be the previous command line argument. If the previous
+# argument is `-draftmessage', a hard wired draft folder name is used.
+#
+mhfseq() {
+ local folder foldpath words pos nums
+ read -cA words
+ read -cn pos
+
+ # Look for a folder name.
+ # First try the previous word.
+ if [[ $words[$pos-1] = [@+]* ]]; then
+ folder=$words[$pos-1]
+ # Next look and see if we're looking for a draftmessage
+ elif [[ $words[$pos-1] = -draftmessage ]]; then
+ # EDIT ME: shortcut -- hard-wire draftfolder here
+ # Should really look for a +draftfolder argument.
+ folder=+drafts
+ fi
+ # Else use the current folder ($folder empty)
+
+ if [[ $folder = +* ]]; then
+ # EDIT ME: use hard-wired path with + for speed.
+ foldpath=~/Mail/$folder[2,-1]
+ else
+ foldpath=$(mhpath $folder)
+ fi
+
+ # Extract all existing message numbers from the folder.
+ nums=($foldpath/<->(N:t))
+ # If that worked, look for marked sequences.
+ # EDIT ME
+ # if you never use non-standard sequences, comment out
+ # or delete the next three lines.
+ if (( $#nums )); then
+ nums=($nums $(mark $folder | awk -F: '{print $1}'))
+ fi
+
+ # EDIT ME: `unseen' is the value of Unseen-Sequence, if it exists;
+ set -A reply next cur prev first last all unseen $nums
+
+}
+
+#
+# Find an nmh file; for use with -form arguments and the like.
+# Use with compctl -K mhfile.
+#
+mhfile () {
+ local mhfpath file
+ # EDIT ME
+ # Array containing all the places nmh will look for templates etc.
+ mhfpath=(~/Mail /usr/local/nmh/lib)
+
+ # Emulate completeinword behaviour as appropriate
+ local wordstr
+ if [[ -o completeinword ]]; then
+ wordstr='$1*$2'
+ else
+ wordstr='$1$2*'
+ fi
+
+ if [[ $1$2 = */* ]]; then
+ # path given: don't search nmh locations
+ eval "reply=($wordstr(.N))"
+ else
+ # no path: only search nmh locations.
+ eval "reply=(\$mhfpath/$wordstr(.N:t))"
+ fi
+}
+
+# Note: you must type the initial + or @ of a folder name to get
+# completion, even in places where only folder names are allowed.
+# Abbreviations for options are not recognised. Hit tab to complete
+# the option name first.
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(all noall fast nofast header noheader help list nolist \
+ pack nopack pop push recurse norecurse total nototal)" -- folder folders
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(sequence all noall recurse norecurse showzero noshowzero \
+ alpha noalpha fast nofast help)" -- flist flists
+
+compctl -K mhfseq -x 's[+][@],c[-1,-draftfolder] s[+][@]' \
+ -K mhcomp -S / -q - 'c[-1,-draftmessage]' -K mhfseq - \
+ 'C[-1,-(editor|whatnowproc)]' -c - \
+ 's[-]' -k "(draftfolder draftmessage nodraftfolder editor noedit \
+ file form use nouse whatnowproc nowhatnowproc help)" - \
+ 'c[-1,-form]' -K mhfile -- comp
+
+compctl -K mhfseq -x 's[+][@]' \
+ -K mhcomp -S / -q - 'c[-1,-draftmessage]' -K mhfseq -\
+ 's[-]' -k "(annotate noannotate cc nocc draftfolder nodraftfolder \
+ draftmessage editor noedit fcc filter form group nogroup inplace noinplace
+ query noquery width whatnowproc nowhatnowproc help)" - 'c[-1,(cc|nocc)]' \
+ -k "(all to cc me)" - 'C[-1,-(filter|form)]' -K mhfile - \
+ 'C[-1,-(editor|whatnowproc)]' -c -- repl
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(audit noaudit changecur nochangecur form format \
+ file silent nosilent truncate notruncate width help)" - \
+ 'C[-1,-(audit|form)]' -K mhfile - 'c[-1,-file]' -f + -- inc
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(sequence add delete list public nopublic zero nozero help)" -- \
+ mark
+
+compctl -K mhfseq -x 's[+][@]' \
+ -K mhcomp -S / -q - 'c[-1,-file]' -f - 'c[-1,-rmmprov]' -c - \
+ 's[-]' -k "(draft link nolink preserve nopreserve src file \
+ rmmproc normmproc help)" -- refile
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(clear noclear form format header noheader reverse noreverse \
+ file help width)" - 'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile -- scan
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(draft form moreproc nomoreproc header noheader \
+ showproc noshowproc length width help)" - 'C[-1,-(show|more)proc]' -c - \
+ 'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile - \
+ 'c[-1,-length]' -s '$LINES' - 'c[-1,-width]' -s '$COLUMNS' -- show next prev
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
+ -k "(help)" -- rmm
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
+ 's[-]' -k "(after before cc date datefield from help list nolist \
+ public nopublic search sequence subject to zero nozero not or and \
+ lbrace rbrace)" -- pick
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
+ -k "(alias check draft draftfolder draftmessage help nocheck \
+ nodraftfolder)" -- whom
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
+ -k "(file part type list headers noheaders realsize norealsize nolist \
+ show serialonly noserialonly form pause nopause noshow store auto noauto \
+ nostore cache nocache rcache wcache check nocheck ebcdicsafe noebcdicsafe \
+ rfc934mode norfc934mode verbose noverbose help)" - \
+ 'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile - \
+ 'C[-1,-[rw]cache]' -k '(public private never ask)' -- mhn
+
+compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' -k '(help)' -- mhpath
+