zsh-users
 help / color / mirror / code / Atom feed
* zparseopts help
@ 2015-01-23 15:39 TJ Luoma
  2015-01-23 16:37 ` ZyX
  2015-01-23 17:15 ` Bart Schaefer
  0 siblings, 2 replies; 4+ messages in thread
From: TJ Luoma @ 2015-01-23 15:39 UTC (permalink / raw)
  To: Zsh-Users List

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

As I've mentioned before, I have been using zsh forever but feel like I
missed out on learning about 97% of what it can do.

For example, today I learned about zparseopts.

(Feel free to mock.)

I took a look through the `man` entry, but… I don't know what it is about
my brain, but I can read and re-read man pages and still fail to understand
what it is saying. I do much better with examples.

I did some googling and found
http://emg-2.blogspot.com/2008/01/zsh-unique-features.html and once I had
that I could go back and look at the `man` page to understand what it was
doing.

So here is my first attempt at using `zparseopts`:

zparseopts -D -E -A MyVariableNameHere -- a b -orange -grape -apple

if (( ${+MyVariableNameHere[-a]} )); then
        echo "Apple";
fi

if (( ${+MyVariableNameHere[--apple]} )); then
        echo "Apple";
fi

if (( ${+MyVariableNameHere[-b]} )); then
        echo "Banana";
fi

if (( ${+MyVariableNameHere[--orange]} )); then
        echo "orange";
fi

if (( ${+MyVariableNameHere[--grape]} )); then
        echo "grape";
fi

Questions:

1. Is there a way to combine the -a and --apple statements into one?

2. Are a series of 'if' statements the best way to handle these sorts of
options?

What I have been doing is something like this:

for MyVariableNameHere in "$@"
do
case "$MyVariableNameHere" in
-a|--apple)
echo "Apple"
shift
;;
-b|--banana)
echo "Banana"
shift
;;
esac
done

but that has the disadvantage of not being able to parse "-ab" as two
separate arguments. OTOH it's very readable and I don't have to worry about
very many chances of missing a closing bracket or brace!

TjL

ps - if anyone knows of a good place for zparseopts examples, please let me
know. Google was not very much help.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: zparseopts help
  2015-01-23 15:39 zparseopts help TJ Luoma
@ 2015-01-23 16:37 ` ZyX
  2015-01-23 17:15 ` Bart Schaefer
  1 sibling, 0 replies; 4+ messages in thread
From: ZyX @ 2015-01-23 16:37 UTC (permalink / raw)
  To: TJ Luoma, Zsh-Users List



23.01.2015, 18:42, "TJ Luoma" <luomat@gmail.com>:
> As I've mentioned before, I have been using zsh forever but feel like I
> missed out on learning about 97% of what it can do.
>
> For example, today I learned about zparseopts.
>
> (Feel free to mock.)
>
> I took a look through the `man` entry, but… I don't know what it is about
> my brain, but I can read and re-read man pages and still fail to understand
> what it is saying. I do much better with examples.
>
> I did some googling and found
> http://emg-2.blogspot.com/2008/01/zsh-unique-features.html and once I had
> that I could go back and look at the `man` page to understand what it was
> doing.
>
> So here is my first attempt at using `zparseopts`:
>
> zparseopts -D -E -A MyVariableNameHere -- a b -orange -grape -apple
>
> if (( ${+MyVariableNameHere[-a]} )); then
>         echo "Apple";
> fi
>
> if (( ${+MyVariableNameHere[--apple]} )); then
>         echo "Apple";
> fi
>
> if (( ${+MyVariableNameHere[-b]} )); then
>         echo "Banana";
> fi
>
> if (( ${+MyVariableNameHere[--orange]} )); then
>         echo "orange";
> fi
>
> if (( ${+MyVariableNameHere[--grape]} )); then
>         echo "grape";
> fi
>
> Questions:
>
> 1. Is there a way to combine the -a and --apple statements into one?

    zparseopts -- a=A -apple=A
    if (( $#A )) ; then
        echo Apple
    fi

>
> 2. Are a series of 'if' statements the best way to handle these sorts of
> options?

I guess this is why zparseopts has `option_definition=ARRNAME` syntax.

>
> What I have been doing is something like this:
>
> for MyVariableNameHere in "$@"
> do
> case "$MyVariableNameHere" in
> -a|--apple)
> echo "Apple"
> shift
> ;;
> -b|--banana)
> echo "Banana"
> shift
> ;;
> esac
> done
>
> but that has the disadvantage of not being able to parse "-ab" as two
> separate arguments. OTOH it's very readable and I don't have to worry about
> very many chances of missing a closing bracket or brace!

