Skip to content

Commit

Permalink
Implement ConsoleIo::overwrite().
Browse files Browse the repository at this point in the history
  • Loading branch information
markstory committed Apr 10, 2014
1 parent fa1f4f4 commit 192bef8
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
45 changes: 43 additions & 2 deletions src/Console/ConsoleIo.php
Expand Up @@ -75,6 +75,14 @@ class ConsoleIo {
*/
protected $_level = ConsoleIo::NORMAL;

/**
* The number of bytes last written to the output stream
* used when overwriting the previous message.
*
* @var integer
*/
protected $_lastWritten = 0;

/**
* Constructor
*
Expand Down Expand Up @@ -140,13 +148,46 @@ public function quiet($message, $newlines = 1) {
* @return integer|boolean Returns the number of bytes returned from writing to stdout.
* @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::out
*/
public function out($message = null, $newlines = 1, $level = Shell::NORMAL) {
public function out($message = null, $newlines = 1, $level = ConsoleIo::NORMAL) {
if ($level <= $this->_level) {
return $this->_out->write($message, $newlines);
$this->_lastWritten = $this->_out->write($message, $newlines);
return $this->_lastWritten;
}
return true;
}

/**
* Overwrite some already output text.
*
* Useful for building progress bars, or when you want to replace
* text already output to the screen with new text.
*
* **Warning** You cannot overwrite text that contains newlines.
*
* @param array|string $message The message to output.
* @param integer $newlines Number of newlines to append.
* @param integer $size The number of bytes to overwrite. Defaults to the
* length of the last message output.
* @return integer|boolean Returns the number of bytes returned from writing to stdout.
*/
public function overwrite($message, $newlines = 1, $size = null) {
$size = $size ?: $this->_lastWritten;

// Output backspaces.
$this->out(str_repeat("\x08", $size), 0);

$newBytes = $this->out($message, 0);

// Fill any remaining bytes with spaces.
$fill = $size - $newBytes;
if ($fill > 0) {
$this->out(str_repeat(' ', $fill), 0);
}
if ($newlines) {
$this->out($this->nl($newlines), 0);
}
}

/**
* Outputs a single or multiple error messages to stderr. If no parameters
* are passed outputs just a newline.
Expand Down
30 changes: 30 additions & 0 deletions tests/TestCase/Console/ConsoleIoTest.php
Expand Up @@ -280,4 +280,34 @@ public function testHr() {
$this->io->hr(2);
}

/**
* Test overwriting.
*
* @return void
*/
public function testOverwrite() {
$number = strlen('Some text I want to overwrite');

$this->out->expects($this->at(0))
->method('write')
->with('Some <info>text</info> I want to overwrite', 0)
->will($this->returnValue($number));

$this->out->expects($this->at(1))
->method('write')
->with(str_repeat("\x08", $number), 0);

$this->out->expects($this->at(2))
->method('write')
->with('Less text', 0)
->will($this->returnValue(9));

$this->out->expects($this->at(3))
->method('write')
->with(str_repeat(' ', $number - 9), 0);

$this->io->out('Some <info>text</info> I want to overwrite', 0);
$this->io->overwrite('Less text');
}

}

0 comments on commit 192bef8

Please sign in to comment.