Skip to content

Commit dfbc55f

Browse files
committed
Only redraw() when necessary
1 parent 6d4ff15 commit dfbc55f

File tree

2 files changed

+101
-7
lines changed

2 files changed

+101
-7
lines changed

src/Readline.php

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public function __construct($output)
6565
*/
6666
public function setPrompt($prompt)
6767
{
68+
if ($prompt === $this->prompt) {
69+
return $this;
70+
}
71+
6872
$this->prompt = $prompt;
6973

7074
return $this->redraw();
@@ -83,9 +87,18 @@ public function setPrompt($prompt)
8387
*/
8488
public function setEcho($echo)
8589
{
90+
if ($echo === $this->echo) {
91+
return $this;
92+
}
93+
8694
$this->echo = !!$echo;
8795

88-
return $this->redraw();
96+
// only redraw if there is any input
97+
if ($this->linebuffer !== '') {
98+
$this->redraw();
99+
}
100+
101+
return $this;
89102
}
90103

91104
/**
@@ -102,9 +115,7 @@ public function setMove($move)
102115
{
103116
$this->move = !!$move;
104117

105-
$this->linepos = $this->strlen($this->linebuffer);
106-
107-
return $this->redraw();
118+
return $this->moveCursorTo($this->strlen($this->linebuffer));
108119
}
109120

110121
/**
@@ -134,10 +145,19 @@ public function getCursorPosition()
134145
*/
135146
public function setInput($input)
136147
{
148+
if ($this->linebuffer === $input) {
149+
return $this;
150+
}
151+
137152
$this->linebuffer = $input;
138153
$this->linepos = $this->strlen($this->linebuffer);
139154

140-
return $this->redraw();
155+
// only redraw if input should be echo'ed (i.e. is not hidden anyway)
156+
if ($this->echo) {
157+
$this->redraw();
158+
}
159+
160+
return $this;
141161
}
142162

143163
/**
@@ -362,12 +382,17 @@ public function moveCursorBy($n)
362382
public function moveCursorTo($n)
363383
{
364384
if ($n < 0 || $n === $this->linepos || $n > $this->strlen($this->linebuffer)) {
365-
return;
385+
return $this;
366386
}
367387

368388
$this->linepos = $n;
369389

370-
return $this->redraw();
390+
// only redraw if cursor is actually visible
391+
if ($this->echo) {
392+
$this->redraw();
393+
}
394+
395+
return $this;
371396
}
372397

373398
/**

tests/ReadlineTest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,73 @@ public function testRedrawingReadlineWritesToOutputOnce()
5555
$this->output->expects($this->once())->method('write')->with($this->equalTo("\r\033[K" . "> " . "test" . "\x08\x08"));
5656
$this->assertSame($this->readline, $this->readline->redraw());
5757
}
58+
59+
public function testSettingSameSettingsDoesNotNeedToRedraw()
60+
{
61+
$this->readline->setPrompt('> ');
62+
$this->readline->setInput('test');
63+
$this->readline->moveCursorBy(-2);
64+
65+
$this->output->expects($this->never())->method('write');
66+
67+
$this->assertSame($this->readline, $this->readline->setPrompt('> '));
68+
$this->assertSame($this->readline, $this->readline->setInput('test'));
69+
$this->assertSame($this->readline, $this->readline->moveCursorTo(2));
70+
}
71+
72+
public function testSettingEchoOnWithInputDoesRedraw()
73+
{
74+
$this->readline->setEcho(false);
75+
$this->readline->setPrompt('> ');
76+
$this->readline->setInput('test');
77+
78+
$this->output->expects($this->once())->method('write')->with($this->equalTo("\r\033[K" . "> " . "test"));
79+
80+
$this->assertSame($this->readline, $this->readline->setEcho(true));
81+
}
82+
83+
public function testSettingEchoOffWithInputDoesRedraw()
84+
{
85+
$this->readline->setEcho(true);
86+
$this->readline->setPrompt('> ');
87+
$this->readline->setInput('test');
88+
89+
$this->output->expects($this->once())->method('write')->with($this->equalTo("\r\033[K" . "> "));
90+
91+
$this->assertSame($this->readline, $this->readline->setEcho(false));
92+
}
93+
94+
public function testSettingEchoWithoutInputDoesNotNeedToRedraw()
95+
{
96+
$this->output->expects($this->never())->method('write');
97+
98+
$this->assertSame($this->readline, $this->readline->setEcho(false));
99+
$this->assertSame($this->readline, $this->readline->setEcho(true));
100+
}
101+
102+
public function testSettingInputDoesRedraw()
103+
{
104+
$this->output->expects($this->once())->method('write');
105+
$this->assertSame($this->readline, $this->readline->setInput('test'));
106+
}
107+
108+
public function testSettingInputWithoutEchoDoesNotNeedToRedraw()
109+
{
110+
$this->readline->setEcho(false);
111+
112+
$this->output->expects($this->never())->method('write');
113+
114+
$this->assertSame($this->readline, $this->readline->setInput('test'));
115+
}
116+
117+
public function testMovingCursorWithoutEchoDoesNotNeedToRedraw()
118+
{
119+
$this->readline->setEcho(false);
120+
$this->readline->setInput('test');
121+
122+
$this->output->expects($this->never())->method('write');
123+
124+
$this->assertSame($this->readline, $this->readline->moveCursorTo(0));
125+
$this->assertSame($this->readline, $this->readline->moveCursorBy(2));
126+
}
58127
}

0 commit comments

Comments
 (0)