I did not know about `zparseopts` and have written the following interesting piece of code which handles `-ab`, `-c{arg}`, `--foo {arg}`. No `--foo={arg}`, but you can easily imagine how it would look:

```
function parseargs()
{
    local -i ENDOFARGS=0
    local -i OUTPUT=0
    for arg in $@ ;
    do
        if (( OUTPUT == 1 ))
        then
            OUTPUTFILE=${arg}
            OUTPUT=0
            continue
        elif (( OUTPUT == 2 ))
        then
            OUTPUT=0
        fi
        [[ "${METHOD}" == "1" ]] &&
            METHOD=${arg} && continue
        [[ "${ARCHTYPE}" == "1" ]] &&
            ARCHTYPE=${arg} && continue
        if (( ! $ENDOFARGS )) && [[ ${arg[1]} == "-" ]]
        then
            case ${arg} in
                --)          ENDOFARGS=1 ;;
                --type)       ARCHTYPE=1 ;;
                --method)       METHOD=1 ;;
                --debug)         DEBUG=1 ;;
                --help)          Help    ;;
                --stdout)        setargument  1 1 ;;
                --decompress)    setargument  2 1 ;;
                --compress)      setargument  3 1 ;;
                --test)          setargument  4 1 ;;
                --force)         setargument  5 1 ;;
                --keep)          setargument  6 1 ;;
                --quiet)         setargument  7 1 ;;
                --show-progress) setargument  8 1 ;;
                --fast)          setargument  9 1 ;;
                --best)          setargument  9 9 ;;
                --onefile)       setargument 10 1 ;;
                --verbose)       setargument 11 1 ;;
                -)               setargument 12 1 ;;
                --*) eerror 64 "Unknown key: ${arg}!" ;;
                -*) local -i I=2
                    while [[ ! -z "${arg[$I]}" ]]
                    do
                        local CUR="${arg[$I]}"
                        if (( OUTPUT ))
                        then
                            OUTPUT=2
                            OUTPUTFILE="${arg[$I,-1]}" && break
                        fi
                        case ${CUR} in
                            o) OUTPUT=1 ;;
                            c)     setargument 1 1 ;;
                            d)     setargument 2 1 ;;
                            z)     setargument 3 1 ;;
                            t)     setargument 4 1 ;;
                            f)     setargument 5 1 ;;
                            k)     setargument 6 1 ;;
                            q)     setargument 7 1 ;;
                            p)     setargument 8 1 ;;
                            O)     setargument 10 1 ;;
                            v)     setargument 11 1 ;;
                            [1-9]) setargument 9 ${CUR} ;;
                            *) eerror 64 "Unknown key: -${CUR}!" ;;
                        esac
                        (( I++ ))
                    done ;;
            esac
        else
            FILES+=( ${arg:a} )
        fi
    done
    [[ -z $ARCHTYPE ]] && EXT="7z" \
                       || EXT="$ARCHTYPE"
    [[ "${OUTPUTFILE}" == "-" ]] && setargument 1 1 && unset OUTPUTFILE
    ARGUMENTS[3]=$(( ! ${ARGUMENTS[2]} && ! ${ARGUMENTS[4]} ))
    (( ${ARGUMENTS[3]} )) && [[ -z ${OUTPUTFILE} ]] && [[ ! -z ${FILES} ]] &&\
        OUTPUTFILE="${FILES[1]}.$EXT"
}
```

