Skip to content

Commit a1129f9

Browse files
committed
[Console] Fix autocomplete multibyte input support
1 parent fa783f9 commit a1129f9

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

src/Symfony/Component/Console/Helper/QuestionHelper.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
264264
} elseif ("\177" === $c) { // Backspace Character
265265
if (0 === $numMatches && 0 !== $i) {
266266
--$i;
267-
$fullChoice = substr($fullChoice, 0, -1);
267+
$fullChoice = self::substr($fullChoice, 0, -1);
268268
// Move cursor backwards
269269
$output->write("\033[1D");
270270
}
@@ -278,7 +278,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
278278
}
279279

280280
// Pop the last character off the end of our string
281-
$ret = substr($ret, 0, $i);
281+
$ret = self::substr($ret, 0, $i);
282282
} elseif ("\033" === $c) {
283283
// Did we read an escape sequence?
284284
$c .= fread($inputStream, 2);
@@ -304,7 +304,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
304304
$remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
305305
$output->write($remainingCharacters);
306306
$fullChoice .= $remainingCharacters;
307-
$i = \strlen($fullChoice);
307+
$i = self::strlen($fullChoice);
308308
}
309309

310310
if ("\n" === $c) {

src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php

+12-8
Original file line numberDiff line numberDiff line change
@@ -175,19 +175,20 @@ public function testAskWithAutocomplete()
175175
// Acm<NEWLINE>
176176
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
177177
// <NEWLINE>
178-
// <UP ARROW><UP ARROW><NEWLINE>
179-
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
178+
// <UP ARROW><UP ARROW><UP ARROW><NEWLINE>
179+
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
180180
// <DOWN ARROW><NEWLINE>
181181
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
182182
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
183-
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
183+
// F⭐<TAB><BACKSPACE><BACKSPACE>⭐<TAB><NEWLINE>
184+
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\nF⭐\t\177\177\t\n");
184185

185186
$dialog = new QuestionHelper();
186187
$helperSet = new HelperSet([new FormatterHelper()]);
187188
$dialog->setHelperSet($helperSet);
188189

189190
$question = new Question('Please select a bundle', 'FrameworkBundle');
190-
$question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle']);
191+
$question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle', 'F⭐Y']);
191192

192193
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
193194
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
@@ -197,6 +198,7 @@ public function testAskWithAutocomplete()
197198
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
198199
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
199200
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
201+
$this->assertEquals('F⭐Y', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
200202
}
201203

202204
public function testAskWithAutocompleteWithNonSequentialKeys()
@@ -680,20 +682,21 @@ public function testLegacyAskWithAutocomplete()
680682
// Acm<NEWLINE>
681683
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
682684
// <NEWLINE>
683-
// <UP ARROW><UP ARROW><NEWLINE>
684-
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
685+
// <UP ARROW><UP ARROW><UP ARROW><NEWLINE>
686+
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
685687
// <DOWN ARROW><NEWLINE>
686688
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
687689
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
688-
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
690+
// F⭐<TAB><BACKSPACE><BACKSPACE>⭐<TAB><NEWLINE>
691+
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\nF⭐\t⭐\t\n");
689692

690693
$dialog = new QuestionHelper();
691694
$dialog->setInputStream($inputStream);
692695
$helperSet = new HelperSet([new FormatterHelper()]);
693696
$dialog->setHelperSet($helperSet);
694697

695698
$question = new Question('Please select a bundle', 'FrameworkBundle');
696-
$question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle']);
699+
$question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle', 'F⭐Y']);
697700

698701
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
699702
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
@@ -703,6 +706,7 @@ public function testLegacyAskWithAutocomplete()
703706
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
704707
$this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
705708
$this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
709+
$this->assertEquals('F⭐Y', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
706710
}
707711

708712
/**

0 commit comments

Comments
 (0)