about summary refs log tree commit diff
path: root/Completion/Unix/Type
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Unix/Type')
-rw-r--r--Completion/Unix/Type/_baudrates5
-rw-r--r--Completion/Unix/Type/_canonical_paths3
-rw-r--r--Completion/Unix/Type/_diff_options66
-rw-r--r--Completion/Unix/Type/_ldap_attributes27
-rw-r--r--Completion/Unix/Type/_ldap_filters91
-rw-r--r--Completion/Unix/Type/_path_commands13
-rw-r--r--Completion/Unix/Type/_path_files2
-rw-r--r--Completion/Unix/Type/_ssh_hosts11
-rw-r--r--Completion/Unix/Type/_time_zone3
-rw-r--r--Completion/Unix/Type/_umountable10
-rw-r--r--Completion/Unix/Type/_zfs_dataset15
-rw-r--r--Completion/Unix/Type/_zfs_keysource_props15
12 files changed, 195 insertions, 66 deletions
diff --git a/Completion/Unix/Type/_baudrates b/Completion/Unix/Type/_baudrates
index a9d7fe541..416a4919f 100644
--- a/Completion/Unix/Type/_baudrates
+++ b/Completion/Unix/Type/_baudrates
@@ -72,6 +72,7 @@ if (( ${+opts[-f]} )); then
   done
 fi
 
-# -1 removes dupes (which there shouldn't be)
-_description -1 -o numeric baud-rates expl 'baud rate'
+# -1V removes dupes (which there shouldn't be) and otherwise leaves the
+# order in the $rates array intact.
+_description -1V baud-rates expl 'baud rate'
 compadd "${argv[@]}" "$expl[@]" -- "${rates[@]}"
diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index a8fbbb524..1444bc165 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -42,7 +42,8 @@ _canonical_paths_add_paths () {
     # ### Ideally, this codepath would do what the 'if' above does,
     # ### but telling compadd to pretend the "word on the command line"
     # ### is ${"the word on the command line"/$origpref/$canpref}.
-    matches+=(${${(M)files:#$canpref*}/$canpref/$origpref})
+    # ### The following approximates that.
+    matches+=(${(q)${(M)files:#$canpref*}/$canpref/$origpref})
   fi
 
   for subdir in $expref?*(@); do
diff --git a/Completion/Unix/Type/_diff_options b/Completion/Unix/Type/_diff_options
index dfa9889f2..03ea1d7fe 100644
--- a/Completion/Unix/Type/_diff_options
+++ b/Completion/Unix/Type/_diff_options
@@ -1,6 +1,6 @@
 #autoload
 
-local of ofwuc ouc oss ofwy ofwg ofwl cmd variant
+local of ofwuc ouc oss ofwy ofwg ofwl cmd variant ign
 local -a args
 
 cmd="$1"
@@ -25,7 +25,10 @@ _diff_palette() {
   return ret
 }
 
-if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->.* ]]; then
+if _pick_variant -r variant -c $cmd gnu=GNU unix -v ||
+  [[ $OSTYPE = (freebsd<12->|darwin<22->).* ]]; then
+  (( $#words > 2 )) && ign='!'
+
   # output formats
   of="-y --side-by-side -n --rcs -e -f --ed -q --brief -c -C --context -u -U \
   --unified --old-group-format --new-group-format --changed-group-format \
@@ -61,29 +64,28 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->
   --unchanged-group-format"
 
   if [[ $variant = gnu ]]; then
-    (( $#words > 2 )) || args+=(
-      '(-v --version)'{-v,--version}'[display version information]'
-      '--help[display usage information]'
-    )
     args+=(
       '(-H --speed-large-files)'{-H,--speed-large-files}'[assume large files and many small changes]'
       '(-E --ignore-tab-expansion)'{-E,--ignore-tab-expansion}'[ignore changes due to tab expansion]'
       '(-Z --ignore-trailing-space)'{-Z,--ignore-trailing-space}'[ignore white space at line end]'
-      "($ofwuc $oss -F --show-function-line)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex'
       "($ofwy $ouc)--left-column[output only left column of common lines]"
       "($ofwg $ouc $oss)--old-group-format=[set old group format]:old group format"
       "($ofwg $ouc $oss)--new-group-format=[set new group format]:new group format"
       "($ofwl $ouc $oss)--unchanged-line-format=[set unchanged line format]:unchanged line format"
-      '(--to-file)--from-file=[compare specified file to all operands]:from file:_files' \
-      '(--from-file)--to-file=[compare all operands to specified file]:to file:_files' \
-      '--color=-[use colors in output]::when [auto]:(never always auto)'
+      '(--to-file)--from-file=[compare specified file to all operands]:from file:_files'
+      '(--from-file)--to-file=[compare all operands to specified file]:to file:_files'
       '--palette=[specify colors to use]:color:_diff_palette'
+      "${ign}(1 2)-v[display version information]"
     )
   else
     args+=( '!--speed-large-files' )
+    if [[ $OSTYPE = darwin<22->.* ]]; then
+      args+=( '(-A --algorithm)'{-A+,--algorithm=}'[specify the algorithm to use]:algorithm:(myers patience stone)' )
+    fi
   fi
 
   _arguments -s $args \
+    '--color=-[use colors in output]::when [auto]:(never always auto)' \
     '(-i --ignore-case)'{-i,--ignore-case}'[case insensitive]' \
     '--ignore-file-name-case[ignore case when comparing file names]' \
     '!(--ignore-file-name-case)--no-ignore-file-name-case' \
@@ -99,6 +101,7 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->
     "($of $oss)-u[output a unified diff]" \
     "($ofwuc $oss)*"{-L+,--label=}'[set label to use instead of file name and timestamp]:label' \
     "($ofwuc $oss -p --show-c-function)"{-p,--show-c-function}'[show C function of each change]' \
+    "($ofwuc $oss -F --show-function-line)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex' \
     "($of $ouc $oss)"{-q,--brief}'[output only whether files differ]' \
     "($of $ouc $oss -e --ed)"{--ed,-e}'[output an ed script]' \
     "!($of $ouc $oss)--normal" \
@@ -127,39 +130,52 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->
     "($of $ouc)"{-y,--side-by-side}'[output in two columns]' \
     "($ofwy $ouc)--suppress-common-lines[don't output common lines]" \
     "($ofwy $ouc --width -W)"{--width=,-W+}'[set size of line]:number of characters per line' \
+    "${ign}(1 2)--version[display version information]" \
+    "${ign}(1 2)--help[display usage information]" \
     "$@"
 else
   of='-c -e -f'
   case $OSTYPE in
     openbsd*|solaris2.<9->)
       of+=' -u -U'
+    ;|
+    openbsd*|solaris*)
+      of+=' -n -C -D'
+    ;|
+    solaris*)
+      of+=' -h'
+    ;|
+    openbsd*)
+      of+=' -q'
+    ;|
+    # modifications to "$of" should be done above this line so that it is
+    # uniformly defined while constructing $args
+    openbsd*|solaris2.<9->)
       args+=(
-	"($of)-u[output a unified diff]"
-	"($of)-U+[output a unified diff]:lines of context"
+        "($of)-u[output a unified diff]"
+        "($of)-U+[output a unified diff]:lines of context"
       )
     ;|
     openbsd*|solaris*)
       args+=(
-	"($of)-C+[output a context diff]:lines of context"
-	"($of)-D+[output merged file with preprocessor directives]:preprocessor symbol"
-	'-i[case insensitive]'
-	'-l[long output format (paginate with pr(1))]'
-	'-s[report on identical files]'
-	'-t[expand tabs in output lines]'
+        "($of)-C+[output a context diff]:lines of context"
+        "($of)-D+[output merged file with preprocessor directives]:preprocessor symbol"
+        '-i[case insensitive]'
+        '-s[report on identical files]'
+        '-t[expand tabs in output lines]'
       )
     ;|
     solaris*)
-      of+=' -h -n'
       args+=(
-	'-w[ignore all white space]'
-	"($of)-h[do a fast, half-hearted job]"
-	"($of)-n[output a reversed ed script]"
+        '-w[ignore all white space]'
+        "($of)-h[do a fast, half-hearted job]"
+        "($of)-n[output a reversed ed script]"
         '-S+[set first file in comparison]:start with file:_files'
+        '-l[long output format (paginate with pr(1))]'
       )
     ;;
     openbsd*)
