components/zsh/Completion/Unix/Type/_zfs_dataset
changeset 904 114a5240af22
parent 429 02007d525e89
child 1625 b35ca5ff8eee
--- a/components/zsh/Completion/Unix/Type/_zfs_dataset	Sat Jun 30 13:01:02 2012 -0700
+++ b/components/zsh/Completion/Unix/Type/_zfs_dataset	Fri Jun 29 21:49:03 2012 -0700
@@ -1,13 +1,19 @@
 #autoload
 
-local -a type paths_allowed typearg datasetlist expl
+local -a type expl_type_arr rsrc rdst paths_allowed
+local -a typearg datasetlist expl mlist
 local expl_type
 
-zparseopts -D -E t+:=type p=paths_allowed
+# -e takes an argument which is passed as as the "descr" argument to _wanted
+# -p indicates that filesystem paths, not just dataset names, are allowed
+# -r1 indicates that we're completing the source of a rename
+# -r2 indicates that we're completing the destination of a rename
+# -t takes arguments (what kinds of datasets) and can appear multiple times
+zparseopts -D -E e:=expl_type_arr p=paths_allowed r1=rsrc r2=rdst t+:=type
 
-[[ -n $type[(r)fs] ]]   && typearg=( filesystem )
-[[ -n $type[(r)vol] ]]  && typearg=( $typearg volume )
-[[ -n $type[(r)snap] ]] && typearg=( $typearg snapshot )
+[[ -n $type[(r)fs] ]]    && typearg=( filesystem )
+[[ -n $type[(r)vol] ]]   && typearg=( $typearg volume )
+[[ -n $type[(r)snap] ]]  && typearg=( $typearg snapshot )
 if [[ -n $typearg ]]; then
 	typearg=( -t ${(j:,:)typearg} )
 # We know we're in zfs list if paths_allowed is non-empty.
@@ -20,7 +26,39 @@
 	return
 fi
 
-datasetlist=( ${="$(zfs list -H -o name $typearg)":#no datasets available} )
+if [[ ${#rsrc} -gt 0 ]]; then
+	# With the -r option to zfs rename, we can only rename snapshots.  With the
+	# -p option, we can only rename filesystems and volumes.
+	if [[ -n $words[(r)-r] ]]; then
+		typearg=( -t snapshot )
+	elif [[ -n $words[(r)-p] ]]; then
+		typearg=( -t filesystem,volume )
+	else
+		typearg=( -t filesystem,snapshot,volume )
+	fi
+fi
+
+if [[ ${#rdst} -gt 0 ]]; then
+	if [[ ${words[CURRENT - 1]} == *@* ]]; then
+		# If we're renaming snapshots, there's nothing to complete, so
+		# we simply give instructions.  (In non-recursive cases, we
+		# could put the name of the snapshotted dataset first, but why
+		# bother with the long form?)
+		_message -e 'snapshot name (beginning with "@")'
+		return
+	else
+		# The parent dataset must be a filesystem, and can't rename
+		# a dataset into another pool.  Plus we hardcode the expl.
+		typearg=( -t fs -r ${${words[CURRENT - 1]}%%/*} )
+		expl_type_arr=( -e "parent dataset" )
+	fi
+fi
+
+if [[ -n $type[(r)clone] ]]; then
+	datasetlist=( ${="$(zfs list -H -o name,origin -t fs | awk "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} )
+else
+	datasetlist=( ${="$(zfs list -H -o name $typearg)":#no datasets available} )
+fi
 
 expl_type=${typearg[2,-1]//,/\/}
 if [[ -n $type[(r)mtpt] ]]; then
@@ -29,4 +67,8 @@
 	expl_type="$expl_type/mountpoint"
 fi
 
+if [[ -n $expl_type_arr[2] ]]; then
+	expl_type=$expl_type_arr[2]
+fi
+
 _wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist