feature #15382 [Console] Use readline for user input when available #DX (michaelperrin)

This PR was merged into the 2.8 branch.

Discussion
----------

[Console] Use readline for user input when available #DX

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Given I am entering data in an user input
When I use left and right keys to make some changes in what I have typed
Then the cursor should move accordingly instead of adding characters at the end of the line

To make it simple: using the arrow keys (←  →)  to make changes to what I already typed would be much handier than getting `^[[D` and `^[[C` characters in the terminal and having to delete all chars to type everything again.

I could not add any extra tests to this as the STDIN can't be used during tests. But they are not breaking and I tried again all types of questions (text, choices, hidden) by myself.

Note that `readline` can't be used for hidden questions, as `stty -echo` is not taken into account.

Commits
-------

0534899 [Console] Fix Symfony coding standards violations
8b63d62 [Console] Use readline for user input when available
This commit is contained in:
Fabien Potencier 2015-08-01 13:59:20 +02:00
commit c856a010a2
2 changed files with 35 additions and 9 deletions

View File

@ -1,6 +1,12 @@
CHANGELOG
=========
2.8.0
-----
* use readline for user input in the question helper when available to allow
the use of arrow keys
2.6.0
-----

View File

@ -77,7 +77,7 @@ class QuestionHelper extends Helper
}
/**
* Returns the helper's input stream
* Returns the helper's input stream.
*
* @return resource
*/
@ -127,11 +127,7 @@ class QuestionHelper extends Helper
}
if (false === $ret) {
$ret = fgets($inputStream, 4096);
if (false === $ret) {
throw new \RuntimeException('Aborted');
}
$ret = trim($ret);
$ret = $this->readFromInput($inputStream);
}
} else {
$ret = trim($this->autocomplete($output, $question, $inputStream));
@ -150,7 +146,7 @@ class QuestionHelper extends Helper
* Outputs the question prompt.
*
* @param OutputInterface $output
* @param Question $question
* @param Question $question
*/
protected function writePrompt(OutputInterface $output, Question $question)
{
@ -222,7 +218,7 @@ class QuestionHelper extends Helper
// Backspace Character
if ("\177" === $c) {
if (0 === $numMatches && 0 !== $i) {
$i--;
--$i;
// Move cursor backwards
$output->write("\033[1D");
}
@ -275,7 +271,7 @@ class QuestionHelper extends Helper
} else {
$output->write($c);
$ret .= $c;
$i++;
++$i;
$numMatches = 0;
$ofs = 0;
@ -423,6 +419,30 @@ class QuestionHelper extends Helper
return self::$shell;
}
/**
* Reads user input.
*
* @param resource $stream The input stream
*
* @return string User input
*
* @throws \RuntimeException
*/
private function readFromInput($stream)
{
if (STDIN === $stream && function_exists('readline')) {
$ret = readline();
} else {
$ret = fgets($stream, 4096);
if (false === $ret) {
throw new \RuntimeException('Aborted');
}
}
return trim($ret);
}
/**
* Returns whether Stty is available or not.
*