about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Completion/Solaris/Command/_pfexec12
-rw-r--r--Completion/Unix/Command/_doas21
-rw-r--r--Completion/Unix/Command/_su6
-rw-r--r--Completion/Unix/Command/_sudo14
-rw-r--r--Completion/Zsh/Type/_command_names19
6 files changed, 57 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 56934bc46..ed2a63b00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2020-03-11  dana  <dana@dana.is>
+
+	* 45424 (tweaked): Completion/Solaris/Command/_pfexec,
+	Completion/Unix/Command/_doas, Completion/Unix/Command/_su,
+	Completion/Unix/Command/_sudo, Completion/Zsh/Type/_command_names:
+	Add **/sbin to PATH when completing commands like sudo
+
 2020-03-10  Romain Porte  <debian@microjoe.org>
 
 	* 45524: Completion/Debian/Command/_dscverify: Add completion
diff --git a/Completion/Solaris/Command/_pfexec b/Completion/Solaris/Command/_pfexec
index 2519c3cdc..e90f33222 100644
--- a/Completion/Solaris/Command/_pfexec
+++ b/Completion/Solaris/Command/_pfexec
@@ -22,11 +22,15 @@ _privset() {
 }
 
 _pfexec() {
+	local cmd cpp
 	local -a _comp_priv_prefix
- 	_arguments \
-		'-P[privileges to acquire]:privspec:_privset' \
- 		'(-):command name: _command_names -e' \
-		'*::arguments:{ _comp_priv_prefix=( pfexec ${(kv)opt_args[-P]} ) ; _normal }'
+	local -A opt_args
+	cmd="$words[1]"
+	cpp='_comp_priv_prefix=( $cmd ${(kv)opt_args[(I)-P]} )'
+	_arguments \
+		'-P+[privileges to acquire]:privspec:_privset' \
+		"(-): :{ $cpp; _command_names -e }" \
+		"*:: :{ $cpp; _normal }"
 }
 
 _pfexec "$@"
diff --git a/Completion/Unix/Command/_doas b/Completion/Unix/Command/_doas
index 94395557c..3ef036a88 100644
--- a/Completion/Unix/Command/_doas
+++ b/Completion/Unix/Command/_doas
@@ -1,7 +1,8 @@
 #compdef doas
 
-local environ e cmd
+local environ e cmd cpp
 local -a _comp_priv_prefix
+local -A opt_args
 
 zstyle -a ":completion:${curcontext}:" environ environ
 
@@ -10,13 +11,13 @@ do local -x "$e"
 done
 
 cmd="$words[1]"
+cpp='_comp_priv_prefix=( $cmd -n ${(kv)opt_args[(I)-u]} )'
 _arguments -s -S -A '-*' : \
-  - optL \
-  '-L[clear any persisted authorizations]' \
-  - default \
-  '-a+[specify authentication style]:authentication style' \
-  '(-n -s)-C+[check config file and report on command matching]:config:_files' \
-  '(-C)-n[non-interactive: fail rather than prompt for a password]' \
-  '(-C *)-s[run a shell]' \
-  '-u+[run command as specified user]:user:_users' \
-  '*::arguments:{ _comp_priv_prefix=( $cmd -n ${(kv)opt_args[-u]} ) ; _normal }'
+  '(: * -)-L[clear any persisted authorizations]' \
+  '(-L)-a+[specify authentication style]:authentication style' \
+  '(-L -n -s)-C+[check config file and report on command matching]:config:_files' \
+  '(-C -L)-n[non-interactive: fail rather than prompt for a password]' \
+  '(-C -L *)-s[run a shell]' \
+  '(-L)-u+[run command as specified user]: :_users' \
+  "(-)1: :{ $cpp; _command_names -e }" \
+  "*:: :{ $cpp; _normal }"
diff --git a/Completion/Unix/Command/_su b/Completion/Unix/Command/_su
index 032f867f4..066f5c3b6 100644
--- a/Completion/Unix/Command/_su
+++ b/Completion/Unix/Command/_su
@@ -63,6 +63,12 @@ if (( $words[(i)-] < CURRENT )); then
   norm=2
 fi
 
+# This is set so that _command_names will understand that we're completing for
+# a privileged command, but _call_program won't actually prepend anything to
+# commands if gain-privileges is enabled (which would be undesirable here since
+# su always prompts for a password). We delay setting it until this point so it
+# doesn't cause issues for the check above
+local -a _comp_priv_prefix=( '' )
 _arguments $args ${(e)first} "*:shell arguments:= ->rest" && return
 
 usr=${${(Q)line[norm]}/--/root}
diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo
index 41e32cbae..e3d12d72f 100644
--- a/Completion/Unix/Command/_sudo
+++ b/Completion/Unix/Command/_sudo
@@ -2,9 +2,9 @@
 
 setopt localoptions extended_glob
 
-local environ e cmd
-local -a args
-local -a _comp_priv_prefix
+local environ e cmd cpp
+local -a args _comp_priv_prefix
+local -A opt_args
 
 zstyle -a ":completion:${curcontext}:" environ environ
 
@@ -42,6 +42,10 @@ if [[ $service = sudoedit ]] || (( $words[(i)-e] < $words[(i)^(*sudo|-[^-]*)] ))
   args=( -A "-*" $args '!(-V --version -h --help)-e' '*:file:_files' )
 else
   cmd="$words[1]"
+  cpp='_comp_priv_prefix=(
+    $cmd -n
+    ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]}
+  )'
   args+=(
     '(-e --edit 1 *)'{-e,--edit}'[edit files instead of running a command]' \
     '(-s --shell)'{-s,--shell}'[run shell as the target user; a command may also be specified]' \
@@ -51,8 +55,8 @@ else
     '(-E -i --login -s --shell -e --edit)--preserve-env=-[preserve user environment when running command]::environment variable:_sequence _parameters -g "*export*"' \
     '(-H --set-home -i --login -s --shell -e --edit)'{-H,--set-home}"[set HOME variable to target user's home dir]" \
     '(-P --preserve-groups -i -login -s --shell -e --edit)'{-P,--preserve-groups}"[preserve group vector instead of setting to target's]" \
-    '(-)1:command: _command_names -e'
-    '*::arguments:{ _comp_priv_prefix=( $cmd -n ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]} ) ; _normal }'
+    "(-)1: :{ $cpp; _command_names -e }"
+    "*:: :{ $cpp; _normal }"
   )
 fi
 
diff --git a/Completion/Zsh/Type/_command_names b/Completion/Zsh/Type/_command_names
index cd630b7a4..b1c35f013 100644
--- a/Completion/Zsh/Type/_command_names
+++ b/Completion/Zsh/Type/_command_names
@@ -41,11 +41,24 @@ fi
 args=( "$@" )
 
 local -a cmdpath
-if zstyle -a ":completion:${curcontext}" command-path cmdpath &&
-   [[ $#cmdpath -gt 0 ]]
-then
+
+zstyle -a ":completion:${curcontext}" command-path cmdpath
+
+# Using the current PATH doesn't necessarily make sense when completing commands
+# to tools like sudo, which might set a different one. A common issue is that
+# /**/sbin appear in the PATH used by the tool, but not in the one used by the
+# unprivileged user who calls it. To do the right thing in the most common
+# cases, we'll simply ensure that the sbin variants always appear here when not
+# otherwise overridden (bash-completion's _sudo does something similar)
+if (( ! $#cmdpath && $#_comp_priv_prefix )); then
+  cmdpath=( $path ${path/%\/bin//sbin} )
+  cmdpath=( ${(u)^cmdpath}(/-N) )
+fi
+
+if (( $#cmdpath )); then
   local -a +h path
   local -A +h commands
   path=( $cmdpath )
 fi
+
 _alternative -O args "$defs[@]"