summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Completion/Unix/Command/_su73
2 files changed, 67 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 3627033c2..2e1f975d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-01-16 Bart Schaefer <schaefer@zsh.org>
+
+ * 22110 (slightly tweaked): Completion/Unix/Command/_su: complete
+ options, be more clever about determining the shell being used,
+ and treat the argument of the -c option as a command (cf. _sh).
+
2006-01-13 Wayne Davison <wayned@users.sourceforge.net>
* 22162: Src/prompt.c, Src/Modules/datetime.c, Src/Modules/stat.c:
diff --git a/Completion/Unix/Command/_su b/Completion/Unix/Command/_su
index 24fb5932e..6d0f2cd9f 100644
--- a/Completion/Unix/Command/_su
+++ b/Completion/Unix/Command/_su
@@ -1,20 +1,69 @@
#compdef su
-local shell comp name usr base
+local -A opt_args
+local -a args state context
+local shell=${words[(i)(-s|--shell=*)]} first='1:user name:_users'
+local usr=root line
-[[ $words[2] != - ]]
-(( base=$?+2 ))
+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
-if [[ CURRENT -eq base ]]; then
- _users && return
- usr=root
-elif [[ CURRENT -ge base+1 ]]; then
- usr=$words[base]
+[[ $words[shell] == -s ]] && ((shell++))
+
+if [[ CURRENT -ne shell && -n ${words[shell]} ]]; then
+ shell=${words[shell]#*=}
else
- return
+ shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
fi
-shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
-compset -n $base
+[[ -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
-_dispatch $shell:t $shell $shell:t -default-
+return 1