2021-03-05 12:06:23 -05:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Aviat\Kilo;
|
|
|
|
|
2021-03-11 16:56:02 -05:00
|
|
|
use Aviat\Kilo\Type\TerminalSize;
|
|
|
|
|
2021-03-05 12:06:23 -05:00
|
|
|
class Terminal {
|
2021-03-11 16:56:02 -05:00
|
|
|
/**
|
|
|
|
* Get the size of the current terminal window
|
|
|
|
*
|
|
|
|
* @codeCoverageIgnore
|
|
|
|
* @return TerminalSize
|
|
|
|
*/
|
|
|
|
public static function size(): TerminalSize
|
|
|
|
{
|
|
|
|
return new TerminalSize(...self::getWindowSize());
|
|
|
|
}
|
|
|
|
|
2021-03-05 12:06:23 -05:00
|
|
|
/**
|
|
|
|
* Get the size of the current terminal window
|
|
|
|
*
|
|
|
|
* @codeCoverageIgnore
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public static function getWindowSize(): array
|
|
|
|
{
|
|
|
|
$ffiSize = Termios::getWindowSize();
|
|
|
|
if ($ffiSize !== NULL)
|
|
|
|
{
|
|
|
|
return $ffiSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try using tput
|
|
|
|
if (self::has_tput())
|
|
|
|
{
|
|
|
|
$rows = (int)trim((string)shell_exec('tput lines'));
|
|
|
|
$cols = (int)trim((string)shell_exec('tput cols'));
|
|
|
|
|
|
|
|
if ($rows > 0 && $cols > 0)
|
|
|
|
{
|
|
|
|
return [$rows, $cols];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Worst-case, return an arbitrary 'standard' size
|
|
|
|
return [25, 80];
|
|
|
|
}
|
|
|
|
|
2021-03-05 20:47:59 -05:00
|
|
|
/**
|
|
|
|
* Clear the screen and reset the cursor position
|
|
|
|
*/
|
2021-03-05 12:06:23 -05:00
|
|
|
public static function clear(): void
|
|
|
|
{
|
|
|
|
self::write(ANSI::CLEAR_SCREEN . ANSI::RESET_CURSOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pull input from the stdin stream.
|
|
|
|
*
|
|
|
|
* @codeCoverageIgnore
|
|
|
|
* @param int $len
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function read(int $len = 128): string
|
|
|
|
{
|
|
|
|
$handle = fopen('php://stdin', 'rb');
|
|
|
|
if ($handle === false)
|
|
|
|
{
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
$input = fread($handle, $len);
|
|
|
|
fclose($handle);
|
|
|
|
|
|
|
|
return (is_string($input)) ? $input : '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write to the stdout stream
|
|
|
|
*
|
|
|
|
* @codeCoverageIgnore
|
|
|
|
* @param string $str
|
|
|
|
* @param int|NULL $len
|
|
|
|
* @return int|false
|
|
|
|
*/
|
|
|
|
public static function write(string $str, int $len = NULL): int|false
|
|
|
|
{
|
|
|
|
$handle = fopen('php://stdout', 'ab');
|
|
|
|
if ($handle === false)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$res = (is_int($len))
|
|
|
|
? fwrite($handle, $str, $len)
|
|
|
|
: fwrite($handle, $str);
|
|
|
|
|
|
|
|
fflush($handle);
|
|
|
|
|
|
|
|
fclose($handle);
|
|
|
|
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See if tput exists for fallback terminal size detection
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
* @codeCoverageIgnore
|
|
|
|
*/
|
|
|
|
private static function has_tput(): bool
|
|
|
|
{
|
|
|
|
$cmd = shell_exec('type tput');
|
|
|
|
if ( ! is_string($cmd))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return str_contains($cmd, ' is ');
|
|
|
|
}
|
|
|
|
}
|