Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. CompletionInput.php

class CompletionInput

An input specialized for shell completion.

This input allows unfinished option names or values and exposes what kind of completion is expected.

@author Wouter de Jong <wouter@wouterj.nl>

Hierarchy

  • class \Symfony\Component\Console\Input\Input implements \Symfony\Component\Console\Input\InputInterface, \Symfony\Component\Console\Input\StreamableInputInterface
    • class \Symfony\Component\Console\Input\ArgvInput extends \Symfony\Component\Console\Input\Input
      • class \Symfony\Component\Console\Completion\CompletionInput extends \Symfony\Component\Console\Input\ArgvInput

Expanded class hierarchy of CompletionInput

17 files declare their use of CompletionInput
Application.php in vendor/symfony/console/Application.php
BaseCommand.php in vendor/composer/composer/src/Composer/Command/BaseCommand.php
Command.php in vendor/symfony/console/Command/Command.php
CommandCompletionTester.php in vendor/symfony/console/Tester/CommandCompletionTester.php
CompleteCommand.php in vendor/symfony/console/Command/CompleteCommand.php

... See full list

File

vendor/symfony/console/Completion/CompletionInput.php, line 27

Namespace

Symfony\Component\Console\Completion
View source
final class CompletionInput extends ArgvInput {
    public const TYPE_ARGUMENT_VALUE = 'argument_value';
    public const TYPE_OPTION_VALUE = 'option_value';
    public const TYPE_OPTION_NAME = 'option_name';
    public const TYPE_NONE = 'none';
    private array $tokens;
    private int $currentIndex;
    private string $completionType;
    private ?string $completionName = null;
    private string $completionValue = '';
    
    /**
     * Converts a terminal string into tokens.
     *
     * This is required for shell completions without COMP_WORDS support.
     */
    public static function fromString(string $inputStr, int $currentIndex) : self {
        preg_match_all('/(?<=^|\\s)([\'"]?)(.+?)(?<!\\\\)\\1(?=$|\\s)/', $inputStr, $tokens);
        return self::fromTokens($tokens[0], $currentIndex);
    }
    
    /**
     * Create an input based on an COMP_WORDS token list.
     *
     * @param string[] $tokens       the set of split tokens (e.g. COMP_WORDS or argv)
     * @param int      $currentIndex the index of the cursor (e.g. COMP_CWORD)
     */
    public static function fromTokens(array $tokens, int $currentIndex) : self {
        $input = new self($tokens);
        $input->tokens = $tokens;
        $input->currentIndex = $currentIndex;
        return $input;
    }
    public function bind(InputDefinition $definition) : void {
        parent::bind($definition);
        $relevantToken = $this->getRelevantToken();
        if ('-' === $relevantToken[0]) {
            // the current token is an input option: complete either option name or option value
            [
                $optionToken,
                $optionValue,
            ] = explode('=', $relevantToken, 2) + [
                '',
                '',
            ];
            $option = $this->getOptionFromToken($optionToken);
            if (null === $option && !$this->isCursorFree()) {
                $this->completionType = self::TYPE_OPTION_NAME;
                $this->completionValue = $relevantToken;
                return;
            }
            if ($option?->acceptValue()) {
                $this->completionType = self::TYPE_OPTION_VALUE;
                $this->completionName = $option->getName();
                $this->completionValue = $optionValue ?: (!str_starts_with($optionToken, '--') ? substr($optionToken, 2) : '');
                return;
            }
        }
        $previousToken = $this->tokens[$this->currentIndex - 1];
        if ('-' === $previousToken[0] && '' !== trim($previousToken, '-')) {
            // check if previous option accepted a value
            $previousOption = $this->getOptionFromToken($previousToken);
            if ($previousOption?->acceptValue()) {
                $this->completionType = self::TYPE_OPTION_VALUE;
                $this->completionName = $previousOption->getName();
                $this->completionValue = $relevantToken;
                return;
            }
        }
        // complete argument value
        $this->completionType = self::TYPE_ARGUMENT_VALUE;
        foreach ($this->definition
            ->getArguments() as $argumentName => $argument) {
            if (!isset($this->arguments[$argumentName])) {
                break;
            }
            $argumentValue = $this->arguments[$argumentName];
            $this->completionName = $argumentName;
            if (\is_array($argumentValue)) {
                $this->completionValue = $argumentValue ? $argumentValue[array_key_last($argumentValue)] : null;
            }
            else {
                $this->completionValue = $argumentValue;
            }
        }
        if ($this->currentIndex >= \count($this->tokens)) {
            if (!isset($this->arguments[$argumentName]) || $this->definition
                ->getArgument($argumentName)
                ->isArray()) {
                $this->completionName = $argumentName;
            }
            else {
                // we've reached the end
                $this->completionType = self::TYPE_NONE;
                $this->completionName = null;
            }
            $this->completionValue = '';
        }
    }
    
    /**
     * Returns the type of completion required.
     *
     * TYPE_ARGUMENT_VALUE when completing the value of an input argument
     * TYPE_OPTION_VALUE   when completing the value of an input option
     * TYPE_OPTION_NAME    when completing the name of an input option
     * TYPE_NONE           when nothing should be completed
     *
     * TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component.
     *
     * @return self::TYPE_*
     */
    public function getCompletionType() : string {
        return $this->completionType;
    }
    
    /**
     * The name of the input option or argument when completing a value.
     *
     * @return string|null returns null when completing an option name
     */
    public function getCompletionName() : ?string {
        return $this->completionName;
    }
    
