PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / prefixed / symfony / console / Completion / CompletionInput.php
matomo / app / vendor / prefixed / symfony / console / Completion Last commit date
Output 2 years ago CompletionInput.php 1 year ago CompletionSuggestions.php 2 years ago Suggestion.php 2 years ago
CompletionInput.php
213 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace Matomo\Dependencies\Symfony\Component\Console\Completion;
12
13 use Matomo\Dependencies\Symfony\Component\Console\Exception\RuntimeException;
14 use Matomo\Dependencies\Symfony\Component\Console\Input\ArgvInput;
15 use Matomo\Dependencies\Symfony\Component\Console\Input\InputDefinition;
16 use Matomo\Dependencies\Symfony\Component\Console\Input\InputOption;
17 /**
18 * An input specialized for shell completion.
19 *
20 * This input allows unfinished option names or values and exposes what kind of
21 * completion is expected.
22 *
23 * @author Wouter de Jong <wouter@wouterj.nl>
24 */
25 final class CompletionInput extends ArgvInput
26 {
27 public const TYPE_ARGUMENT_VALUE = 'argument_value';
28 public const TYPE_OPTION_VALUE = 'option_value';
29 public const TYPE_OPTION_NAME = 'option_name';
30 public const TYPE_NONE = 'none';
31 private $tokens;
32 private $currentIndex;
33 private $completionType;
34 private $completionName = null;
35 private $completionValue = '';
36 /**
37 * Converts a terminal string into tokens.
38 *
39 * This is required for shell completions without COMP_WORDS support.
40 */
41 public static function fromString(string $inputStr, int $currentIndex) : self
42 {
43 preg_match_all('/(?<=^|\\s)([\'"]?)(.+?)(?<!\\\\)\\1(?=$|\\s)/', $inputStr, $tokens);
44 return self::fromTokens($tokens[0], $currentIndex);
45 }
46 /**
47 * Create an input based on an COMP_WORDS token list.
48 *
49 * @param string[] $tokens the set of split tokens (e.g. COMP_WORDS or argv)
50 * @param int $currentIndex the index of the cursor (e.g. COMP_CWORD)
51 */
52 public static function fromTokens(array $tokens, int $currentIndex) : self
53 {
54 $input = new self($tokens);
55 $input->tokens = $tokens;
56 $input->currentIndex = $currentIndex;
57 return $input;
58 }
59 /**
60 * {@inheritdoc}
61 */
62 public function bind(InputDefinition $definition) : void
63 {
64 parent::bind($definition);
65 $relevantToken = $this->getRelevantToken();
66 if ('-' === $relevantToken[0]) {
67 // the current token is an input option: complete either option name or option value
68 [$optionToken, $optionValue] = explode('=', $relevantToken, 2) + ['', ''];
69 $option = $this->getOptionFromToken($optionToken);
70 if (null === $option && !$this->isCursorFree()) {
71 $this->completionType = self::TYPE_OPTION_NAME;
72 $this->completionValue = $relevantToken;
73 return;
74 }
75 if (null !== $option && $option->acceptValue()) {
76 $this->completionType = self::TYPE_OPTION_VALUE;
77 $this->completionName = $option->getName();
78 $this->completionValue = $optionValue ?: (!str_starts_with($optionToken, '--') ? substr($optionToken, 2) : '');
79 return;
80 }
81 }
82 $previousToken = $this->tokens[$this->currentIndex - 1];
83 if ('-' === $previousToken[0] && '' !== trim($previousToken, '-')) {
84 // check if previous option accepted a value
85 $previousOption = $this->getOptionFromToken($previousToken);
86 if (null !== $previousOption && $previousOption->acceptValue()) {
87 $this->completionType = self::TYPE_OPTION_VALUE;
88 $this->completionName = $previousOption->getName();
89 $this->completionValue = $relevantToken;
90 return;
91 }
92 }
93 // complete argument value
94 $this->completionType = self::TYPE_ARGUMENT_VALUE;
95 foreach ($this->definition->getArguments() as $argumentName => $argument) {
96 if (!isset($this->arguments[$argumentName])) {
97 break;
98 }
99 $argumentValue = $this->arguments[$argumentName];
100 $this->completionName = $argumentName;
101 if (\is_array($argumentValue)) {
102 $this->completionValue = $argumentValue ? $argumentValue[array_key_last($argumentValue)] : null;
103 } else {
104 $this->completionValue = $argumentValue;
105 }
106 }
107 if ($this->currentIndex >= \count($this->tokens)) {
108 if (!isset($this->arguments[$argumentName]) || $this->definition->getArgument($argumentName)->isArray()) {
109 $this->completionName = $argumentName;
110 $this->completionValue = '';
111 } else {
112 // we've reached the end
113 $this->completionType = self::TYPE_NONE;
114 $this->completionName = null;
115 $this->completionValue = '';
116 }
117 }
118 }
119 /**
120 * Returns the type of completion required.
121 *
122 * TYPE_ARGUMENT_VALUE when completing the value of an input argument
123 * TYPE_OPTION_VALUE when completing the value of an input option
124 * TYPE_OPTION_NAME when completing the name of an input option
125 * TYPE_NONE when nothing should be completed
126 *
127 * @return string One of self::TYPE_* constants. TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component
128 */
129 public function getCompletionType() : string
130 {
131 return $this->completionType;
132 }
133 /**
134 * The name of the input option or argument when completing a value.
135 *
136 * @return string|null returns null when completing an option name
137 */
138 public function getCompletionName() : ?string
139 {
140 return $this->completionName;
141 }
142 /**
143 * The value already typed by the user (or empty string).
144 */
145 public function getCompletionValue() : string
146 {
147 return $this->completionValue;
148 }
149 public function mustSuggestOptionValuesFor(string $optionName) : bool
150 {
151 return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName();
152 }
153 public function mustSuggestArgumentValuesFor(string $argumentName) : bool
154 {
155 return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName();
156 }
157 protected function parseToken(string $token, bool $parseOptions) : bool
158 {
159 try {
160 return parent::parseToken($token, $parseOptions);
161 } catch (RuntimeException $e) {
162 // suppress errors, completed input is almost never valid
163 }
164 return $parseOptions;
165 }
166 private function getOptionFromToken(string $optionToken) : ?InputOption
167 {
168 $optionName = ltrim($optionToken, '-');
169 if (!$optionName) {
170 return null;
171 }
172 if ('-' === ($optionToken[1] ?? ' ')) {
173 // long option name
174 return $this->definition->hasOption($optionName) ? $this->definition->getOption($optionName) : null;
175 }
176 // short option name
177 return $this->definition->hasShortcut($optionName[0]) ? $this->definition->getOptionForShortcut($optionName[0]) : null;
178 }
179 /**
180 * The token of the cursor, or the last token if the cursor is at the end of the input.
181 */
182 private function getRelevantToken() : string
183 {
184 return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex];
185 }
186 /**
187 * Whether the cursor is "free" (i.e. at the end of the input preceded by a space).
188 */
189 private function isCursorFree() : bool
190 {
191 $nrOfTokens = \count($this->tokens);
192 if ($this->currentIndex > $nrOfTokens) {
193 throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.');
194 }
195 return $this->currentIndex >= $nrOfTokens;
196 }
197 public function __toString()
198 {
199 $str = '';
200 foreach ($this->tokens as $i => $token) {
201 $str .= $token;
202 if ($this->currentIndex === $i) {
203 $str .= '|';
204 }
205 $str .= ' ';
206 }
207 if ($this->currentIndex > $i) {
208 $str .= '|';
209 }
210 return rtrim($str);
211 }
212 }
213