Not particularly readable (and is in fact one part of my first big zsh scripts).

(If you are wondering this is the part of a wrapper script for `7z` archiver that makes it able to be used as `gzip` (but only if both `-so` and `-si` options are fully supported and they are not).)


>
> TjL
>
> ps - if anyone knows of a good place for zparseopts examples, please let me
> know. Google was not very much help.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: zparseopts help
  2015-01-23 15:39 zparseopts help TJ Luoma
  2015-01-23 16:37 ` ZyX
@ 2015-01-23 17:15 ` Bart Schaefer
  2015-01-23 17:56   ` Ray Andrews
  1 sibling, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2015-01-23 17:15 UTC (permalink / raw)
  To: Zsh-Users List

On Jan 23, 10:39am, TJ Luoma wrote:
}
} I took a look through the `man` entry, but I don't know what it is about
} my brain, but I can read and re-read man pages and still fail to understand
} what it is saying. I do much better with examples.

Not uncommon ... if we could find some volunteers to write more examples
for the manual, that would be nice.

} zparseopts -D -E -A MyVariableNameHere -- a b -orange -grape -apple
} 
} Questions:
} 
} 1. Is there a way to combine the -a and --apple statements into one?

Yes, that's what zparseopts -M is for.  With -M, "-apple=a" means to
store anything you find for "--apple" in the location for "-a" instead.

 zparseopts -M -D -E -A MyVariableNameHere -- a b -orange -grape -apple=a

} 2. Are a series of 'if' statements the best way to handle these sorts of
} options?

If you're using "-A MyVariableNameHere" then you should be able to do

    # Cycle through the keys of the associative array
    for myOption in "${(k@)MyVariableNameHere}"
    do
      case "$myOption" in
      ...
      esac
    done

} ps - if anyone knows of a good place for zparseopts examples, please let me
} know. Google was not very much help.

The majority of uses of zparseopts are to interpret the options of some
*other* command, do some manipuation on them, and then construct a call
to that other command.  I.e., for writing a wrapper function around some
other complicated command.  So you won't find very many good examples of
doing something with everything that zparseopts parsed.

The only comprehensive example in the zsh distribution is the "zargs"
function, but it uses "-a array" instead of "-A hash" so the handling
of the parsed options might be too confusing for an introduction.

I wish I had a better suggestion.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: zparseopts help
  2015-01-23 17:15 ` Bart Schaefer
@ 2015-01-23 17:56   ` Ray Andrews
  0 siblings, 0 replies; 4+ messages in thread
From: Ray Andrews @ 2015-01-23 17:56 UTC (permalink / raw)
  To: zsh-users

On 01/23/2015 09:15 AM, Bart Schaefer wrote:
> On Jan 23, 10:39am, TJ Luoma wrote:
> }
> } I took a look through the `man` entry, but I don't know what it is about
> } my brain, but I can read and re-read man pages and still fail to understand
> } what it is saying. I do much better with examples.
>
> Not uncommon ... if we could find some volunteers to write more examples
> for the manual, that would be nice.

I'm glad to hear that it would even be welcomed.  When I've ranted 
against the general helpfulness of docs (not just here, and not just zsh 
docs, but throughout the Linux world), I'm usually met with a stout 
defense of the status quo.  Zsh docs are written very much in the 
standard style of Linux docs in general, that dust dry, list-of-facts 
that does anything but help you learn.  I'd be very interested in 
working on docs, but so far my preliminary efforts have been rebuffed 
without comment.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-01-23 18:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-23 15:39 zparseopts help TJ Luoma
2015-01-23 16:37 ` ZyX
2015-01-23 17:15 ` Bart Schaefer
2015-01-23 17:56   ` Ray Andrews

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).