/** * * * Generate an zsh option format like this: '(-v --invert-match)'{-v,--invert-match}'[invert match: select non-matching lines]' Or: '-gcflags[flags for 5g/6g/8g]:flags' '-p[number of parallel builds]:number' '--cleanup=[specify how the commit message should be cleaned up]:mode:((verbatim\:"do not change the commit message at all" whitespace\:"remove leading and trailing whitespace lines" strip\:"remove both whitespace and commentary lines" default\:"act as '\''strip'\'' if the message is to be edited and as '\''whitespace'\'' otherwise"))' \ */ public function option_flag_item(Option $opt, $cmdSignature) { // TODO: Check conflict options $str = ""; $optspec = $opt->flag || $opt->optional ? '' : '='; $optName = $opt->long ? $opt->long : $opt->short; if ($opt->short && $opt->long) { if (!$opt->multiple) { $str .= "'(-" . $opt->short . " --" . $opt->long . ")'"; // conflict options } $str .= "{-" . $opt->short . ',' . '--' . $opt->long . $optspec . "}"; $str .= "'"; } else { if ($opt->long) { $str .= "'--" . $opt->long . $optspec; } else { if ($opt->short) { $str .= "'-" . $opt->short . $optspec; } else { throw new Exception('undefined option type'); } } } // output description $str .= "[" . addcslashes($opt->desc, '[]:') . "]"; $placeholder = $opt->valueName ? $opt->valueName : $opt->isa ? $opt->isa : null; // has anything to complete if ($opt->validValues || $opt->suggestions || $opt->isa) { $str .= ':'; // for the value name if ($placeholder) { $str .= $placeholder; } if ($opt->validValues || $opt->suggestions) { if ($opt->validValues) { if (is_callable($opt->validValues)) { $str .= ':{' . join(' ', array($this->meta_command_name(), Utils::qq($placeholder), $cmdSignature, 'opt', $optName, 'valid-values')) . '}'; } elseif ($values = $opt->getValidValues()) { // not callable, generate static array $str .= ':(' . join(' ', Utils::array_qq($values)) . ')'; } } elseif ($opt->suggestions) { if (is_callable($opt->suggestions)) { $str .= ':{' . join(' ', array($this->meta_command_name(), Utils::qq($placeholder), $cmdSignature, 'opt', $optName, 'suggestions')) . '}'; } elseif ($values = $opt->getSuggestions()) { // not callable, generate static array $str .= ':(' . join(' ', Utils::array_qq($values)) . ')'; } } } elseif (in_array($opt->isa, array('file', 'dir', 'path'))) { switch ($opt->isa) { case 'file': $str .= ':_files'; break; case 'dir': $str .= ':_directories'; break; case 'path': $str .= ':_path_files'; break; } if (isset($opt->glob)) { $str .= ' -g "' . $opt->glob . '"'; } } } $str .= "'"; // close quote return $str; }
public function testSuggestions() { $opt = new Option('scope'); $opt->suggestions(['public', 'private']); $this->assertNotEmpty($opt->getSuggestions()); $this->assertSame(['public', 'private'], $opt->getSuggestions()); $opt->setValue('public'); $opt->setValue('private'); $this->assertEquals('private', $opt->value); $this->assertEquals('--scope=[public,private]', $opt->renderReadableSpec(true)); }