Skip to content

Commit e3ec4c0

Browse files
committed
Optionally use ext-readline to enable raw input mode if available
1 parent f574375 commit e3ec4c0

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,13 @@ If this extension is missing, then this library will use a slighty slower Regex
567567
work-around that should otherwise work equally well.
568568
Installing `ext-mbstring` is highly recommended.
569569

570+
Internally, it will use the `ext-readline` to enable raw terminal input mode.
571+
If this extension is missing, then this library will manually set the required
572+
TTY settings on start and will try to restore previous settings on exit.
573+
Input line editing is handled entirely within this library and does not rely on
574+
`ext-readline`.
575+
Installing `ext-readline` is entirely optional.
576+
570577
Note that *Microsoft Windows is not supported*.
571578
Due to platform inconsistencies, PHP does not provide support for reading from
572579
standard console input without blocking.

src/Stdin.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ class Stdin extends Stream
1010
{
1111
private $oldMode = null;
1212

13+
/**
14+
* @param LoopInterface $loop
15+
* @codeCoverageIgnore this is covered by functional tests with/without ext-readline
16+
*/
1317
public function __construct(LoopInterface $loop)
1418
{
1519
// STDIN not defined ("php -a") or already closed (`fclose(STDIN)`)
@@ -26,6 +30,14 @@ public function __construct(LoopInterface $loop)
2630
return $this->close();
2731
}
2832

33+
if (function_exists('readline_callback_handler_install')) {
34+
// Prefer `ext-readline` to install dummy handler to turn on raw input mode.
35+
// We will nevery actually feed the readline handler and instead
36+
// handle all input in our `Readline` implementation.
37+
readline_callback_handler_install('', function () { });
38+
return;
39+
}
40+
2941
if ($this->isTty()) {
3042
$this->oldMode = shell_exec('stty -g');
3143

@@ -49,9 +61,15 @@ public function __destruct()
4961
$this->restore();
5062
}
5163

64+
/**
65+
* @codeCoverageIgnore this is covered by functional tests with/without ext-readline
66+
*/
5267
private function restore()
5368
{
54-
if ($this->oldMode !== null && $this->isTty()) {
69+
if (function_exists('readline_callback_handler_remove')) {
70+
// remove dummy readline handler to turn to default input mode
71+
readline_callback_handler_remove();
72+
} elseif ($this->oldMode !== null && $this->isTty()) {
5573
// Reset stty so it behaves normally again
5674
shell_exec(sprintf('stty %s', $this->oldMode));
5775
$this->oldMode = null;

0 commit comments

Comments
 (0)