1#autoload
2
3local -a type expl_type_arr rsrc rdst paths_allowed
4local -a typearg datasetlist expl mlist
5local expl_type
6
7# -e takes an argument which is passed as the "descr" argument to _wanted
8# -p indicates that filesystem paths, not just dataset names, are allowed
9# -r1 indicates that we're completing the source of a rename
10# -r2 indicates that we're completing the destination of a rename
11# -t takes arguments (what kinds of datasets) and can appear multiple times
12zparseopts -D -E e:=expl_type_arr p=paths_allowed r1=rsrc r2=rdst t+:=type
13
14[[ -n $type[(r)fs] ]]    && typearg=( filesystem )
15[[ -n $type[(r)vol] ]]   && typearg=( $typearg volume )
16[[ -n $type[(r)snap] ]]  && typearg=( $typearg snapshot )
17[[ -n $type[(r)share] ]]  && typearg=( $typearg share )
18if [[ -n $typearg ]]; then
19	typearg=( -t ${(j:,:)typearg} )
20# We know we're in zfs list if paths_allowed is non-empty.
21elif [[ -n $opt_args[-t] && ${#paths_allowed} -gt 0 ]]; then
22	typearg=( -t $opt_args[-t] )
23fi
24
25if [[ ${#paths_allowed} -gt 0 && $PREFIX == /* ]]; then
26	_path_files
27	return
28fi
29
30if [[ ${#rsrc} -gt 0 ]]; then
31	# With the -r option to zfs rename, we can only rename snapshots.  With the
32	# -p option, we can only rename filesystems and volumes.
33	if [[ -n $words[(r)-r] ]]; then
34		typearg=( -t snapshot )
35	elif [[ -n $words[(r)-p] ]]; then
36		typearg=( -t filesystem,volume )
37	elif [[ $implementation == openzfs ]]; then
38		typearg=( -t filesystem,snapshot,volume )
39	else
40		typearg=( -t filesystem,share,snapshot,volume )
41	fi
42fi
43
44if [[ ${#rdst} -gt 0 ]]; then
45	if [[ ${words[CURRENT - 1]} == *@* ]]; then
46		# If we're renaming snapshots, there's nothing to complete, so
47		# we simply give instructions.  (In non-recursive cases, we
48		# could put the name of the snapshotted dataset first, but why
49		# bother with the long form?)
50		_message -e 'snapshot name (beginning with "@")'
51		return
52	else
53		# The parent dataset must be a filesystem, and can't rename
54		# a dataset into another pool.  Plus we hardcode the expl.
55		typearg=( -t filesystem -r ${${words[CURRENT - 1]}%%/*} )
56		expl_type_arr=( -e "parent dataset" )
57	fi
58fi
59
60if [[ -n $type[(r)clone] ]]; then
61	datasetlist=( ${="$(zfs list -H -o name,origin -t filesystem 2>/dev/null | awk "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} )
62else
63	datasetlist=( ${="$(zfs list -H -o name $typearg 2>/dev/null)":#no datasets available} )
64fi
65
66expl_type=${typearg[2,-1]//,/\/}
67if [[ -n $type[(r)mtpt] ]]; then
68	mlist=( ${="$(zfs list -H -o mountpoint $typearg 2>/dev/null)":#no mountpoints available} )
69	datasetlist=( $datasetlist $mlist )
70	expl_type="$expl_type/mountpoint"
71fi
72
73if [[ -n $expl_type_arr[2] ]]; then
74	expl_type=$expl_type_arr[2]
75fi
76
77_wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist
78