Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm
Precedence: bulk
X-No-Archive: yes
List-Id: Zsh Workers List <zsh-workers.zsh.org>
List-Post: <mailto:zsh-workers@zsh.org>
List-Help: <mailto:zsh-workers-help@zsh.org>
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au
X-Spam-Level: 
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,HTML_MESSAGE,
	T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1
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==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to;
        bh=NFoV5Rkn1sWh/A5FxrC1NMyTJJ83e+Wkzui+uPJxMbc=;
        b=m1uXilCFce7aVh2gf2ifufX8M/WU14Vq+3llLn1DNsCd746S50nSv+ZFMcuASdzNff
         E+LKleCCIiQ0B814Jrkl4h7d17No2imeRVq4rU1d+LITz+P1lq1J6eaAi+0qemGXRFLA
         gtWwMy8IbCrQaBYxq7RWZoBPgA+i+gijIWhi2m5apThBKfIaBWiV9e7+oU8ZD5kxSU5l
         Eea3EIz/3CpCLWoYNpeM+xMQhpIvW3baAC7g+e/+7SwPOdmtzDgetD8NFZNG5YS7yU9q
         SC+qdA5BXSQ+SgFRPL/kSb+dq4N4WUX2r02zL9YSWMkefevMjt/0v7zmQNyXq2DMRD+9
         eAwg==
X-Gm-Message-State: ALyK8tKD81F6WlCbCfxCaqayx1B3TMguBNTwPzSvj2dJQCLk3YGO7MDQqyYkuhvNIM0B14j3YYKfQ8As8MMDRw==
X-Received: by 10.28.24.82 with SMTP id 79mr17273714wmy.42.1465536459841; Thu,
 09 Jun 2016 22:27:39 -0700 (PDT)
MIME-Version: 1.0
In-Reply-To: <1688.1465480099@thecus.kiddle.eu>
References: <CAKc7PVBnpkEnkWZb4yh9BgutbBgfKS0Hh1x6e_Q-jnOyVDHQOg@mail.gmail.com>
 <160606090104.ZM11947@torch.brasslantern.com> <CAKc7PVB8rH-MeCMzjgSLYi1QhBawcX4tde_SQ06DaHOYo3gDyQ@mail.gmail.com>
 <1688.1465480099@thecus.kiddle.eu>
From: Alexius Ludeman <lex-zsh@lexinator.com>
Date: Thu, 9 Jun 2016 22:27:10 -0700
Message-ID: <CAD_-DumBwiFX6MkMi5GfQeMQ5yZ0CkXs9eB66MAWCDhMoudvPQ@mail.gmail.com>
Subject: Re: PATCH: _su (was Re: Are completions in some way heavy?)
To: Zsh Workers <zsh-workers@zsh.org>
Content-Type: multipart/alternative; boundary=001a11469ece1837e80534e5ccd7
X-Seq: zsh-workers 38644

--001a11469ece1837e80534e5ccd7
Content-Type: text/plain; charset=UTF-8

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@yahoo.co.uk> 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
>

--001a11469ece1837e80534e5ccd7--

