php-kilo/src/Terminal.php

122 lines
2.1 KiB
PHP

<?php declare(strict_types=1);
namespace Aviat\Kilo;
use Aviat\Kilo\Type\TerminalSize;
class Terminal {
/**
* Get the size of the current terminal window
*
* @codeCoverageIgnore
* @return TerminalSize
*/
public static function size(): TerminalSize
{
return new TerminalSize(...self::getWindowSize());
}
/**
* 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];
}
/**
* Clear the screen and reset the cursor position
*/
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 ');
}
}