Skip to content

Commit 2e11cb9

Browse files
authored
Merge pull request #56 from clue-labs/ctrl-d
Explicitly end stream on CTRL+D and emit final data on EOF without EOL
2 parents 0cf3696 + 339f7c6 commit 2e11cb9

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

examples/01-periodic.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@
1616
});
1717

1818
// react to commands the user entered
19-
$stdio->on('line', function ($line) use ($stdio, $timer) {
20-
$stdio->writeln('you just said: ' . $line . ' (' . strlen($line) . ')');
19+
$stdio->on('data', function ($line) use ($stdio, $loop, $timer) {
20+
$stdio->writeln('you just said: ' . addcslashes($line, "\0..\37") . ' (' . strlen($line) . ')');
2121

22-
$timer->cancel();
22+
$loop->cancelTimer($timer);
23+
$stdio->end();
24+
});
25+
26+
// cancel periodic timer if STDIN closed
27+
$stdio->on('end', function () use ($stdio, $loop, $timer) {
28+
$loop->cancelTimer($timer);
2329
$stdio->end();
2430
});
2531

src/Readline.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public function __construct(ReadableStreamInterface $input, WritableStreamInterf
4848
"\x7f" => 'onKeyBackspace',
4949
"\t" => 'onKeyTab',
5050

51+
"\x04" => 'handleEnd', // CTRL+D
52+
5153
"\033[A" => 'onKeyUp',
5254
"\033[B" => 'onKeyDown',
5355
"\033[C" => 'onKeyRight',
@@ -803,6 +805,10 @@ public function strwidth($str)
803805
/** @internal */
804806
public function handleEnd()
805807
{
808+
if ($this->linebuffer !== '') {
809+
$this->processLine();
810+
}
811+
806812
if (!$this->closed) {
807813
$this->emit('end');
808814
$this->close();

src/Stdio.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public function handleError(\Exception $e)
241241
/** @internal */
242242
public function handleEnd()
243243
{
244-
$this->emit('end', array());
244+
$this->emit('end');
245245
}
246246

247247
/** @internal */

tests/ReadlineTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,24 @@ public function testDataEventWillBeEmittedForEmptyLine()
223223
$this->input->emit('data', array("\n"));
224224
}
225225

226+
public function testEndInputWithoutDataOnCtrlD()
227+
{
228+
$this->readline->on('data', $this->expectCallableNever());
229+
$this->readline->on('end', $this->expectCallableOnce());
230+
$this->readline->on('close', $this->expectCallableOnce());
231+
232+
$this->input->emit('data', array("\x04"));
233+
}
234+
235+
public function testEndInputWithIncompleteLineOnCtrlD()
236+
{
237+
$this->readline->on('data', $this->expectCallableOnceWith('hello'));
238+
$this->readline->on('end', $this->expectCallableOnce());
239+
$this->readline->on('close', $this->expectCallableOnce());
240+
241+
$this->input->emit('data', array("hello\x04"));
242+
}
243+
226244
public function testWriteSimpleCharWritesOnce()
227245
{
228246
$this->output->expects($this->once())->method('write')->with($this->equalTo("\r\033[K" . "k"));
@@ -963,9 +981,22 @@ public function testEmitErrorWillEmitErrorAndClose()
963981

964982
public function testEmitEndWillEmitEndAndClose()
965983
{
984+
$this->readline->on('data', $this->expectCallableNever());
985+
$this->readline->on('end', $this->expectCallableOnce());
986+
$this->readline->on('close', $this->expectCallableOnce());
987+
988+
$this->input->emit('end');
989+
990+
$this->assertFalse($this->readline->isReadable());
991+
}
992+
993+
public function testEmitEndAfterDataWillEmitDataAndEndAndClose()
994+
{
995+
$this->readline->on('data', $this->expectCallableOnce('hello'));
966996
$this->readline->on('end', $this->expectCallableOnce());
967997
$this->readline->on('close', $this->expectCallableOnce());
968998

999+
$this->input->emit('data', array('hello'));
9691000
$this->input->emit('end');
9701001

9711002
$this->assertFalse($this->readline->isReadable());

0 commit comments

Comments
 (0)