#
# 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 originally 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 \
  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

