Theming improvements, theme save/load, cursor funcs
This commit is contained in:
@@ -17,26 +17,84 @@ class Style
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromThemeString(string $style): Style
|
||||
{
|
||||
$defs = explode(",", $style);
|
||||
$tri = function(string $t, string $f) use ($defs) {
|
||||
if (in_array($t, $defs)) return true;
|
||||
if (in_array($f, $defs)) return false;
|
||||
return null;
|
||||
};
|
||||
|
||||
$fg = null;
|
||||
$bg = null;
|
||||
foreach ($defs as $def) {
|
||||
if ($def[0] === 'F') {
|
||||
$fg = intval(substr($def, 1));
|
||||
}
|
||||
if ($def[0] === 'B') {
|
||||
$bg = intval(substr($def, 1));
|
||||
}
|
||||
}
|
||||
|
||||
return new Style(
|
||||
fg: $fg,
|
||||
bg: $bg,
|
||||
bold: $tri('b', '-b'),
|
||||
dim: $tri('d', '-d'),
|
||||
italic: $tri('i', '-i'),
|
||||
underline: $tri('u', '-u'),
|
||||
reverse: $tri('r', '-r'),
|
||||
reset: in_array('R', $defs),
|
||||
);
|
||||
}
|
||||
|
||||
public function toThemeString(): string
|
||||
{
|
||||
$def = [];
|
||||
|
||||
if ($this->reset === true) $def[] = "R";
|
||||
if ($this->bold === true) $def[] = "b";
|
||||
if ($this->bold === false) $def[] = "-b";
|
||||
if ($this->dim === true) $def[] = "d";
|
||||
if ($this->dim === false) $def[] = "-d";
|
||||
if ($this->italic === true) $def[] = "i";
|
||||
if ($this->italic === false) $def[] = "-i";
|
||||
if ($this->underline === true) $def[] = "u";
|
||||
if ($this->underline === false) $def[] = "-u";
|
||||
if ($this->reverse === true) $def[] = "r";
|
||||
if ($this->reverse === false) $def[] = "-r";
|
||||
if ($this->fg !== null) $def[] = "F{$this->fg}";
|
||||
if ($this->bg !== null) $def[] = "B{$this->bg}";
|
||||
|
||||
return join(",", $def);
|
||||
}
|
||||
|
||||
public function __invoke(string $content): string
|
||||
{
|
||||
return $this->toSgr() . $content;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toSgr();
|
||||
}
|
||||
|
||||
public function toSgr(): string
|
||||
{
|
||||
$sgr = [];
|
||||
|
||||
if ($this->reset == true) $sgr[] = "0";
|
||||
if ($this->bold == true) $sgr[] = "1";
|
||||
if ($this->bold == false) $sgr[] = "22";
|
||||
if ($this->dim == true) $sgr[] = "2";
|
||||
if ($this->dim == false) $sgr[] = "22";
|
||||
if ($this->italic == true) $sgr[] = "3";
|
||||
if ($this->italic == false) $sgr[] = "23";
|
||||
if ($this->underline == true) $sgr[] = "4";
|
||||
if ($this->underline == false) $sgr[] = "24";
|
||||
if ($this->reverse == true) $sgr[] = "7";
|
||||
if ($this->reverse == false) $sgr[] = "27";
|
||||
if ($this->reset === true) $sgr[] = "0";
|
||||
if ($this->bold === true) $sgr[] = "1";
|
||||
if ($this->bold === false) $sgr[] = "22";
|
||||
if ($this->dim === true) $sgr[] = "2";
|
||||
if ($this->dim === false) $sgr[] = "22";
|
||||
if ($this->italic === true) $sgr[] = "3";
|
||||
if ($this->italic === false) $sgr[] = "23";
|
||||
if ($this->underline === true) $sgr[] = "4";
|
||||
if ($this->underline === false) $sgr[] = "24";
|
||||
if ($this->reverse === true) $sgr[] = "7";
|
||||
if ($this->reverse === false) $sgr[] = "27";
|
||||
|
||||
if ($this->fg !== null) {
|
||||
if ($this->fg > 7) {
|
||||
|
||||
@@ -177,6 +177,20 @@ class Terminal implements EventEmitterInterface
|
||||
echo "\e[?25" . ($visible?"h":"l");
|
||||
}
|
||||
|
||||
public function showCursorAt(int $line, int $column): void
|
||||
{
|
||||
$this->setCursorPosition($line, $column);
|
||||
$this->setCursorVisible(true);
|
||||
}
|
||||
|
||||
public function setCursorPosition(int $line, int $column): void
|
||||
{
|
||||
$l = $line+1;
|
||||
$c = $column+1;
|
||||
$data = "\e[{$l};{$c}H";
|
||||
$this->write($data);
|
||||
}
|
||||
|
||||
public function writeAt(int $line, int $column, string $data, ?Style $style = null): void
|
||||
{
|
||||
$l = $line+1;
|
||||
|
||||
@@ -10,6 +10,26 @@ class Theme implements ArrayAccess
|
||||
|
||||
private array $styles = [];
|
||||
|
||||
public function saveFile(string $filename): void
|
||||
{
|
||||
$theme = [];
|
||||
foreach ($this->defaults as $name => $style) {
|
||||
if (isset($this->styles[$name]))
|
||||
$style = $this->styles[$name];
|
||||
$theme[] = sprintf("%s: %s", $name, $style->toThemeString());
|
||||
}
|
||||
file_put_contents($filename, join("\n", $theme));
|
||||
}
|
||||
|
||||
public function loadFile(string $filename, bool $throw = true): void
|
||||
{
|
||||
$defs = file($filename, FILE_IGNORE_NEW_LINES);
|
||||
foreach ($defs as $def) {
|
||||
[$name,$style] = explode(": ", $def);
|
||||
$this->set($name, Style::fromThemeString($style));
|
||||
}
|
||||
}
|
||||
|
||||
public function define(string $element, Style $defaultStyle): void
|
||||
{
|
||||
$this->defaults[$element] = $defaultStyle;
|
||||
|
||||
Reference in New Issue
Block a user