Skip to content

Commit

Permalink
[Console] Fix multi select auto-complete bug for subsequent choices
Browse files Browse the repository at this point in the history
  • Loading branch information
battye committed May 3, 2019
1 parent 9041637 commit 68648b2
Showing 1 changed file with 40 additions and 5 deletions.
45 changes: 40 additions & 5 deletions src/Symfony/Component/Console/Helper/QuestionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ protected function writeError(OutputInterface $output, \Exception $error)
*/
private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete)
{
$fullChoice = '';
$ret = '';

$i = 0;
Expand All @@ -265,6 +266,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
} elseif ("\177" === $c) { // Backspace Character
if (0 === $numMatches && 0 !== $i) {
--$i;
$fullChoice = substr($fullChoice, 0, -1);
// Move cursor backwards
$output->write("\033[1D");
}
Expand Down Expand Up @@ -301,7 +303,9 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
if ($numMatches > 0 && -1 !== $ofs) {
$ret = $matches[$ofs];
// Echo out remaining chars for current match
$output->write(substr($ret, $i));
$remainingCharacters = substr($ret, strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
$output->write($remainingCharacters);
$fullChoice .= $remainingCharacters;
$i = \strlen($ret);
}

Expand All @@ -321,14 +325,22 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu

$output->write($c);
$ret .= $c;
$fullChoice .= $c;
++$i;

$tempRet = $ret;

if ($question instanceof ChoiceQuestion && $question->isMultiselect())
{
$tempRet = $this->mostRecentlyEnteredValue($ret);
}

$numMatches = 0;
$ofs = 0;

foreach ($autocomplete as $value) {
// If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
if (0 === strpos($value, $ret)) {
if (0 === strpos($value, $tempRet)) {
$matches[$numMatches++] = $value;
}
}
Expand All @@ -340,8 +352,9 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
if ($numMatches > 0 && -1 !== $ofs) {
// Save cursor position
$output->write("\0337");
// Write highlighted text
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).'</hl>');
// Write highlighted text, complete the partially entered response
$charactersEntered = strlen(trim($this->mostRecentlyEnteredValue($ret)));
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $charactersEntered)).'</hl>');
// Restore cursor position
$output->write("\0338");
}
Expand All @@ -350,9 +363,31 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
// Reset stty so it behaves normally again
shell_exec(sprintf('stty %s', $sttyMode));

return $ret;
return $fullChoice;
}

/**
* Determine the most recent value the user entered
* @param $ret
* @return string
*/
private function mostRecentlyEnteredValue($ret)
{
$tempRet = $ret;

if (strpos($ret, ',') !== false)
{
$choices = explode(',', $ret);
$lastChoice = trim($choices[count($choices) - 1]);
if (strlen($lastChoice) > 0)
{
$tempRet = $lastChoice;
}
}

return $tempRet;
}

/**
* Gets a hidden response from user.
*
Expand Down

0 comments on commit 68648b2

Please sign in to comment.