Application.php
protected function getBashCompletion()
    {
        // Bash completion variables.
        $completion = '';
        $function = '';
        $tab = str_repeat(' ', 4);

        // Application variables.
        $appName = $this->getName();
        $appVersion = $this->getVersion();
        $appId = basename($_SERVER['SCRIPT_NAME']);

        // Command variables.
        $commands = '"' . implode('" "', array_keys($this->commands)) . '"';
        $defaulOptions = '"--' . implode('" "--', $this->getDefaultOptionIds()) . '"';

        // Headers.
        $headers = <<<HEADERS
#!/bin/bash

# Bash Completion for $appName ($appVersion)
# Generated by IN2PIRE CLI Framework (https://github.com/in2pire/in2pire-cli)
HEADERS;

        // Function.
        $function .= $tab . 'COMPREPLY=()' . PHP_EOL;
        $function .= $tab . 'local cur=${COMP_WORDS[COMP_CWORD]}' . PHP_EOL;
        $function .= $tab . 'local prev=${COMP_WORDS[COMP_CWORD-1]}' . PHP_EOL;
        $function .= $tab . 'local options=(' . $defaulOptions . ')' . PHP_EOL;
        $function .= $tab . 'local arrayOptions=()' . PHP_EOL;
        $function .= PHP_EOL;
        $function .= $tab . 'if [ $COMP_CWORD -eq 1 ]; then' . PHP_EOL;
        $function .= $tab . $tab . 'if [[ ${cur} == -* ]] ; then' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'COMPREPLY=( $( compgen -W "${options[*]}" -- $cur) )' . PHP_EOL;
        $function .= $tab . $tab . 'else' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'commands=(' . $commands . ')' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'COMPREPLY=( $( compgen -W "${commands[*]}" -- $cur) )' . PHP_EOL;
        $function .= $tab . $tab . 'fi' . PHP_EOL;
        $function .= $tab . $tab . 'return 0' . PHP_EOL;
        $function .= $tab . 'fi' . PHP_EOL;
        $function .= PHP_EOL;

        $cases = [];
        $caseContents = [];

        foreach ($this->commandAliases as $commandId => $aliases) {
            $command = $this->commands[$commandId];
            $definition = $command->getDefinition();
            $options = [];
            $arrayOptions = [];
            $possibleOptionValues = [];

            foreach ($definition->getOptions() as $option) {
                $optionName = $option->getName();

                if ($option instanceof \In2pire\Cli\Input\InputOption) {
                    if ($option->isFlag() || !$option->acceptValue()) {
                        $options[] = '--' . $optionName;
                        continue;
                    }

                    $possibleValues = $option->getPossibleValues();

                    if (!empty($possibleValues)) {
                        $possibleOptionValues[$optionName] = array_filter($possibleValues, function ($value) {
                            return $value !== '';
                        });
                    }
                }

                $options[] = '--' . $optionName;

                if ($option->isArray()) {
                    $arrayOptions[] = $optionName;
                }
            }

            if (!empty($options)) {
                $signature = md5(serialize($options) . serialize($arrayOptions) . serialize($possibleOptionValues));

                if (isset($cases[$signature])) {
                    $cases[$signature] = array_merge($cases[$signature], $aliases);
                } else {
                    $cases[$signature] = $aliases;
                    $caseContents[$signature]['options'] = $options;
                    $caseContents[$signature]['arrayOptions'] = $arrayOptions;
                    $caseContents[$signature]['possibleOptionValues'] = $possibleOptionValues;
                }
            }
        }

        if (!empty($cases)) {
            $function .= $tab . 'case "${COMP_WORDS[1]}" in' . PHP_EOL;

            foreach ($cases as $case => $conditions) {
                $function .= $tab . $tab . '"' . implode('"|"', $conditions) . '")' . PHP_EOL;

                if (empty($caseContents[$case]['possibleOptionValues'])) {
                    $function .= $tab . $tab . $tab . 'options+=("' . implode('" "', $caseContents[$case]['options']) . '")' . PHP_EOL;

                    if (!empty($caseContents[$case]['arrayOptions'])) {
                        $function .= $tab . $tab . $tab . 'arrayOptions+=("' . implode('" "', $caseContents[$case]['arrayOptions']) . '")' . PHP_EOL;
                    }
                } else {
                    $function .= $tab . $tab . $tab . 'if [[ ${cur} == -* ]] ; then' . PHP_EOL;
                    $function .= $tab . $tab . $tab . $tab . 'options+=("' . implode('" "', $caseContents[$case]['options']) . '")' . PHP_EOL;

                    if (!empty($caseContents[$case]['arrayOptions'])) {
                        $function .= $tab . $tab . $tab . $tab . 'arrayOptions+=("' . implode('" "', $caseContents[$case]['arrayOptions']) . '")' . PHP_EOL;
                    }

                    $function .= $tab . $tab . $tab . 'else' . PHP_EOL;
                    $function .= $tab . $tab . $tab . $tab . 'case "$prev" in' . PHP_EOL;

                    foreach ($caseContents[$case]['possibleOptionValues'] as $option => $possibleOptionValue) {
                        $function .= $tab . $tab . $tab . $tab . $tab . '"--' . $option . '")' . PHP_EOL;
                        $function .= $tab . $tab . $tab . $tab . $tab . $tab . 'options=("' . implode('" "', $possibleOptionValue) . '")' . PHP_EOL;
                        $function .= $tab . $tab . $tab . $tab . $tab . ';;' . PHP_EOL;
                    }

                    $function .= $tab . $tab . $tab . $tab . $tab . '*)' . PHP_EOL;
                    $function .= $tab . $tab . $tab . $tab . $tab . $tab . 'options+=("' . implode('" "', $caseContents[$case]['options']) . '")' . PHP_EOL;

                    if (!empty($caseContents[$case]['arrayOptions'])) {
                        $function .= $tab . $tab . $tab . $tab . $tab . $tab . 'arrayOptions+=("' . implode('" "', $caseContents[$case]['arrayOptions']) . '")' . PHP_EOL;
                    }

                    $function .= $tab . $tab . $tab . $tab . $tab . ';;' . PHP_EOL;

                    $function .= $tab . $tab . $tab . $tab . 'esac' . PHP_EOL;
                    $function .= $tab . $tab . $tab . 'fi' . PHP_EOL;
                }

                $function .= $tab . $tab . ';;' . PHP_EOL;
            }

            $function .= $tab . 'esac' . PHP_EOL;
            $function .= PHP_EOL;
        }

        $function .= $tab . 'filteredOptions=()' . PHP_EOL;
        $function .= $tab . 'for opt in "${options[@]}"; do' . PHP_EOL;
        $function .= $tab . $tab . 'skip=' . PHP_EOL;
        $function .= $tab . $tab . 'for word in "${COMP_WORDS[@]}"; do' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'if [[ $opt == $word ]]; then' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . 'skip=1' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . 'for optArr in "${arrayOptions[@]}"; do' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . $tab . '[[ $opt == $optArr ]] && { skip=; break; }' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . 'done' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . '[[ -n $skip ]] && break;' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'fi' . PHP_EOL;
        $function .= $tab . $tab . 'done' . PHP_EOL;
        $function .= $tab . $tab . '[[ -n $skip ]] || filteredOptions+=("$opt");' . PHP_EOL;
        $function .= $tab . 'done' . PHP_EOL;
        $function .= PHP_EOL;

        $function .= $tab . 'COMPREPLY=( $( compgen -W "${filteredOptions[*]}" -- $cur) )' . PHP_EOL;

        // Bash Completion.
        $completion .= $headers . PHP_EOL;
        $completion .= PHP_EOL;
        $completion .= "_$appId() {" . PHP_EOL;
        $completion .= $function;
        $completion .= '}' . PHP_EOL;
        $completion .= PHP_EOL;
        $completion .= "complete -F _$appId $appId" . PHP_EOL;

        if (!empty($this->alias)) {
            $completion .= "complete -F _$appId " . $this->alias . PHP_EOL;
        }

        $completion .= PHP_EOL;

        return $completion;
    }
