zsh-workers
 help / color / mirror / code / Atom feed
From: Alexius Ludeman <lex-zsh@lexinator.com>
To: Zsh Workers <zsh-workers@zsh.org>
Subject: Re: PATCH: _su (was Re: Are completions in some way heavy?)
Date: Thu, 9 Jun 2016 22:27:10 -0700	[thread overview]
Message-ID: <CAD_-DumBwiFX6MkMi5GfQeMQ5yZ0CkXs9eB66MAWCDhMoudvPQ@mail.gmail.com> (raw)
In-Reply-To: <1688.1465480099@thecus.kiddle.eu>

[-- Attachment #1: Type: text/plain, Size: 7329 bytes --]

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
>

  reply	other threads:[~2016-06-10  5:55 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CAKc7PVBnpkEnkWZb4yh9BgutbBgfKS0Hh1x6e_Q-jnOyVDHQOg@mail.gmail.com>
     [not found] ` <160606090104.ZM11947@torch.brasslantern.com>
     [not found]   ` <CAKc7PVB8rH-MeCMzjgSLYi1QhBawcX4tde_SQ06DaHOYo3gDyQ@mail.gmail.com>
2016-06-09 13:48     ` Oliver Kiddle
2016-06-10  5:27       ` Alexius Ludeman [this message]
2016-06-17 16:50         ` Oliver Kiddle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAD_-DumBwiFX6MkMi5GfQeMQ5yZ0CkXs9eB66MAWCDhMoudvPQ@mail.gmail.com \
    --to=lex-zsh@lexinator.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).