Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Completing option/value pairs without space



Mario Lang wrote:

> ...
> 
> _arguments \
>   '-c[Start in interactive mode]' \
>   '-d\:[Debug level]:Debug level:' \
>   '-D[Print all debug information to stderr]' \
>   '-q[Quiet mode, no output]' \
>   '--help[Show help]' \
>   '--version[Show version information]' \
>   '-n\:[Set the name of chainsetup]' \
>   '-s\:[Create a new chainsetup from file]:filename:_files' \
>   '-sr\:[Set internal sampling rate]:Sampling rate:(8000 11025 22050 44100 48000)'
> 
> When I now e.g. do:
> ecasound -sr:<TAB>
> i get a space, and when hitting tab again, I get the sampling rates for completion.

You have to tell _arguments that the option's argument comes directly
after the option.  That's done by adding `-' after the option name
(before the description), as in:

  '-sr\:-[Set internal sampling rate]:Sampling rate:(8000 11025 22050 44100 48000)' \

> The same problem would strike when I come to the more complicated
> effects. e.g. I would like to have:
> ecasound ... -efs:<TAB>
> and get
> -efs: -- Resonator center freq
> 
> and when doing
> ecasound ... -efs:100,<TAB>
> Id like to get
> -efs:*, -- resonator width

That's done using actions of the `->state' form, e.g.:

  '-efs\:-[Set resonator parameters]: :->efs' \

After the call to _arguments one can then test if the real action for
`efs' has to be taken:

  case $state in
  efs)
    if compset -P '*,'; then
      _message 'Resonator width'
    else
      _message 'Resonator center frequency'
    fi
    ;;
    ...
  esac

> And a really reall neat(tm) gadget would be:
> ecasound ... -efs:100,50 -kl:<TAB>
> should give
> -kl:1 -- Linear controller controlling Resonator freq
> -kl:2 -- Linear controller controlling Resonator width
> 
> and so on.

You didn't describe `-kl' so I don't know what it gets as arguments.
If you only need it to complete `1' or `2' (or `3',...) with some
description and some other values separated by commas one woul use
another:

  '-kl\:-[linear controller]: :->kl'

with a case-branch such as:

  kl)
    if compset -P '*,'; then
      _message 'Linear controller value...'
    else
      _values 'Linear controller parameters' \
        '1[Linear controller controlling resonator freq]' \
        '2[Linear controller controlling resonator width]'
    fi

If the values and descriptions completed after `-kl' depend on
previous options one could still do it but one would have to look
either into the opt_args associative array to find the options set on
the line (and their values) or one could loop through the $words array 
set up by the completion system to contain the words on the line (one
would probably start at element $CURSOR-1 -- the word before the
cursor -- and go back to the first word to find the options on which
one has to decide what to complete).

Below are all the code snippets above merged into your function.

Two remarks: without a `->state' action one doesn't need to make local 
all those parameters.  And the `&& return 0' makes sure that the
function is left if `_arguments' says that it's sure to have
completely handled completion in the current context.

And one remark to all -workers: with the function below completion
after `ecasound -efs:<TAB>' makes _arguments report (and show) `-efs:' 
as a possible completion.  That's correct somehow, but looks very
weird in this case.  Hm.


Bye
 Sven

#compdef ecasound

local context state line
typeset -A opt_args

_arguments \
  '-c[Start in interactive mode]' \
  '-d\:[Debug level]:Debug level:' \
  '-D[Print all debug information to stderr]' \
  '-q[Quiet mode, no output]' \
  '--help[Show help]' \
  '--version[Show version information]' \
  '-n\:[Set the name of chainsetup]' \
  '-s\:[Create a new chainsetup from file]:filename:_files' \
  '-sr\:-[Set internal sampling rate]:Sampling rate:(8000 11025 22050 44100 48000)' \
  '-efs\:-[Set resonator parameters]: :->efs' \
  '-kl\:-[linear controller]: :->kl' && return 0

case $state in
efs)
  if compset -P '*,'; then
    _message 'Resonator width'
  else
    _message 'Resonator center frequency'
  fi
  ;;
kl)
  if compset -P '*,'; then
    _message 'Linear controller value...'
  else
    _values 'Linear controller parameters' \
      '1[Linear controller controlling resonator freq]' \
      '2[Linear controller controlling resonator width]'
  fi
  ;;
esac

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author