bug #35578 [Console][QuestionHelper] Use String width() to properly move the cursor backwards (fancyweb)
This PR was merged into the 5.1-dev branch.
Discussion
----------
[Console][QuestionHelper] Use String width() to properly move the cursor backwards
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/symfony/symfony/pull/35536#issuecomment-581343181
| License | MIT
| Doc PR | -
This bug can only be fixed on master since we need to require the String component. Once the component is required, we can iterate in the Console component to use it more where it is needed.
Commits
-------
67a1f55ce1
[Console][QuestionHelper] Use String width() to properly move the cursor backwards
This commit is contained in:
commit
da9f3af3e1
|
@ -22,6 +22,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Console\Terminal;
|
||||
use function Symfony\Component\String\s;
|
||||
|
||||
/**
|
||||
* The QuestionHelper class provides helpers to interact with the user.
|
||||
|
@ -242,9 +243,10 @@ class QuestionHelper extends Helper
|
|||
} elseif ("\177" === $c) { // Backspace Character
|
||||
if (0 === $numMatches && 0 !== $i) {
|
||||
--$i;
|
||||
$fullChoice = self::substr($fullChoice, 0, $i);
|
||||
// Move cursor backwards
|
||||
$output->write("\033[1D");
|
||||
$output->write(sprintf("\033[%dD", s($fullChoice)->slice(-1)->width(false)));
|
||||
|
||||
$fullChoice = self::substr($fullChoice, 0, $i);
|
||||
}
|
||||
|
||||
if (0 === $i) {
|
||||
|
|
|
@ -797,6 +797,25 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
|||
$this->assertEquals(['AcmeDemoBundle', 'AsseticBundle'], $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
public function testAutocompleteMoveCursorBackwards()
|
||||
{
|
||||
// F<TAB><BACKSPACE><BACKSPACE><BACKSPACE>
|
||||
$inputStream = $this->getInputStream("F\t\177\177\177");
|
||||
|
||||
$dialog = new QuestionHelper();
|
||||
$helperSet = new HelperSet([new FormatterHelper()]);
|
||||
$dialog->setHelperSet($helperSet);
|
||||
|
||||
$question = new Question('Question?', 'F⭐Y');
|
||||
$question->setAutocompleterValues(['F⭐Y']);
|
||||
|
||||
$dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question);
|
||||
|
||||
$stream = $output->getStream();
|
||||
rewind($stream);
|
||||
$this->assertStringEndsWith("\033[1D\033[K\033[2D\033[K\033[1D\033[K", stream_get_contents($stream));
|
||||
}
|
||||
|
||||
protected function getInputStream($input)
|
||||
{
|
||||
$stream = fopen('php://memory', 'r+', false);
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
"php": "^7.2.5",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php73": "^1.8",
|
||||
"symfony/service-contracts": "^1.1|^2"
|
||||
"symfony/service-contracts": "^1.1|^2",
|
||||
"symfony/string": "^5.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "^4.4|^5.0",
|
||||
|
|
Reference in New Issue