#compdef eix eix-diff eix-update
local curcontext="$curcontext" state state_descr line expl
typeset -A opt_args

local service_opts excl_opt ret i

# Options common to diff-eix and eix
service_opts=(
{'(--quick)-Q','(-Q)--quick'}'[do not try to read unguessable slots]'
'--care[always read slots of installed packages]'
'--deps-installed[always read deps of installed packages]'
'--ansi[reset the ansi 256 color palette]'
)

case $service in
(*update*)
	excl_opt='(-)'
	service_opts=(
'(--forcestatus '{'--nostatus)-H','-H)--nostatus'}'[do not update status line]'
'(--nostatus -H)--forcestatus[force status line on non-terminal]'
{'(--output)-o+','(-o)--output'}'[output to FILE]:output_file:_files'
{'*--exclude-overlay','*-x+'}'[OVERLAY (exclude)]:exclude overlay:->overlay'
{'*--add-overlay','*-a+'}'[OVERLAY (add)]:add overlay:_files -/'
{'*--override-method','*-m+'}'[OVERLAY_MASK METHOD (override method)]:overlay mask to change method:->overlay:cache method: '
{'*--repo-name','*-r+'}'[OVERLAY REPO_NAME (set REPO_NAME for OVERLAY)]:overlay to change name:->overlay:repo-name: '
);;
(*diff*)
	excl_opt='(1 2 -)'
	service_opts+=(
'1:old_cache:_files'
'2::new_cache:_files'
);;
(*)
	excl_opt='(* -)'
	service_opts+=(
"$excl_opt"'--print-all-useflags[print all IUSE words]'
"$excl_opt"'--print-all-keywords[print all KEYWORDS words]'
"$excl_opt"'--print-all-slots[print all SLOT strings]'
"$excl_opt"'--print-all-licenses[print all LICENSE strings]'
"$excl_opt"'--print-all-depends[print all *DEPEND words]'
"$excl_opt"'--print-world-sets[print the world sets]'
"$excl_opt"'--print-profile-paths[print the profile paths]'
"$excl_opt"'--256[print all ansi color palettes]'
"$excl_opt"'--256l[print light ansi color palettes]'
"$excl_opt"'--256l0[print light ansi color palette (normal)]'
"$excl_opt"'--256l1[print light ansi color palette (bright)]'
"$excl_opt"'--256d[print dark ansi color palettes]'
"$excl_opt"'--256d0[print dark ansi color palette (normal)]'
"$excl_opt"'--256d1[print dark ansi color palette (bright)]'
"$excl_opt"'--256b[print ansi color palette for background]'
{'(--remote)-R','(-R)--remote'}'[use remote database 1]'
{'(--remote2)-Z','(-Z)--remote2'}'[use remote database 2]'
{'(--versionsort)-x','(-x)--versionsort'}'[sort output by slots/versions]'
{'(--versionlines)-l','(-l)--versionlines'}'[output versions line by line]'
{'(--compact)-c','(-c)--compact'}'[use \$FORMAT_COMPACT]'
{'(--verbose)-v','(-v)--verbose'}'[use \$FORMAT_VERBOSE]'
'--xml[output in xml format]'
{'(--pure-packages)-\\*','(-\\*)--pure-packages'}'[omit printing of overlay names and package number]'
{'(--only-names)-#','(-#)--only-names'}'[print with format \<category\>/\<name\>]'
{'(--brief)-0','(-0)--brief'}'[print at most one package]'
'--brief2[print at most two packages]'
{'(--test-non-matching)-t','(-t)--test-non-matching'}'[check /etc/portage/package.* and installed packages]'
'--cache-file[CACHE_FILE (use instead of /var/cache/eix/portage.eix)]:cache-file:_files'
'--format[FORMAT]:format: '
'--format-compact[FORMAT_COMPACT]:format_compact: '
'--format-verbose[FORMAT_VERBOSE]:format_verbose: '
{'*--not','*-\!'}'[logical negation]'
{'*--and','*-a'}'[logical disjunction]'
{'*--or','*-o'}'[logical conjunction]'
{'*--open','*-\('}'[logical opening brace]'
{'*--close','*-\)'}'[logical closing brace]'
{'*--installed','*-I'}'[test for installed packages]'
{'*--multi-installed','*-i'}'[test for multiple installed packages]'
{'*--dup-packages','*-d'}'[test for duplicate packages]'
{'*--dup-versions','*-D'}'[test for duplicated versions]'
{'*--slotted','*-1'}'[test for nontrivial slots]'
{'*--slots','*-2'}'[test for multiple slots]'
{'*--upgrade','*-u'}'[test for upgradable packages]'
'*--upgrade\+[test for upgradable packages, local]'
'*--upgrade\-[test for upgradable packages, non-local]'
'*--stable[test for stable packages]'
'*--stable+[test for stable packages, local]'
'*--stable-[test for stable packages, non-local]'
'*--testing[test for testing packages]'
'*--testing+[test for testing packages, local]'
'*--testing-[test for testing packages, non-local]'
'*--non-masked[test for non-masked packages]'
'*--non-masked+[test for non-masked packages, local]'
'*--non-masked-[test for non-masked packages, non-local]'
'*--system[test for @system packages]'
'*--system+[test for @system packages, local]'
'*--system-[test for @system packages, non-local]'
'*--installed-unstable[test for installed unstable packages]'
'*--installed-testing[test for installed testing packages]'
'*--installed-masked[test for installed masked packages]'
'*--world[test for @world packages]'
'*--world-file[test for @world-file packages]'
'*--world-set[test for @world-set packages]'
'*--selected[test for @selected packages]'
'*--selected-file[test for @selected-file packages]'
'*--selected-set[test for @selected-set packages]'
'*--binary[test for packages with .tbz2/.xpak]'
'*--multi-binary[NR (test for at least NR of .tbz2/.xpak)]::minimal binaries:(1 2 3 4 5 6 7 8 9)'
{'*--overlay','*-O'}'[test if package is in an overlay]'
'*--in-overlay[OVERLAY (test for packages in OVERLAY)]:overlay for testing:->overlay'
'*--only-in-overlay[OVERLAY (test for packages only in OVERLAY)]:overlay (only) for testing:->overlay'
{'*--installed-overlay','*-J'}'[test if package is installed from an overlay]'
'*--installed-from-overlay[OVERLAY (test for package installed from OVERLAY)]:overlay (installed) for testing:->overlay'
'*--installed-in-overlay[OVERLAY (test for package installed and in OVERLAY)]:overlay (installed and in) for testing:->overlay'
'*--installed-in-some-overlay[test for package installed and in some overlay]'
'*--restrict-fetch[test for RESTRICT=fetch packages]'
'*--restrict-mirror[test for RESTRICT=mirror packages]'
'*--restrict-primaryuri[test for RESTRICT=primaryuri packages]'
'*--restrict-binchecks[test for RESTRICT=binchecks packages]'
'*--restrict-strip[test for RESTRICT=strip packages]'
'*--restrict-test[test for RESTRICT=test packages]'
'*--restrict-userpriv[test for RESTRICT=userpriv packages]'
'*--restrict-installsources[test for RESTRICT=installsources packages]'
'*--restrict-bindist[test for RESTRICT=bindist packages]'
'*--restrict-parallel[test for RESTRICT=parallel packages]'
'*--properties-interactive[test for PROPERTIES=interactive packages]'
'*--properties-live[test for PROPERTIES=live packages]'
'*--properties-virtual[test for PROPERTIES=virtual packages]'
'*--properties-set[test for PROPERTIES=set packages]'
{'*--test-obsolete','*-T'}'[test for packages with obsolete /etc/portage/package.*]'
{'*--pipe','*-\|'}'[test for packages/versions matching stdin]'
'*--pipe-name[test for packages matching stdin]'
'*--pipe-version[test for versions matching stdin]'
{'*--name','*-s'}'[match name]'
{'*--description','*-S'}'[match description]'
{'*--category','*-C'}'[match category]'
{'*--category-name','*-A'}'[match "category/name"]'
{'*--homepage','*-H'}'[match homepage]'
{'*--license','*-L'}'[match license]'
{'*--use','*-U'}'[match IUSE]'
{'*--any','*-y'}'[match any field (same as -SACsHL...)]'
'*--deps[match *DEPEND]'
'*--depend[match DEPEND]'
'*--rdepend[match RDEPEND]'
'*--pdepend[match PDEPEND]'
'*--hdepend[match HDEPEND]'
'*--set[match setname]'
'*--eapi[match EAPI]'
'*--installed-eapi[match installed EAPI]'
'*--slot[match slotname]'
'*--installed-slot[match installed slotname]'
'*--installed-with-use[match installed enabled USE]'
'*--installed-without-use[match installed disabled USE]'
{'*--exact','*-e'}'[pattern is exact string]'
{'*--begin','*-b'}'[pattern is beginning of string]'
'*--end[pattern is end of string]'
{'*--substring','*-z'}'[pattern is substring]'
{'*--fuzzy','*-f+'}'[N (pattern is fuzzy, Levenshtein N)]::number (Levenshtein distance):(1 2 3 4 5 6 7 8 9)'
{'*--pattern','*-p'}'[pattern is wildcard pattern]'
{'*--regex','*-r'}'[pattern is regular expression]'
)
# find out search field and whether to check only installed packages
	local c w is_or local field= installed=
	if ((CURRENT>2))
	then	is_or=:
		case $(PRINT_APPEND=n _call_program default_is_or 'eix --print DEFAULT_IS_OR 2>/dev/null') in
		([nNfF0]*|[oO][fF]*)
			is_or=false;;
		esac
		for ((i=2;i<CURRENT;++i))
		do	case $words[i] in
			(--)
				i=$CURRENT;;
			(--cache-file|--format(-compact|-verbose|)|--(only-|)in-overlay|--installed-(from|in)-overlay|--fuzzy|--print)
				((++i));;
			(--not|--open|--close|---*|[!-])
				if $is_or
				then	field=
					installed=
				fi;;
			(--(multi-|)installed)
				installed='installed';;
			(--category|--name|--description|--homepage|--license)
				field=${words[i]#--};;
			(--category-name)
				field='category/name';;
			(--use|--installed-with(out|)-use)
				field='useflag';;
			(--depend)
				field='depend';;
			(--rdepend)
				field='rdepend';;
			(--pdepend)
				field='pdepend';;
			(--hdepend)
				field='hdepend';;
			(--deps)
				field='deps';;
			(--set)
				field='set';;
			(--eapi)
				field='eapi';;
			(--installed-eapi)
				installed='installed'
				field='eapi';;
			(--slot)
				field='slot';;
			(--installed-slot)
				installed='installed'
				field='slot';;
			(-[!-]*)
				w=$words[$i]
				for ((c=2;c<=$#w;++c))
				do	case $w[c] in
					([f])
						if ((c==$#w))
						then	((++i))
						else	c=$#w
						fi;;
					([\(\)!])
						if $is_or
						then	field=
							installed=
						fi;;
					([iI])
						installed='installed';;
					(C)
						field='category';;
					(s)
						field='name';;
					(S)
						field='description';;
					(A)
						field='category/name';;
					(H)
						field='homepage';;
					(L)
						field='license';;
					esac
				done;;
			esac
		done
	fi
	: ${field:='package'}
	i=($installed $field)
	service_opts+=(
'*:'"$i"':->args'
);;
esac

_arguments -C -s -S : \
"$excl_opt"{'--help','-h'}'[help]' \
"$excl_opt"{'--version','-v'}'[version]' \
"$excl_opt"'--print[print expanded variable value]:variable:->vars' \
"$excl_opt"'--dump[dump variables]' \
"$excl_opt"'--dump-defaults[dump default values of variables]' \
{'(--quiet)-q','(-q)--quiet'}'[no output]' \
'(--forcecolor -F '{'--nocolor)-n','-n)--nocolor'}'[do not use colors in output]' \
'(--nocolor -n '{'--forcecolor)-F','-F)--forcecolor'}'[force color on non-terminal]' \
$service_opts
ret=$?
case $state in
(vars)
	_tags variables
	_tags && {
		_description variables expl 'eix variable name'
		compadd "$expl[@]" - ${(f)"$(_call_program $service-known-vars '$service --known-vars 2>/dev/null')"}
		ret=$?
	};;
(overlay)
	_tags overlays
	_tags && {
		local -ua o
		o=($(PRINT_APPEND= _call_program portdir_overlay 'eix --print PORTDIR_OVERLAY 2>/dev/null'))
		o+=("$(PRINT_APPEND= _call_program portdir 'eix --print PORTDIR 2>/dev/null')")
		o+=({0..$#o})
		_description overlays expl 'overlay'
		compadd "$expl[@]" - $o
		ret=$?
	};;
(args)
	local -a eixopt
	eixopt=('--pure-packages')
	[[ -z $installed ]] || eixopt+=('-I')
	local -x NEWLINE=false CAREMODE=false QUICKMODE=true FORCE_COLORS=false \
		RESTRICT_INSTALLED=false USE_BUILD_TIME=false DEFAULT_FORMAT=normal
	case $field in
	(category)
		_tags categories
		_tags && {
			_description categories expl 'package category'
			compadd "$expl[@]" - $(FORMAT='<category>\n' _call_program packages${installed:+-installed} 'eix $eixopt 2>/dev/null')
		};;
	(name)
		_tags packages
		_tags && {
			_description packages expl 'package name'
			compadd "$expl[@]" - $(FORMAT='<name>\n' _call_program packages${installed:+-installed} 'eix $eixopt 2>/dev/null')
		};;
	(category/name)
		_tags packages
		_tags && {
			_description packages expl 'category/name'
			compadd "$expl[@]" - $(FORMAT='<category>/<name>\n' _call_program packages${installed:+-installed} 'eix $eixopt 2>/dev/null')
		};;
	(package)
		_tags packages
		_tags && case $PREFIX in
		(*/*)
			_description packages expl 'category/name'
			i=${PREFIX%/*}
			compset -P '*/'
			compadd "$expl[@]" - $(FORMAT='<name>\n' _call_program packages-category${installed:+-installed} 'eix $eixopt -C "$i" 2>/dev/null');;
		(*)
			_description packages expl 'package'
			i=($(FORMAT='<category>/<name>\n' _call_program packages${installed:+-installed} 'eix $eixopt 2>/dev/null'))
			compadd "$expl[@]" - ${i:t} ${i%%/*}/
		esac;;
	(useflag)
		_tags useflags
		_tags && {
			_description useflags expl 'useflag'
			compadd "${expl[@]}" - ${$(_call_program useflags 'eix --print-all-useflags 2>/dev/null')##[()+-]#}
		};;
	(license)
		_tags licenses
		_tags && {
			_description licenses expl 'license'
			compadd "${expl[@]}" - ${$(_call_program licenses 'eix --print-all-licenses 2>/dev/null')//([\(\)\|]|[![:space:]]#\?)/}
		};;
	(eapi)
		_tags slots
		_tags && {
			_description slots expl 'eapi'
			compadd "${expl[@]}" - $(_call_program slots 'eix --print-all-eapis 2>/dev/null')
		};;
	(slot)
		_tags slots
		_tags && {
			_description slots expl 'slot'
			compadd "${expl[@]}" - $(_call_program slots 'eix --print-all-slots 2>/dev/null')
		};;
	(homepage)
		_tags homepages
		_tags && {
			_description homepages expl 'homepage'
			compadd "${expl[@]}" - $(FORMAT='<homepage>\n' _call_program homepages 'eix $eixopt 2>/dev/null')
		};;
	(set)
		_tags sets
		_tags && () {
			local -ua o
			local portdir j k
			local -a sets
			o=($(PRINT_APPEND= _call_program portdir_overlay 'eix --print PORTDIR_OVERLAY 2>/dev/null'))
			portdir="$(PRINT_APPEND= _call_program portdir 'eix --print PORTDIR 2>/dev/null')"
			sets=()
			for i in ${="$(PRINT_APPEND= _call_program eix_local_sets 'eix --print EIX_LOCAL_SETS 2>/dev/null')"}
			do	case $i in
				(/*)
					[[ -d $i ]] && sets+=($i);;
				('*'*)
					k=${i#'*'}
					for j in $o
					do	[[ -d "$j$k" ]] && sets+=("$j$k")
					done;;
				(*)	[[ -d "$portdir$i" ]] && sets+=("$portdir$i");;
				esac
			done
			if (($#sets))
			then	_description sets expl 'set'
				compadd "${expl[@]}" - ${${(f)"$(_call_program sets 'find -L $sets -type f -name "[!.]*" -print 2>/dev/null')"}:t}
			fi
		};;
	esac
	ret=$?;;
esac
return ret
