Skip to content

Commit

Permalink
1. add ansi escape code lib
Browse files Browse the repository at this point in the history
  • Loading branch information
scarwu committed Dec 12, 2018
1 parent 55e8c13 commit 7f5de49
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 123 deletions.
167 changes: 44 additions & 123 deletions src/Oni/CLI/IO.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Oni\CLI;

use Oni\Basic;
use Oni\CLI\IO\ANSIEscapeCode as AEC;

class IO extends Basic
{
Expand All @@ -34,61 +35,6 @@ class IO extends Basic
*/
private $_configs = [];

// ANSI Escape Code
const ESC = "\x1b";
const CSI = self::ESC . '[';
const OSC = self::ESC . ']';

// Control Charater
const BEL = "\x07";
const SEP = ';';

/**
* @var array
*/
private static $fgColorMapping = [
'black' => '30',
'red' => '31',
'green' => '32',
'yellow' => '33',
'blue' => '34',
'magenta' => '35',
'cyan' => '36',
'white' => '37',
'default' => '39',
'brightBlack' => '90',
'brightRed' => '91',
'brightGreen' => '92',
'brightYellow' => '93',
'brightBlue' => '94',
'brightMagenta' => '95',
'brightCyan' => '96',
'brightWhite' => '97'
];

/**
* @var array
*/
private static $bgColorMapping = [
'black' => '40',
'red' => '41',
'green' => '42',
'yellow' => '43',
'blue' => '44',
'magenta' => '45',
'cyan' => '46',
'white' => '47',
'default' => '49',
'brightBlack' => '100',
'brightRed' => '101',
'brightGreen' => '102',
'brightYellow' => '103',
'brightBlue' => '104',
'brightMagenta' => '105',
'brightCyan' => '106',
'brightWhite' => '107'
];

/**
* Construct
*
Expand Down Expand Up @@ -294,59 +240,56 @@ public function ask($text, $callback = null, $fgColor = null, $bgColor = null)
* @param integer $selectedIndex
*/
private function menuRender($options, $selectedIndex) {
foreach ($options as $currentIndex => $option) {
if ($selectedIndex === $currentIndex) {
$this->writeln("> {$option}");
} else {
$this->writeln(" {$option}");
}
}
$this->write(implode("\n", array_map(function ($option, $currentIndex) use ($selectedIndex) {
return ($selectedIndex === $currentIndex)
? "> {$option}" : " {$option}";
}, $options, array_keys($options))));
}

/**
* Menu Input
*
* @param array $options
*/
public function menuInput($options) {
$totalIndex = count($options);
$selectedIndex = 0;
$isBreakLoop = false;
$char = null;
// public function menuInput($options) {
// $totalIndex = count($options);
// $selectedIndex = 0;
// $isBreakLoop = false;
// $char = null;

readline_callback_handler_install('', function() {});
// readline_callback_handler_install('', function() {});

do {
switch (ord($char)) {
case 10: // Enter Key
$isBreakLoop = true;
// do {
// switch (ord($char)) {
// case 10: // Enter Key
// $isBreakLoop = true;

break;
case 65: // Up Key
if ($selectedIndex - 1 >= 0) {
$selectedIndex--;
}
// break;
// case 65: // Up Key
// if ($selectedIndex - 1 >= 0) {
// $selectedIndex--;
// }

break;
case 66: // Down Key
if ($selectedIndex + 1 < $totalIndex) {
$selectedIndex++;
}
// break;
// case 66: // Down Key
// if ($selectedIndex + 1 < $totalIndex) {
// $selectedIndex++;
// }

break;
}
// break;
// }

if ($isBreakLoop) {
break;
}
// if ($isBreakLoop) {
// break;
// }

$this->menuRender($options, $selectedIndex);
} while ($char = stream_get_contents(STDIN, 1));
// $this->menuRender($options, $selectedIndex);
// } while ($char = stream_get_contents(STDIN, 1));

readline_callback_handler_remove();
// readline_callback_handler_remove();

return $selectedIndex;
}
// return $selectedIndex;
// }

/**
* Menu Select
Expand All @@ -359,6 +302,10 @@ public function menuSelect($options) {
$isBreakLoop = false;
$char = null;

$wWidth = (int) exec('tput cols');
$wHeight = (int) exec('tput lines');
$bHeight = count($options);

readline_callback_handler_install('', function() {});

do {
Expand Down Expand Up @@ -386,43 +333,17 @@ public function menuSelect($options) {
}

$this->menuRender($options, $selectedIndex);

$this->write(AEC::moveTo(0, $wHeight - $bHeight));
} while ($char = stream_get_contents(STDIN, 1));

$this->writeln(AEC::moveTo(0, $wHeight));

readline_callback_handler_remove();

return $selectedIndex;
}

/**
* Color
*
* @param string $text
* @param string $fgColor
* @param string $bgColor
*
* @return string
*/
private function color($text, $fgColor = null, $bgColor = null)
{
$startCodes = [];
$stopCodes = [];

if (isset(self::$fgColorMapping[$fgColor])) {
$startCodes[] = self::$fgColorMapping[$fgColor];
$stopCodes[] = 39;
}

if (isset(self::$bgColorMapping[$bgColor])) {
$startCodes[] = self::$bgColorMapping[$bgColor];
$stopCodes[] = 49;
}

$start = self::CSI . implode(';', $startCodes) . 'm';
$end = self::CSI . implode(';', $stopCodes) . 'm';

return "{$start}{$text}{$end}";
}

/**
* Write data to STDOUT
*
Expand All @@ -433,7 +354,7 @@ private function color($text, $fgColor = null, $bgColor = null)
public function write($text, $fgColor = null, $bgColor = null)
{
if (null !== $fgColor || null !== $bgColor) {
$text = $this->color($text, $fgColor, $bgColor);
$text = AEC::color($text, $fgColor, $bgColor);
}

fwrite(STDOUT, $text);
Expand Down
148 changes: 148 additions & 0 deletions src/Oni/CLI/IO/ANSIEscapeCode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php
/**
* ANSI Escape Code
*
* @package Oni
* @author Scar Wu
* @copyright Copyright (c) Scar Wu (https://scar.tw)
* @link https://github.com/scarwu/Oni
*/

namespace Oni\CLI\IO;

final class ANSIEscapeCode
{
// ANSI Escape Code
const ESC = "\x1b";
const CSI = self::ESC . '[';
const OSC = self::ESC . ']';

// Control Charater
const BEL = "\x07";
const SEP = ';';

/**
* @var array
*/
private static $fgColorMapping = [
'black' => '30',
'red' => '31',
'green' => '32',
'yellow' => '33',
'blue' => '34',
'magenta' => '35',
'cyan' => '36',
'white' => '37',
'default' => '39',
'brightBlack' => '90',
'brightRed' => '91',
'brightGreen' => '92',
'brightYellow' => '93',
'brightBlue' => '94',
'brightMagenta' => '95',
'brightCyan' => '96',
'brightWhite' => '97'
];

/**
* @var array
*/
private static $bgColorMapping = [
'black' => '40',
'red' => '41',
'green' => '42',
'yellow' => '43',
'blue' => '44',
'magenta' => '45',
'cyan' => '46',
'white' => '47',
'default' => '49',
'brightBlack' => '100',
'brightRed' => '101',
'brightGreen' => '102',
'brightYellow' => '103',
'brightBlue' => '104',
'brightMagenta' => '105',
'brightCyan' => '106',
'brightWhite' => '107'
];

private function __construct() {}

/**
* Select Graphic Rendition
*
* @param string|array $param
*
* @return string
*/
public static function SGR($param) {
if (is_array($param)) {
$param = implode(SEP, $param);
}

return self::CSI . "{$param}m";
}

/**
* Cursor Position
*
* @param string $x
* @param string $y
*
* @return string
*/
public static function CUP($x, $y) {
return self::CSI . ($y + 1) . SEP . ($x + 1) . 'H';
}

/**
* Move To
*
* @param string $x
* @param string $y
*
* @return string
*/
public static function moveTo($x, $y) {
return self::CUP($x, $y);
}

/**
* Reset
*
* @return string
*/
public static function reset() {
return self::SGR(0);
}

/**
* Front Ground Color
*
* @param string $text
* @param string $fgColor
*
* @return string
*/
public static function color($text, $fgColor = null, $bgColor = null)
{
$startCodes = [];
$stopCodes = [];

if (isset(self::$fgColorMapping[$fgColor])) {
$startCodes[] = self::$fgColorMapping[$fgColor];
$stopCodes[] = 39;
}

if (isset(self::$bgColorMapping[$bgColor])) {
$startCodes[] = self::$bgColorMapping[$bgColor];
$stopCodes[] = 49;
}

$start = self::SGR($startCodes);
$end = self::SGR($stopCodes);

return "{$start}{$text}{$end}";
}
}

0 comments on commit 7f5de49

Please sign in to comment.