From 419f09c2ba62befb0e70b72dd74d035b25090655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 1 Nov 2017 19:14:06 +0100 Subject: [PATCH 1/2] Consistently return boolean success from write() --- src/Readline.php | 11 +++++++++-- src/Stdio.php | 10 +++++----- tests/StdioTest.php | 4 ++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Readline.php b/src/Readline.php index 0317cae..42376ff 100644 --- a/src/Readline.php +++ b/src/Readline.php @@ -426,6 +426,14 @@ public function setAutocomplete($autocomplete) * @internal */ public function redraw() + { + $this->output->write($this->__toString()); + + return $this; + } + + /** @internal */ + public function __toString() { // Erase characters from cursor to end of line $output = "\r\033[K" . $this->prompt; @@ -439,9 +447,8 @@ public function redraw() // write output, then move back $reverse chars (by sending backspace) $output .= $buffer . str_repeat("\x08", $this->strwidth($buffer) - $this->getCursorCell()); } - $this->output->write($output); - return $this; + return $output; } /** diff --git a/src/Stdio.php b/src/Stdio.php index 5cd8acb..37f5237 100644 --- a/src/Stdio.php +++ b/src/Stdio.php @@ -91,8 +91,9 @@ public function pipe(WritableStreamInterface $dest, array $options = array()) public function write($data) { - if ($this->ending || (string)$data === '') { - return; + // return false if already ended, return true if writing empty string + if ($this->ending || $data === '') { + return !$this->ending; } $out = $data; @@ -147,8 +148,7 @@ public function write($data) if ($restoreReadline) { // write output and restore original readline prompt and line buffer - $this->output->write($out); - $this->readline->redraw(); + return $this->output->write($out . $this->readline->__toString()); } else { // restore original cursor position in readline prompt $pos = $this->width($this->readline->getPrompt()) + $this->readline->getCursorCell(); @@ -158,7 +158,7 @@ public function write($data) } // write to actual output stream - $this->output->write($out); + return $this->output->write($out); } } diff --git a/tests/StdioTest.php b/tests/StdioTest.php index e127dda..defd0c4 100644 --- a/tests/StdioTest.php +++ b/tests/StdioTest.php @@ -50,7 +50,7 @@ public function testWriteEmptyStringWillNotWriteToOutput() $output->expects($this->never())->method('write'); - $stdio->write(''); + $this->assertTrue($stdio->write('')); } public function testWriteWillClearReadlineWriteOutputAndRestoreReadline() @@ -423,7 +423,7 @@ public function testWriteAfterEndWillNotWriteToOutput() $output->expects($this->never())->method('write'); - $stdio->write('test'); + $this->assertFalse($stdio->write('test')); } public function testEndTwiceWillCloseInputAndEndOutputOnce() From d73bf706745040c44d069bcb0c6fe1a310beb1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 3 Nov 2017 23:55:42 +0000 Subject: [PATCH 2/2] Avoid unneeded control codes to overwrite input prompt --- src/Readline.php | 15 ++++++++++----- src/Stdio.php | 2 +- tests/StdioTest.php | 14 +++++++------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Readline.php b/src/Readline.php index 42376ff..c92142c 100644 --- a/src/Readline.php +++ b/src/Readline.php @@ -427,16 +427,21 @@ public function setAutocomplete($autocomplete) */ public function redraw() { - $this->output->write($this->__toString()); + // Erase characters from cursor to end of line and then redraw actual input + $this->output->write("\r\033[K" . $this->getDrawString()); return $this; } - /** @internal */ - public function __toString() + /** + * Returns the string that is used to draw the input prompt + * + * @return string + * @internal + */ + public function getDrawString() { - // Erase characters from cursor to end of line - $output = "\r\033[K" . $this->prompt; + $output = $this->prompt; if ($this->echo !== false) { if ($this->echo === true) { $buffer = $this->linebuffer; diff --git a/src/Stdio.php b/src/Stdio.php index 37f5237..c01e840 100644 --- a/src/Stdio.php +++ b/src/Stdio.php @@ -148,7 +148,7 @@ public function write($data) if ($restoreReadline) { // write output and restore original readline prompt and line buffer - return $this->output->write($out . $this->readline->__toString()); + return $this->output->write($out . $this->readline->getDrawString()); } else { // restore original cursor position in readline prompt $pos = $this->width($this->readline->getPrompt()) + $this->readline->getCursorCell(); diff --git a/tests/StdioTest.php b/tests/StdioTest.php index defd0c4..d6f2baa 100644 --- a/tests/StdioTest.php +++ b/tests/StdioTest.php @@ -72,7 +72,7 @@ public function testWriteWillClearReadlineWriteOutputAndRestoreReadline() $stdio->write('test'); - $this->assertEquals("\r\033[K" . "test\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "test\n" . "> input", $buffer); } public function testWriteAgainWillMoveToPreviousLineWriteOutputAndRestoreReadlinePosition() @@ -144,7 +144,7 @@ public function testWriteAgainWithNewlinesWillClearReadlineMoveToPreviousLineWri $stdio->write("ond" . "\n" . "third"); - $this->assertEquals("\r\033[K" . "\033[A" . "\r\033[3C" . "ond\nthird\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "\033[A" . "\r\033[3C" . "ond\nthird\n" . "> input", $buffer); } public function testWriteAfterReadlineInputWillClearReadlineWriteOutputAndRestoreReadline() @@ -170,7 +170,7 @@ public function testWriteAfterReadlineInputWillClearReadlineWriteOutputAndRestor $stdio->writeln('test'); - $this->assertEquals("\r\033[K" . "test\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "test\n" . "> input", $buffer); } public function testOverwriteWillClearReadlineMoveToPreviousLineWriteOutputAndRestoreReadline() @@ -194,7 +194,7 @@ public function testOverwriteWillClearReadlineMoveToPreviousLineWriteOutputAndRe $stdio->overwrite('overwrite'); - $this->assertEquals("\r\033[K" . "\033[A" . "\r\033[K" . "overwrite\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "\033[A" . "\r\033[K" . "overwrite\n" . "> input", $buffer); } public function testOverwriteAfterNewlineWillClearReadlineAndWriteOutputAndRestoreReadline() @@ -218,7 +218,7 @@ public function testOverwriteAfterNewlineWillClearReadlineAndWriteOutputAndResto $stdio->overwrite('overwrite'); - $this->assertEquals("\r\033[K" . "overwrite\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "overwrite\n" . "> input", $buffer); } public function testWriteLineWillClearReadlineWriteOutputAndRestoreReadline() @@ -240,7 +240,7 @@ public function testWriteLineWillClearReadlineWriteOutputAndRestoreReadline() $stdio->writeln('test'); - $this->assertEquals("\r\033[K" . "test\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "test\n" . "> input", $buffer); } public function testWriteTwoLinesWillClearReadlineWriteOutputAndRestoreReadline() @@ -263,7 +263,7 @@ public function testWriteTwoLinesWillClearReadlineWriteOutputAndRestoreReadline( $stdio->writeln('hello'); $stdio->writeln('world'); - $this->assertEquals("\r\033[K" . "hello\n" . "\r\033[K" . "> input" . "\r\033[K" . "world\n" . "\r\033[K" . "> input", $buffer); + $this->assertEquals("\r\033[K" . "hello\n" . "> input" . "\r\033[K" . "world\n" . "> input", $buffer); } public function testPauseWillBeForwardedToInput()