#compdef vi ex vim view gvim gview evim eview rvim rview rgvim rgview vimdiff gvimdiff

_netrw_urls () {
  local precedence_char_for_port alternative_args
  local expl suf ret=1

  case "$scheme" in
    ftp)
      precedence_char_for_port='#'
      ;&
    fetch)
      precedence_char_for_port+=':'
      ;&
    http|rcp|rsync|scp|sftp)
      alternative_args=( 'users:user:_remote_users -qS@' )
      ;&
    dav)
      alternative_args=( "hosts:host:_remote_hosts -S/ -r '$precedence_char_for_port'" $alternative_args )
      if compset -P 1 '*/'; then
	_remote_files
      elif [[ $scheme == (fetch|ftp) ]] && compset -P "*[$precedence_char_for_port]"; then
	suf=( -S '' )
	compset -S '/*' || suf=( -S / -r / )
	_ports $suf
      elif compset -P '*@'; then
	suf=( -S '' )
	compset -S '/*' || suf=( -S / -r "$precedence_char_for_port" )
	_wanted hosts expl host _remote_hosts "$suf[@]"
      else
	_alternative $alternative_args
      fi
      ;;
    file)
      if [[ -prefix ''(|127.0.0.1|localhost)/ ]]; then
	compset -P '(127.0.0.1|localhost)'
	_tags -C file files
	while _tags; do
	  while _next_label files expl 'local file'; do
	    if [[ -prefix / ]]; then
	      _path_files "$expl[@]" -S '' -g '*(^/)' && ret=0
	      _path_files "$expl[@]" -S/ -r '/' -/ && ret=0
	    elif [[ -z "$PREFIX" ]]; then
	      compadd -S '/' -r '/' "$expl[@]" "$@" - "${PWD%/}" && ret=0
	    fi
	  done
	  (( ret )) || return 0
	done
	return 1
      elif [[ -prefix '' ]]; then
	_wanted -C "$scheme" prefixes expl 'end of prefix' compadd -S '' "$@" /
      else
	_wanted -C "$scheme" prefixes expl 'localhost' compadd -S / "$@" 127.0.0.1 localhost
      fi
      ;;
    *)
      PREFIX="$IPREFIX$PREFIX"
      IPREFIX=
      _files
  esac
}

_remote_users () {
  _combination -s '[:@]' my-accounts users-hosts users "$@"
}

_remote_hosts () {
  if [[ "$IPREFIX" == *@ ]]; then
    _combination -s '[:@]' my-accounts users-hosts "users=${IPREFIX/@}" hosts "$@"
  else
    _combination -s '[:@]' my-accounts users-hosts hosts "$@"
  fi
}

_remote_files () {
  local expl remfiles remdispf remdispd suf ret=1

  if zstyle -T ":completion:${curcontext}:files" remote-access; then
    case "$scheme" in
      dav)
	;&
      fetch)
	;&
      ftp)
	;&
      http)
	;&
      rcp)
	;&
      rsync)
	_message -e remote-files 'remote file'
	;;
      scp)
	remfiles=(${(M)${(f)"$(_call_program ${scheme}_files ssh -a -x ${${IPREFIX#$scheme://}%/} "ls -d1F ${(Q)PREFIX%%[^./][^/]#}\*" 2>/dev/null)"}%%[^/]#(|/)})
	;;
      sftp)
	_message -e remote-files 'remote file'
	;;
    esac

    compset -P '*/'
    compset -S '/*' || suf='remote file'

    remdispf=(${remfiles:#*/})
    remdispd=(${(M)remfiles:#*/})

    _tags files
    while _tags; do
      while _next_label files expl ${suf:-remote directory}; do
        [[ -n $suf ]] && compadd "$@" "$expl[@]" -d remdispf \
            ${(q)remdispf%[*=@|]} && ret=0 
        compadd ${suf:+-S/} "$@" "$expl[@]" -d remdispd \
            ${(q)remdispd%/} && ret=0
      done
      (( ret )) || return 0
    done
  else
    _message -e remote-files 'remote file'
  fi
}

local curcontext="$curcontext" state ret=1
local scheme

_arguments -C -s \
  '-g[Run using GUI]' \
  '(-f --nofork)'{-f,--nofork}'[Foreground: Don''t fork when starting GUI]' \
  '(   -e -s -d -y -R -Z)-v[Vi mode]' \
  '(-v    -s -d -y -R -Z)-e[Ex mode]' \
  '(-v -e    -d -y -R -Z)-s[Silent batch mode]' \
  '(-v -e -s    -y -R -Z)-d[Diff mode]' \
  '(-v -e -s -d    -R -Z)-y[Easy mode]' \
  '(-v -e -s -d -y    -Z)-R[Readonly mode]' \
  '(-v -e -s -d -y -R   )-Z[Restricted mode]' \
  '(   -M)-m[Modifications (writing files) not allowed]' \
  '(-m   )-M[Modifications in test allowed]' \
  '(   -l)-b[Binary mode]' \
  '(-b   )-l[Lisp mode]' \
  '(   -N)-C[Compatible with Vi: compatible]' \
  '(-C   )-N[Not fully Vi compatible: nocompatible]' \
  '-V-[Verbose]::verbose:' \
  '-D[Debugging mode]' \
  '-n[No swap file, use memory only]' \
  '(-r -L)'{-r,-L}'[Recover crashed session/List swap file]:recover file:_files' \
  '(   -H -F)-A[start in Arbic mode]' \
  '(-A    -F)-H[start in Hebrew mode]' \
  '(-A -H   )-F[start in Farsi mode]' \
  '-T[Set terminal type]:terminal type:' \
  '-u[Use instead of any .vimrc ...]:vimrc file:_files' \
  '--noplugin[Do not load plugin scripts]' \
  '-o-[Open windows]::windows count:(0 1 2 3 4 5 6 7 8 9)' \
  '-O-[Open windows but split vertically]:windows count:(0 1 2 3 4 5 6 7 8 9)' \
  '--cmd[Execute command before loading any vimrc file]:command:' \
  '-c[Execute command after loading the first file]:command:' \
  '-S[Source file session after loading the first file]:session:' \
  '-s[Read Normal mode commands from file scriptin]:scriptin:' \
  '-w[Append all typed commands to file scriptout]:scriptout:' \
  '-W[Write all typed commands to file scriptout]:scriptout:' \
  '-x[Edit encrypted files]' \
  '-X[Do not connect to X server]' \
  '-i[Use instead of .viminfo ...]:viminfo:' \
  '(-h --help)'{-h,--help}'[display help message]' \
  '*:file:->file' && ret=0

case $state in
file)
  if compset -P 1 '*://'; then
    scheme="${IPREFIX%://}"
    _netrw_urls && ret=0
  else
    _files && ret=0
  fi
  ;;
esac

return ret
