From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18533 invoked by alias); 10 Jun 2016 05:55:54 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 38644 Received: (qmail 9151 invoked from network); 10 Jun 2016 05:55:50 -0000 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: <160606090104.ZM11947@torch.brasslantern.com> <1688.1465480099@thecus.kiddle.eu> From: Alexius Ludeman Date: Thu, 9 Jun 2016 22:27:10 -0700 Message-ID: Subject: Re: PATCH: _su (was Re: Are completions in some way heavy?) To: Zsh Workers Content-Type: multipart/alternative; boundary=001a11469ece1837e80534e5ccd7 --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 wrote: > On 6 Jun, Sebastian Gniazdowski wrote: > > But it doesn't complete user names when invoked as "su - ". > > 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)$( + shell="${${(M@)${(@f)$( 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)^"$( - 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)^"$( + 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--