Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: _su (was Re: Are completions in some way heavy?)
- X-seq: zsh-workers 38644
- From: Alexius Ludeman <lex-zsh@xxxxxxxxxxxxx>
- To: Zsh Workers <zsh-workers@xxxxxxx>
- Subject: Re: PATCH: _su (was Re: Are completions in some way heavy?)
- Date: Thu, 9 Jun 2016 22:27:10 -0700
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lexinator-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=NFoV5Rkn1sWh/A5FxrC1NMyTJJ83e+Wkzui+uPJxMbc=; b=X9Ve9w3PTYLtDtefKqNgWjQeooXqFyXxxP96F05DebTwAPGFuIxN3YbuW8GmbqFwWn 0GuzTyzSSBwrGNagq0/ifVLmFlZnHM2QK+TcMKzginQkH5ardBmmyG+1GDxN9SfN2f2b REDK7ee6iEuBPA8QHFFiIHRQu0JDh4gKLSSlS4fzru5pR4PtMn5LuhJFT0Z/HEND83e/ HvhK05uvuoDc1GL89mKX3XiWOvpxKEzIOSc7vXYDe7yHebWdOoWA8jEFbRUaXoQT2Uce zlCHsUPLaiXOD4C1dKMKCxo6bj8mT+OAuxdV6lIUMmOvksF9FUSNG6lvU7eHXO+CNUwT ITGg==
- In-reply-to: <1688.1465480099@thecus.kiddle.eu>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <CAKc7PVBnpkEnkWZb4yh9BgutbBgfKS0Hh1x6e_Q-jnOyVDHQOg@mail.gmail.com> <160606090104.ZM11947@torch.brasslantern.com> <CAKc7PVB8rH-MeCMzjgSLYi1QhBawcX4tde_SQ06DaHOYo3gDyQ@mail.gmail.com> <1688.1465480099@thecus.kiddle.eu>
Hi Oliver,
The su manpage for os x is available at:
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/su.1.html
Even though the page mentions the manpage is for 10.9, I'm on el
capitan(10.11.5) and the content matches exactly.
thanks
On Thu, Jun 9, 2016 at 6:48 AM, Oliver Kiddle <okiddle@xxxxxxxxxxx> wrote:
> On 6 Jun, Sebastian Gniazdowski wrote:
> > But it doesn't complete user names when invoked as "su - <TAB>".
>
> su completion is particularly tricky to get working properly in part
> because of that single dash option. The patch is an attempt to improve
> on it.
>
> _su was also broken in other regards. In particular, Linux su got moved
> to util-linux and removed from GNU coreutils quite a few years ago (I
> dug into the history in case there was still a GNU su that needed
> supporting). That change meant the Linux specifics were skipped.
>
> I'm not too keen on completion functions producing messages like the
> one for the user apparently having no shell. The function failing to
> determine what it is is more likely so falling back to sh might be more
> useful?
>
> Before dispatching to _sh etc $words and $CURRENT need to be cut down
> to remove su options and this wasn't being done. The usual use of
> _arguments' two/three colon '*:: form isn't workable on Linux: su
> options can be specified after the username and you need -- to pass
> arbitrary shell options. I tried using _arguments -n and NORMARG and
> concluded that that feature is badly broken. It only works in very
> simple cases where all options precede all normal arguments but for that
> it offers nothing you can't do by checking $line. It could be a useful
> feature but I think I got something that works by comparing $#words to
> $#line.
>
> I couldn't find an online manpage for su on Mac OS X. Perhaps it doesn't
> have an su. I have verified the function on Solaris, it just doesn't
> need a section in the case statement.
>
> Oliver
>
> diff --git a/Completion/Unix/Command/_su b/Completion/Unix/Command/_su
> index 057a413..73b27ee 100644
> --- a/Completion/Unix/Command/_su
> +++ b/Completion/Unix/Command/_su
> @@ -2,79 +2,86 @@
>
> local -A opt_args
> local -a args context state line expl
> -local shell=${words[(i)(-s|--shell=*)]} first='1:user name:_users'
> -local usr=root
> +local first='(-)${norm}:user name:_users'
> +integer norm=1 strip
> +local shell usr
>
> -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=(
> - '-l[use a login shell]'
> - '-s[run the specified shell]:shell:->shell'
> - )
> - case $OSTYPE in
> - freebsd*)
> - args=(
> +(( $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*|dragonfly*)
> + args+=(
> '-c[use settings from specified login class]:class'
> '-f[if the invoked shell is csh, prevent it from reading .cshrc]'
> - '-l[use a login shell]'
> - '-m[do not reset environment]'
> - '-s[set the MAC label]'
> + '(-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]'
> )
> ;;
> - *) args+=( '-c[pass command to shell]:command string:->command' ) ;;
> - esac
> -fi
> + netbsd*)
> + args+=(
> + '-d[use a login shell but retain current directory]'
> + "-K[don't use Kerberos]"
> + )
> + ;;
> +esac
>
> -if [[ $#words -ge 2 && $words[2] != -* && CURRENT -ne 2 ]]; then
> - usr=$words[2]
> - first=
> +if (( $words[(i)-] < CURRENT )); then
> + args=( ${args:#*-(-login|l|)\[*} '1:-' )
> + norm=2
> fi
>
> -[[ $words[shell] == -s ]] && ((shell++))
> +_arguments $args ${(e)first} "*:shell arguments:= ->rest" && return
>
> -if [[ CURRENT -ne shell && -n ${words[shell]} ]]; then
> - shell=${words[shell]#*=}
> +usr=${line[norm]/--/root}
> +if (( $#opt_args[(i)-(s|-shell)] )); then
> + shell=${(v)opt_args[(i)-(s|-shell)]}
> +elif (( ${+commands[getent]} )); then
> + shell="${$(_call_program shells getent passwd $usr)##*:}"
> else
> - shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
> + 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)
> - _wanted -C $context shells expl shell compadd
> ${(f)^"$(</etc/shells)"}(N)
> - return
> - ;;
> - (rest)
> - if [[ -z $shell || $shell = */(nologin|false) ]]; 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
> - ;;
> + shells)
> + _wanted -C $context shells expl shell compadd
> ${(f)^"$(</etc/shells)"}(N)
> + return
> + ;;
> + rest)
> + if [[ -z $shell || $shell = */(nologin|false) ]]; then
> + _message "-s option required, $usr has no shell"
> + else
> + (( strip = $#words - $#line + norm ))
> + (( CURRENT -= strip - 1 ))
> + words[2,strip]=()
> + _dispatch ${service}:${context} $shell $shell:t -default-
> + return
> + fi
> + ;;
> esac
>
> return 1
>
Messages sorted by:
Reverse Date,
Date,
Thread,
Author