protected function getBashCompletion()
    {
        // Bash completion variables.
        $completion = '';
        $function = '';
        $tab = str_repeat(' ', 4);

        // Application variables.
        $appName = $this->getName();
        $appVersion = $this->getVersion();
        $appId = basename($_SERVER['SCRIPT_NAME']);

        // Command variables.
        $commands = '"' . implode('" "', array_keys($this->commands)) . '"';
        $defaulOptions = '"--' . implode('" "--', $this->getDefaultOptionIds()) . '"';

        // Headers.
        $headers = <<<HEADERS
#!/bin/bash

# Bash Completion for $appName ($appVersion)
# Generated by IN2PIRE CLI Framework (https://github.com/in2pire/in2pire-cli)
HEADERS;

        // Function.
        $function .= $tab . 'COMPREPLY=()' . PHP_EOL;
        $function .= $tab . 'local cur=${COMP_WORDS[COMP_CWORD]}' . PHP_EOL;
        $function .= $tab . 'local prev=${COMP_WORDS[COMP_CWORD-1]}' . PHP_EOL;
        $function .= $tab . 'local options=(' . $defaulOptions . ')' . PHP_EOL;
        $function .= $tab . 'local arrayOptions=()' . PHP_EOL;
        $function .= PHP_EOL;
        $function .= $tab . 'if [ $COMP_CWORD -eq 1 ]; then' . PHP_EOL;
        $function .= $tab . $tab . 'if [[ ${cur} == -* ]] ; then' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'COMPREPLY=( $( compgen -W "${options[*]}" -- $cur) )' . PHP_EOL;
        $function .= $tab . $tab . 'else' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'commands=(' . $commands . ')' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'COMPREPLY=( $( compgen -W "${commands[*]}" -- $cur) )' . PHP_EOL;
        $function .= $tab . $tab . 'fi' . PHP_EOL;
        $function .= $tab . $tab . 'return 0' . PHP_EOL;
        $function .= $tab . 'fi' . PHP_EOL;
        $function .= PHP_EOL;

        $cases = [];
        $caseContents = [];

        foreach ($this->commandAliases as $commandId => $aliases) {
            $command = $this->commands[$commandId];
            $definition = $command->getDefinition();
            $options = [];
            $arrayOptions = [];
            $possibleOptionValues = [];

            foreach ($definition->getOptions() as $option) {
                $optionName = $option->getName();

                if ($option instanceof \In2pire\Cli\Input\InputOption) {
                    if ($option->isFlag() || !$option->acceptValue()) {
                        $options[] = '--' . $optionName;
                        continue;
                    }

                    $possibleValues = $option->getPossibleValues();

                    if (!empty($possibleValues)) {
                        $possibleOptionValues[$optionName] = array_filter($possibleValues, function ($value) {
                            return $value !== '';
                        });
                    }
                }

                $options[] = '--' . $optionName;

                if ($option->isArray()) {
                    $arrayOptions[] = $optionName;
                }
            }

            if (!empty($options)) {
                $signature = md5(serialize($options) . serialize($arrayOptions) . serialize($possibleOptionValues));

                if (isset($cases[$signature])) {
                    $cases[$signature] = array_merge($cases[$signature], $aliases);
                } else {
                    $cases[$signature] = $aliases;
                    $caseContents[$signature]['options'] = $options;
                    $caseContents[$signature]['arrayOptions'] = $arrayOptions;
                    $caseContents[$signature]['possibleOptionValues'] = $possibleOptionValues;
                }
            }
        }

        if (!empty($cases)) {
            $function .= $tab . 'case "${COMP_WORDS[1]}" in' . PHP_EOL;

            foreach ($cases as $case => $conditions) {
                $function .= $tab . $tab . '"' . implode('"|"', $conditions) . '")' . PHP_EOL;

                if (empty($caseContents[$case]['possibleOptionValues'])) {
                    $function .= $tab . $tab . $tab . 'options+=("' . implode('" "', $caseContents[$case]['options']) . '")' . PHP_EOL;

                    if (!empty($caseContents[$case]['arrayOptions'])) {
                        $function .= $tab . $tab . $tab . 'arrayOptions+=("' . implode('" "', $caseContents[$case]['arrayOptions']) . '")' . PHP_EOL;
                    }
                } else {
                    $function .= $tab . $tab . $tab . 'if [[ ${cur} == -* ]] ; then' . PHP_EOL;
                    $function .= $tab . $tab . $tab . $tab . 'options+=("' . implode('" "', $caseContents[$case]['options']) . '")' . PHP_EOL;

                    if (!empty($caseContents[$case]['arrayOptions'])) {
                        $function .= $tab . $tab . $tab . $tab . 'arrayOptions+=("' . implode('" "', $caseContents[$case]['arrayOptions']) . '")' . PHP_EOL;
                    }

                    $function .= $tab . $tab . $tab . 'else' . PHP_EOL;
                    $function .= $tab . $tab . $tab . $tab . 'case "$prev" in' . PHP_EOL;

                    foreach ($caseContents[$case]['possibleOptionValues'] as $option => $possibleOptionValue) {
                        $function .= $tab . $tab . $tab . $tab . $tab . '"--' . $option . '")' . PHP_EOL;
                        $function .= $tab . $tab . $tab . $tab . $tab . $tab . 'options=("' . implode('" "', $possibleOptionValue) . '")' . PHP_EOL;
                        $function .= $tab . $tab . $tab . $tab . $tab . ';;' . PHP_EOL;
                    }

                    $function .= $tab . $tab . $tab . $tab . $tab . '*)' . PHP_EOL;
                    $function .= $tab . $tab . $tab . $tab . $tab . $tab . 'options+=("' . implode('" "', $caseContents[$case]['options']) . '")' . PHP_EOL;

                    if (!empty($caseContents[$case]['arrayOptions'])) {
                        $function .= $tab . $tab . $tab . $tab . $tab . $tab . 'arrayOptions+=("' . implode('" "', $caseContents[$case]['arrayOptions']) . '")' . PHP_EOL;
                    }

                    $function .= $tab . $tab . $tab . $tab . $tab . ';;' . PHP_EOL;

                    $function .= $tab . $tab . $tab . $tab . 'esac' . PHP_EOL;
                    $function .= $tab . $tab . $tab . 'fi' . PHP_EOL;
                }

                $function .= $tab . $tab . ';;' . PHP_EOL;
            }

            $function .= $tab . 'esac' . PHP_EOL;
            $function .= PHP_EOL;
        }

        $function .= $tab . 'filteredOptions=()' . PHP_EOL;
        $function .= $tab . 'for opt in "${options[@]}"; do' . PHP_EOL;
        $function .= $tab . $tab . 'skip=' . PHP_EOL;
        $function .= $tab . $tab . 'for word in "${COMP_WORDS[@]}"; do' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'if [[ $opt == $word ]]; then' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . 'skip=1' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . 'for optArr in "${arrayOptions[@]}"; do' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . $tab . '[[ $opt == $optArr ]] && { skip=; break; }' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . 'done' . PHP_EOL;
        $function .= $tab . $tab . $tab . $tab . '[[ -n $skip ]] && break;' . PHP_EOL;
        $function .= $tab . $tab . $tab . 'fi' . PHP_EOL;
        $function .= $tab . $tab . 'done' . PHP_EOL;
        $function .= $tab . $tab . '[[ -n $skip ]] || filteredOptions+=("$opt");' . PHP_EOL;
        $function .= $tab . 'done' . PHP_EOL;
        $function .= PHP_EOL;

        $function .= $tab . 'COMPREPLY=( $( compgen -W "${filteredOptions[*]}" -- $cur) )' . PHP_EOL;

        // Bash Completion.
        $completion .= $headers . PHP_EOL;
        $completion .= PHP_EOL;
        $completion .= "_$appId() {" . PHP_EOL;
        $completion .= $function;
        $completion .= '}' . PHP_EOL;
        $completion .= PHP_EOL;
        $completion .= "complete -F _$appId $appId" . PHP_EOL;

        if (!empty($this->alias)) {
            $completion .= "complete -F _$appId " . $this->alias . PHP_EOL;
        }

        $completion .= PHP_EOL;

        return $completion;
    }
Get bash completion.

@return string
Bash completion.