-      of+=' -n -q -u -C -D -U'
-      args=(
+      args+=(
         "($of)-n[output an rcsdiff(1)-compatible diff]"
         "($of)-q[only print a line when the files differ; does not produce a list of changes]"
         '-a[treat all files as ASCII text]'
@@ -173,7 +189,7 @@ else
         '-P[treat absent files in the second directory as if they were empty]'
         '-S[start a directory diff from a file name]:file name:_files'
         '*-X[exclude files and subdirectories whose basenames match lines in a file]:file name:_files'
-        '-x[exclude files and subdirectories whose basenames match a pattern]:pattern'
+        '*-x[exclude files and subdirectories whose basenames match a pattern]:pattern'
       )
     ;;
   esac
diff --git a/Completion/Unix/Type/_ldap_attributes b/Completion/Unix/Type/_ldap_attributes
new file mode 100644
index 000000000..0711cfbf1
--- /dev/null
+++ b/Completion/Unix/Type/_ldap_attributes
@@ -0,0 +1,27 @@
+#autoload
+
+local -a expl attrs
+
+# These come from dumping attributes from basic installations of both openldap
+# and FreeIPA and combining results. It is possible to have custom additions so
+# a definitive list is not possible Hence the use of -x with compadd.
+#
+attrs=(
+  associatedDomain authenticationMethod automountInformation automountKey
+  automountMapName bindTimeLimit cACertificate;binary cn dc defaultSearchBase
+  defaultServerList description displayName dn followReferrals gecos gidNumber
+  givenName homeDirectory info initials ipaCertIssuerSerial ipaCertSubject
+  ipaConfigString ipaKeyExtUsage ipaKeyTrust ipaNTSecurityIdentifier
+  ipaPublicKey ipaUniqueID ipHostNumber loginShell mail member memberUid
+  mepManagedBy nisDomain nisNetgroupTriple o objectClass objectClassMap ou
+  pwdAllowUserChange pwdAttribute pwdCheckQuality pwdExpireWarning
+  pwdFailureCountInterval pwdGraceAuthNLimit pwdInHistory pwdLockout
+  pwdLockoutDuration pwdMaxAge pwdMaxFailure pwdMinAge pwdMinLength
+  pwdMustChange pwdSafeModify searchTimeLimit serviceSearchDescriptor sn
+  telephoneNumber uid uidNumber userCertificate;binary userPKCS12
+  userSMIMECertificate
+)
+
+_description ldap-attributes expl "ldap attribute"
+compadd "${@:/-X/-x}" "${expl[@]:/-X/-x}" \
+    -M 'm:{a-zA-Z}={A-Za-z} r:[^A-Z]||[A-Z]=* r:|=*' -a attrs
diff --git a/Completion/Unix/Type/_ldap_filters b/Completion/Unix/Type/_ldap_filters
new file mode 100644
index 000000000..5e0e30f01
--- /dev/null
+++ b/Completion/Unix/Type/_ldap_filters
@@ -0,0 +1,91 @@
+#autoload
+
+# LDAP search filters conforming to RFC4515
+
+local -a expl excl optype disp end pre
+local -i nest=0
+local open='(' close=')' andop='&' orop='|'
+
+[[ -prefix - ]] && return 1
+
+local -a matchingrules=( # From RFC4517
+  bitStringMatch booleanMatch caseExactIA5Match
+  caseExactMatch caseExactOrderingMatch caseExactSubstringsMatch
+  caseIgnoreIA5Match caseIgnoreIA5SubstringsMatch caseIgnoreListMatch
+  caseIgnoreListSubstringsMatch caseIgnoreMatch caseIgnoreOrderingMatch
+  caseIgnoreSubstringsMatch directoryStringFirstComponentMatch
+  distinguishedNameMatch generalizedTimeMatch generalizedTimeOrderingMatch
+  integerFirstComponentMatch integerMatch integerOrderingMatch keywordMatch
+  numericStringMatch numericStringOrderingMatch numericStringSubstringsMatch
+  objectIdentifierFirstComponentMatch objectIdentifierMatch octetStringMatch
+  octetStringOrderingMatch telephoneNumberMatch telephoneNumberSubstringsMatch
+  uniqueMemberMatch wordMatch
+)
+local -a classes=( # Sampled from real servers, arbitrary other values allowed
+  automount automountMap cosTemplate dcObject device dnaSharedConfig domain
+  domainRelatedObject DUAConfigProfile extensibleObject groupOfNames
+  groupOfPrincipals ieee802device inetOrgPerson inetuser ipaassociation ipaca
+  ipacaacl ipaCertificate ipaCertMapConfigObject ipacertprofile ipaConfigObject
+  ipaDomainIDRange ipaDomainLevelConfig ipaGuiConfig ipahbacrule ipahbacservice
+  ipahbacservicegroup ipahost ipahostgroup ipaIDrange ipaKeyPolicy
+  ipakrbprincipal ipaNameResolutionData ipaNTDomainAttrs ipaNTGroupAttrs
+  ipaNTUserAttrs ipaobject ipaPublicKeyObject ipaReplTopoManagedServer
+  ipaservice ipaSshGroupOfPubKeys ipasshhost ipasshuser ipasudorule
+  ipaSupportedDomainLevelConfig ipaTrustedADDomainRange ipaUserAuthTypeClass
+  ipausergroup ipHost krbContainer krbprincipal krbprincipalaux
+  krbrealmcontainer krbTicketPolicyAux mepManagedEntry mepOriginEntry
+  nestedGroup nisDomainObject nisNetgroup nsContainer nsDS5Replica nshost
+  organization organizationalPerson organizationalRole organizationalUnit
+  person pilotObject pkiCA pkiuser posixAccount posixGroup pwdPolicy
+  shadowAccount simpleSecurityObject top
+)
+
+compquote open close andop orop
+open=${(q)open} close=${(q)close}
+# default to double rather than backslash quoting
+[[ -z $compstate[quote] && -z $PREFIX ]] && pre='"('
+
+zstyle -s ":completion:${curcontext}:operators" list-separator sep || sep=--
+print -v disp -f "%s $sep %s" \| or \& and \! not
+end=( ") $sep end" )
+excl=( ! \\\| \& ) # compadd -F uses globs: only | needs quoting
+
+local -a query=(
+  \( /$'*\0[ \t\n]#'/ \) # strip off any preceding arguments
+  \(
+    \( "/${open}!/" -'optype[++nest]=1;pre=""'
+    \| "/${open}${(q)orop}/" -'optype[++nest]=2;pre=""'
+    \| "/${open}${andop}/" -'optype[++nest]=3;pre=""'
+    \| '/[]/' ':operators:operator:compadd -F "( ${(q)excl[optype[nest]]} )" -d disp -P ${pre:-${(Q)open}} -S ${(Q)open} \| \& \!' \)
+  \|
+    \( "/${open}[^\\)]##/" "%$close%" # pass over whole var=value, needed due to lack of backtracking after the following
+    \| "/${open}(#i)homeDirectory=/" '/[]/' ':directories:directory:_directories -P / -W / -r ") \t\n\-"'
+    \| "/${open}(#i)loginShell=/" '/[]/' ':shells:shell:compadd -S ${(Q)close} ${(f)^"$(</etc/shells)"}(N)'
+    \| "/${open}(#i)mail=/" '/[]/' ':email-addresses:mail:_email_addresses -S ${(Q)close}'
+    \| "/${open}(#i)objectClass=/" '/[]/' ':object-classes:class:compadd -S ${(Q)close} -M "m:{a-zA-Z}={A-Za-z} r:[^A-Z]||[A-Z]=* r:|=*" -a classes'
+    \| "/${open}(#i)(automountKey|(member|)uid)=/" '/[]/' ':users:username:_users -S ${(Q)close}'
+    \| "/${open}(#i)cn=/" '/[]/' ':cn:cn: _alternative "users:user:_users -S ${close}" "groups:group:_groups -S ${close}" "hosts:host:_hosts -S ${close}"'
+    \|
+      '/[^:=<>~]##/' '%[=:<>~]%' -'pre=""'
+      ':object-types:object type:_ldap_attributes -P ${pre:-${(Q)open}}  -S = -r ":=~<> \t\n\-"'
+      \(
+        '/:/'
+        '/[^:]##:=/' ':matching-rules:matching rule:compadd -S ":=" -a matchingrules'
+      \|
+        '/([~<>]|)=/' ':operators:operator:compadd -S "" "<=" \>= \~='
+      \)
+      '/[^\\)]##/' "%$close%" ': _message -e object-values "object value (* for presence check)"'
+    \)
+    "/$close/" -'(( nest ))' ':brackets:bracket:compadd ${=query[nest]:+-S ""} \)'
+    \(
+      # This use of -P/-d and an empty match works around a limitation/bug where
+      # mixed use of -P removes any quoting
+      "/$close/" ':operators:operator:compadd ${=query[nest-1]:+-S ""} -d end -P ${(Q)close} ""'
+      \( // -'(( --nest ))' \| '//' -'((!nest))' '/[]/' ': compadd ""' \)
+    \) \#
+    // -'(( nest && optype[nest] > 1 ))'
+  \) \#
+)
+
+_regex_arguments _ldap_search_filters "$query[@]"
+_ldap_search_filters
diff --git a/Completion/Unix/Type/_path_commands b/Completion/Unix/Type/_path_commands
index 66795ae0f..4d5a6c5af 100644
--- a/Completion/Unix/Type/_path_commands
+++ b/Completion/Unix/Type/_path_commands
@@ -87,18 +87,19 @@ fi
 # 'if' block move up to the "_command_names -" branch of _command_names?
 if [[ -o path_dirs ]]; then
   local -a path_dirs
-  path_dirs=(${^path}/*(/N:t))
-  (( ${#path_dirs} )) &&
-  _wanted path-dirs expl 'directory in path' compadd "$@" -a path_dirs && ret=0
 
   if [[ $PREFIX$SUFFIX = */* ]]; then
+    path_dirs=( ${path:#.} )
     # Find command from path, not hashed
-    _wanted commands expl 'external command' _path_files -W path -g '*(*)' &&
-    ret=0
+    _wanted commands expl 'external command' _path_files -W path_dirs -g '*(-*)' && ret=0
+  else
+    path_dirs=(${^path}/*(/N:t))
+    (( ${#path_dirs} )) &&
+        _wanted path-dirs expl 'directory in path' compadd "$@" -S / -a path_dirs && ret=0
   fi
 fi
 
-return $ret
+return ret
 }
 
 _path_commands "$@"
diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files
index 06d9d8d51..d46dcbe5a 100644
--- a/Completion/Unix/Type/_path_files
+++ b/Completion/Unix/Type/_path_files
@@ -734,7 +734,7 @@ for prepath in "$prepaths[@]"; do
 	      compadd "$tmp4[@]" -s "${Uopt:+$ISUFFIX}" $listopts - "$tmpdisp"
 	    done
           else
-            [[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:s./.*/}*"
+            [[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:gs./.*/}*"
 
             for i in "$tmp1[@]"; do
 	      _list_files i "$prepath$realpath$testpath"
diff --git a/Completion/Unix/Type/_ssh_hosts b/Completion/Unix/Type/_ssh_hosts
index a4a08ad91..b50e1c16a 100644
--- a/Completion/Unix/Type/_ssh_hosts
+++ b/Completion/Unix/Type/_ssh_hosts
@@ -24,7 +24,7 @@ if [[ -r $config ]]; then
   while (( idx <= $#lines )); do
     IFS=$'=\t ' read -r key line <<<"${lines[idx]}"
     if [[ "$key" == ((#i)match) ]]; then
-      match_args=(${(z)line})
+      match_args=( ${(Z.C.)line} )
       while [[ $#match_args -ge 2 ]]; do
 	if [[ "${match_args[1]}" == (#i)(canonical|final|(|original)host) ]]; then
 	  key="Host"
@@ -36,13 +36,10 @@ if [[ -r $config ]]; then
     fi
     case "$key" in
     ((#i)include)
-      lines[idx]=("${(@f)$(cd $HOME/.ssh; cat ${(z)~line})}") 2>/dev/null;;
+      lines[idx]=( "${(@f)$(cd $HOME/.ssh; cat ${(Z.C.)~line} 2>/dev/null)}" ) ;;
     ((#i)host(|name))
-      for host in ${(z)line}; do
-	case $host in
-	(*[*?]*) ;;
-	(*) config_hosts+=("$host") ;;
-	esac
+      for host in ${(Z.C.)line}; do
+        [[ $host != *[*?%]* ]] && config_hosts+=( $host )
       done ;&
     (*) (( ++idx ));;
     esac
diff --git a/Completion/Unix/Type/_time_zone b/Completion/Unix/Type/_time_zone
index cd924bbc7..a7b63adcd 100644
--- a/Completion/Unix/Type/_time_zone
+++ b/Completion/Unix/Type/_time_zone
@@ -6,4 +6,5 @@ if (( ! $+_zoneinfo_dirs )); then
   _zoneinfo_dirs=( /usr/{share,lib,share/lib}/{zoneinfo*,locale/TZ}(/) )
 fi
 
-_wanted time-zones expl 'time zone' _files -W _zoneinfo_dirs "$@" -
+_wanted time-zones expl 'time zone' \
+  _files -g '[A-Z]*' -M 'm:{a-z}={A-Z}' -W _zoneinfo_dirs "$@" -
diff --git a/Completion/Unix/Type/_umountable b/Completion/Unix/Type/_umountable
index 7ffce5bb4..0111555b6 100644
--- a/Completion/Unix/Type/_umountable
+++ b/Completion/Unix/Type/_umountable
@@ -1,15 +1,21 @@
 #autoload
 local tmp
-local dev_tmp dpath_tmp mp_tmp mline
+local -a dev_tmp dpath_tmp mp_tmp mline
 
 case "$OSTYPE" in
-linux*|irix*)
+linux*)
+  tmp=( "${(@f)$(< /proc/self/mounts)}" )
+  dev_tmp=( "${(@)${(@)tmp%% *}:#none}" )
+  mp_tmp=( "${(@)${(@)tmp#* }%% *}" )
+  ;;
+irix*)
   tmp=( "${(@f)$(< /etc/mtab)}" )
   dev_tmp=( "${(@)${(@)tmp%% *}:#none}" )
   mp_tmp=( "${(@)${(@)tmp#* }%% *}" )
   ;;
 freebsd*|dragonfly*)
   /sbin/mount | while read mline; do
+    [[ $mline[(w)1] = map ]] && continue
     dev_tmp+=( $mline[(w)1] )
     mp_tmp+=( $mline[(w)3] )
   done
diff --git a/Completion/Unix/Type/_zfs_dataset b/Completion/Unix/Type/_zfs_dataset
index 63384afc6..7edcfd5d7 100644
--- a/Completion/Unix/Type/_zfs_dataset
+++ b/Completion/Unix/Type/_zfs_dataset
@@ -11,10 +11,12 @@ local expl_type
 # -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)share] ]]  && typearg=( $typearg share )
+[[ -n $type[(r)fs] ]] && typearg=( filesystem )
+[[ -n $type[(r)vol] ]] && typearg+=( volume )
+[[ -n $type[(r)snap] ]] && typearg+=( snapshot )
+[[ -n $type[(r)share] && $implementation = solaris ]] && typearg+=( share )
+[[ -n $type[(r)bookmark] && $implementation = openzfs ]] &&
+    typearg+=( bookmark )
 if [[ -n $typearg ]]; then
 	typearg=( -t ${(j:,:)typearg} )
 # We know we're in zfs list if paths_allowed is non-empty.
@@ -58,7 +60,7 @@ if [[ ${#rdst} -gt 0 ]]; then
 fi
 
 if [[ -n $type[(r)clone] ]]; then
-	datasetlist=( ${(f)"$(zfs list -H -o name,origin -t filesystem 2>/dev/null | awk -F $'\t' "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} )
+  datasetlist=( ${(f)"$(zfs list -H -o name,origin -t filesystem 2>/dev/null | awk -F$'\t' "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} )
 else
 	datasetlist=( ${(f)"$(zfs list -H -o name $typearg 2>/dev/null)":#no datasets available} )
 fi
@@ -74,4 +76,5 @@ if [[ -n $expl_type_arr[2] ]]; then
 	expl_type=$expl_type_arr[2]
 fi
 
-_wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist
+_description datasets expl "$expl_type"
+_multi_parts "$@" "$expl[@]" -q / datasetlist
diff --git a/Completion/Unix/Type/_zfs_keysource_props b/Completion/Unix/Type/_zfs_keysource_props
deleted file mode 100644
index 01f63257a..000000000
--- a/Completion/Unix/Type/_zfs_keysource_props
+++ /dev/null
@@ -1,15 +0,0 @@
-#autoload
-
-local -a suf
-local expl
-
-compset -S ",*" || suf=(-S ,)
-if compset -P 1 "*,"; then
-	_alternative "zfs-keylocator-prompt:\"prompt\" locator:(prompt)" \
-		"zfs-keylocator-file:file locator:_path_files" \
-		"zfs-keylocator-pkcs11:PKCS#11 locator: " \
-		"zfs-keylocator-https:HTTPS URL locator: "
-else
-	_description format expl "keysource format"
-	compadd $suf -q "$expl[@]" "$@" raw hex passphrase
-fi