/** * Constructs object, parses command * * @param string $line Command to make completions for */ public function __construct($line) { // TODO: properly parse single and double quotes $this->words = explode(' ', $line); if ($this->words[0] == 'terminus') { array_shift($this->words); } //The last word is either empty or an incomplete subcommand $this->cur_word = end($this->words); $r = $this->getCommand($this->words); if (!is_array($r)) { return; } /** @var \Terminus\Dispatcher\RootCommand $command */ list($command, $args, $assoc_args) = $r; $spec = SynopsisParser::parse($command->getSynopsis()); foreach ($spec as $arg) { if ($arg['type'] == 'positional' && $arg['name'] == 'file') { $this->add('<file> '); return; } } if ($command->canHaveSubcommands()) { foreach ($command->getSubcommands() as $name => $_) { $this->add("{$name} "); } } else { foreach ($spec as $arg) { if (in_array($arg['type'], array('flag', 'assoc'))) { if (isset($assoc_args[$arg['name']])) { continue; } $option = "--{$arg['name']}"; if ($arg['type'] == 'flag') { $option .= ' '; } elseif (!$arg['value']['optional']) { $option .= '='; } $this->add($option); } } } }
/** * Constructs object, parses command * * @param [string] $line Command to make completions for * @return [Completions] $htis */ function __construct($line) { // TODO: properly parse single and double quotes $this->words = explode(' ', $line); // first word is always `wp` array_shift($this->words); // last word is either empty or an incomplete subcommand $this->cur_word = end($this->words); $r = $this->getCommand($this->words); if (!is_array($r)) { return; } list($command, $args, $assoc_args) = $r; $spec = SynopsisParser::parse($command->get_synopsis()); foreach ($spec as $arg) { if ($arg['type'] == 'positional' && $arg['name'] == 'file') { $this->add('<file> '); return; } } if ($command->can_have_subcommands()) { foreach ($command->get_subcommands() as $name => $_) { $this->add("{$name} "); } } else { foreach ($spec as $arg) { if (in_array($arg['type'], array('flag', 'assoc'))) { if (isset($assoc_args[$arg['name']])) { continue; } $opt = "--{$arg['name']}"; if ($arg['type'] == 'flag') { $opt .= ' '; } elseif (!$arg['value']['optional']) { $opt .= '='; } $this->add($opt); } } } }
private function prompt_args($args, $assoc_args) { $synopsis = $this->get_synopsis(); if (!$synopsis) { return array($args, $assoc_args); } $spec = array_filter(Terminus\SynopsisParser::parse($synopsis), function ($spec_arg) { return in_array($spec_arg['type'], array('generic', 'positional', 'assoc', 'flag')); }); $spec = array_values($spec); // 'positional' arguments are positional (aka zero-indexed) // so $args needs to be reset before prompting for new arguments $args = array(); foreach ($spec as $key => $spec_arg) { $current_prompt = $key + 1 . '/' . count($spec) . ' '; $default = $spec_arg['optional'] ? '' : false; // 'generic' permits arbitrary key=value (e.g. [--<field>=<value>] ) if ('generic' == $spec_arg['type']) { list($key_token, $value_token) = explode('=', $spec_arg['token']); $repeat = false; do { if (!$repeat) { $key_prompt = $current_prompt . $key_token; } else { $key_prompt = str_repeat(" ", strlen($current_prompt)) . $key_token; } $key = $this->prompt($key_prompt, $default); if (false === $key) { return array($args, $assoc_args); } if ($key) { $key_prompt_count = strlen($key_prompt) - strlen($value_token) - 1; $value_prompt = str_repeat(" ", $key_prompt_count) . '=' . $value_token; $value = $this->prompt($value_prompt, $default); if (false === $value) { return array($args, $assoc_args); } $assoc_args[$key] = $value; $repeat = true; $required = false; } else { $repeat = false; } } while ($required || $repeat); } else { $prompt = $current_prompt . $spec_arg['token']; if ('flag' == $spec_arg['type']) { $prompt .= ' (Y/n)'; } $response = $this->prompt($prompt, $default); if (false === $response) { return array($args, $assoc_args); } if ($response) { switch ($spec_arg['type']) { case 'positional': if ($spec_arg['repeating']) { $response = explode(' ', $response); } else { $response = array($response); } $args = array_merge($args, $response); break; case 'assoc': $assoc_args[$spec_arg['name']] = $response; break; case 'flag': if ('Y' == $response) { $assoc_args[$spec_arg['name']] = true; } break; } } } } return array($args, $assoc_args); }
public function __construct($synopsis) { $this->spec = SynopsisParser::parse($synopsis); }