summary refs log tree commit diff
path: root/Completion/Unix/Command/_su
blob: 6d0f2cd9f15119a34e7c566a45f2c8848b7cd067 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#compdef su

local -A opt_args
local -a args state context
local shell=${words[(i)(-s|--shell=*)]} first='1:user name:_users'
local usr=root line

if _pick_variant gnu="Free Software Foundation" unix --version; then
  args=(
    '(--command)-c[pass command to shell]:command string:->command'
    '(-c)--command=-[pass command to shell]:command string:->command'
    '-f[pass -f to shell (csh)]'
    '(--login)-l[use a login shell]'
    '(-l)--login[use a login shell]'
    '(-p --preserve-environment)-m[do not reset environment]'
    '(-m --preserve-environment)-p[do not reset environment]'
    '(-m -p)--preserve-environment[do not reset environment]'
    '(--shell)-s[run the specified shell]:shell:->shell'
    '(-s)--shell=-[run the specified shell]:shell:->shell'
  )
else
  args=(
    '-c[pass command to shell]:command string:->command'
    '-l[use a login shell]'
    '-s[run the specified shell]:shell:->shell'
  )
fi

if [[ $#words -ge 2 && $words[2] != -* && CURRENT -ne 2 ]]; then
    usr=$words[2]
    first=
fi

[[ $words[shell] == -s ]] && ((shell++))

if [[ CURRENT -ne shell && -n ${words[shell]} ]]; then
    shell=${words[shell]#*=}
else
    shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
fi

[[ -z $first ]] && compset -n 2

_arguments : $args[@] $first "*:${shell:t} arguments:->rest" && return

case $state in
    (command)
        compset -q
        _normal
        return
        ;;
    (shell)
        compadd ${(f)^"$(</etc/shells)"}(N)
        return
        ;;
    (rest)
        if [[ -z $shell || $shell = */nologin ]]; then
            _arguments "-s[run the specified shell, $usr has no shell]" ||
                _message "-s option required, $usr has no shell"
            compstate[insert]=
        else
            # Something wrong here: doubles the file listing sometimes
            _dispatch ${service}:${context} $shell $shell:t -default-
            return
        fi
        ;;
esac

return 1