    /**
     * The value already typed by the user (or empty string).
     */
    public function getCompletionValue() : string {
        return $this->completionValue;
    }
    public function mustSuggestOptionValuesFor(string $optionName) : bool {
        return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName();
    }
    public function mustSuggestArgumentValuesFor(string $argumentName) : bool {
        return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName();
    }
    protected function parseToken(string $token, bool $parseOptions) : bool {
        try {
            return parent::parseToken($token, $parseOptions);
        } catch (RuntimeException) {
            // suppress errors, completed input is almost never valid
        }
        return $parseOptions;
    }
    private function getOptionFromToken(string $optionToken) : ?InputOption {
        $optionName = ltrim($optionToken, '-');
        if (!$optionName) {
            return null;
        }
        if ('-' === ($optionToken[1] ?? ' ')) {
            // long option name
            return $this->definition
                ->hasOption($optionName) ? $this->definition
                ->getOption($optionName) : null;
        }
        // short option name
        return $this->definition
            ->hasShortcut($optionName[0]) ? $this->definition
            ->getOptionForShortcut($optionName[0]) : null;
    }
    
    /**
     * The token of the cursor, or the last token if the cursor is at the end of the input.
     */
    private function getRelevantToken() : string {
        return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex];
    }
    
    /**
     * Whether the cursor is "free" (i.e. at the end of the input preceded by a space).
     */
    private function isCursorFree() : bool {
        $nrOfTokens = \count($this->tokens);
        if ($this->currentIndex > $nrOfTokens) {
            throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.');
        }
        return $this->currentIndex >= $nrOfTokens;
    }
    public function __toString() : string {
        $str = '';
        foreach ($this->tokens as $i => $token) {
            $str .= $token;
            if ($this->currentIndex === $i) {
                $str .= '|';
            }
            $str .= ' ';
        }
        if ($this->currentIndex > $i) {
            $str .= '|';
        }
        return rtrim($str);
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
ArgvInput::$parsed private property
ArgvInput::addLongOption private function Adds a long option value.
ArgvInput::addShortOption private function Adds a short option value.
ArgvInput::getFirstArgument public function Returns the first argument from the raw parameters (not parsed). Overrides InputInterface::getFirstArgument
ArgvInput::getParameterOption public function Returns the value of a raw option (not parsed). Overrides InputInterface::getParameterOption
ArgvInput::getRawTokens public function Returns un-parsed and not validated tokens.
ArgvInput::hasParameterOption public function Returns true if the raw parameters (not parsed) contain a value. Overrides InputInterface::hasParameterOption
ArgvInput::parse protected function Processes command line arguments. Overrides Input::parse
ArgvInput::parseArgument private function Parses an argument.
ArgvInput::parseLongOption private function Parses a long option.
ArgvInput::parseShortOption private function Parses a short option.
ArgvInput::parseShortOptionSet private function Parses a short option set.
ArgvInput::setTokens protected function
ArgvInput::__construct public function Overrides Input::__construct 1
CompletionInput::$completionName private property
CompletionInput::$completionType private property
CompletionInput::$completionValue private property
CompletionInput::$currentIndex private property
CompletionInput::$tokens private property @var list&lt;string&gt; Overrides ArgvInput::$tokens
CompletionInput::bind public function Binds the current Input instance with the given arguments and options. Overrides Input::bind
CompletionInput::fromString public static function Converts a terminal string into tokens.
CompletionInput::fromTokens public static function Create an input based on an COMP_WORDS token list.
CompletionInput::getCompletionName public function The name of the input option or argument when completing a value.
CompletionInput::getCompletionType public function Returns the type of completion required.
CompletionInput::getCompletionValue public function The value already typed by the user (or empty string).
CompletionInput::getOptionFromToken private function
CompletionInput::getRelevantToken private function The token of the cursor, or the last token if the cursor is at the end of the input.
CompletionInput::isCursorFree private function Whether the cursor is &quot;free&quot; (i.e. at the end of the input preceded by a space).
CompletionInput::mustSuggestArgumentValuesFor public function
CompletionInput::mustSuggestOptionValuesFor public function
CompletionInput::parseToken protected function Overrides ArgvInput::parseToken
CompletionInput::TYPE_ARGUMENT_VALUE public constant
CompletionInput::TYPE_NONE public constant
CompletionInput::TYPE_OPTION_NAME public constant
CompletionInput::TYPE_OPTION_VALUE public constant
CompletionInput::__toString public function Returns a stringified representation of the args passed to the command. Overrides ArgvInput::__toString
Input::$arguments protected property
Input::$definition protected property
Input::$interactive protected property
Input::$options protected property
Input::$stream protected property @var resource
Input::escapeToken public function Escapes a token through escapeshellarg if it contains unsafe chars.
Input::getArgument public function Returns the argument value for a given argument name. Overrides InputInterface::getArgument
Input::getArguments public function Returns all the given arguments merged with the default values. Overrides InputInterface::getArguments
Input::getOption public function Returns the option value for a given option name. Overrides InputInterface::getOption
Input::getOptions public function Returns all the given options merged with the default values. Overrides InputInterface::getOptions
Input::getStream public function Overrides StreamableInputInterface::getStream
Input::hasArgument public function Returns true if an InputArgument object exists by name or position. Overrides InputInterface::hasArgument
Input::hasOption public function Returns true if an InputOption object exists by name. Overrides InputInterface::hasOption
Input::isInteractive public function Is this input means interactive? Overrides InputInterface::isInteractive
Input::setArgument public function Sets an argument value by name. Overrides InputInterface::setArgument
Input::setInteractive public function Sets the input interactivity. Overrides InputInterface::setInteractive
Input::setOption public function Sets an option value by name. Overrides InputInterface::setOption
Input::setStream public function Overrides StreamableInputInterface::setStream
Input::validate public function Validates the input. Overrides InputInterface::validate

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal