#compdef su local -A opt_args local -a args context state line expl local first='(-)${norm}:user name:_users' integer norm=1 strip local shell usr (( $words[(i)-(l|-login)] < CURRENT )) || args=( '-[use a login shell]' ) case $OSTYPE in linux*) args=( -S $args '(-c --command --session-command *)'{-c,--command=}'[pass command to shell]:command string:_cmdstring' "(-c --command *)--session-command=[pass command to shell and don't create a new session]:command string:_cmdstring" '(--fast -f)'{-f,--fast}'[pass -f to shell]' '(-l --login -m -p --preserve-environment)'{-l,--login}'[use a login shell]' '(-l --login -m -p --preserve-environment)'{-m,-p,--preserve-environment}"[don't reset environment]" '(-s --shell)'{-s,--shell=}'[run the specified shell]:shell:->shells' '(-)--help[display help information]' '(-)--version[display version information]' ) (( EUID )) || args+=( '(-g --group)'{-g,--group=}'[specify primary group]:group:_groups' \*{-G,--supp-group=}'[specify supplemental group]:group:_groups' ) first="(--help --version)${first#???}" ;; *bsd*|darwin*|dragonfly*) args+=( '-c[use settings from specified login class]:class' '-f[if the invoked shell is csh, prevent it from reading .cshrc]' '(-m)-l[use a login shell]' "(-l)-m[don't reset environment]" ) ;| freebsd*) args+=( '-s[set the MAC label]' ) ;; openbsd*) args+=( '(-K)-a[specify authentication type]:authentication type' '(-a)-K[shorthand for -a passwd]' '-s[run the specified shell]:shell:->shells' '-L[loop until login succeeds]' ) ;; netbsd*) args+=( '-d[use a login shell but retain current directory]' "-K[don't use Kerberos]" ) ;; esac if (( $words[(i)-] < CURRENT )); then args=( ${args:#*-(-login|l|)\[*} '1:-' ) norm=2 fi _arguments $args ${(e)first} "*:shell arguments:= ->rest" && return usr=${line[norm]/--/root} # Normal users generally don't appear in passwd on macOS; try the Directory # Service first if [[ $OSTYPE == darwin* ]] && (( $+commands[dscl] )); then shell=${"$( _call_program shells dscl . -read /Users/${(q)usr} UserShell )"#UserShell: } fi [[ -z $shell ]] && if (( ${#${(@M)args:#*-s\[*\]:*}} && $#opt_args[(i)-(s|-shell)] )); then shell=${(v)opt_args[(i)-(s|-shell)]} elif (( ${+commands[getent]} )); then shell="${$(_call_program shells getent passwd ${(q)usr})##*:}" else shell="${${(M@)${(@f)$(