Clean up code, add comments

This commit is contained in:
Chris 2024-10-01 22:51:58 +02:00
parent 338449824f
commit 9ca53df0ec

View File

@ -25,6 +25,13 @@ class Editor
private ?string $shortfilename = "untitled.json"; private ?string $shortfilename = "untitled.json";
private bool $running = true;
/**
* Constructor
*
* @param Terminal $term
*/
public function __construct(private Terminal $term) public function __construct(private Terminal $term)
{ {
$this->document = new Tree(); $this->document = new Tree();
@ -40,6 +47,12 @@ class Editor
$this->list = new TreeList($this->document); $this->list = new TreeList($this->document);
} }
/**
* Read a file into the Tree and TreeList
*
* @param string $filename
* @return void
*/
public function loadFile(string $filename): void public function loadFile(string $filename): void
{ {
$this->filename = $filename; $this->filename = $filename;
@ -60,14 +73,23 @@ class Editor
$this->list->parseTree(); $this->list->parseTree();
} }
/**
* Load a document from array/object
*
* @param mixed $document
* @return void
*/
public function loadDocument(mixed $document): void public function loadDocument(mixed $document): void
{ {
$this->document->load($document); $this->document->load($document);
$this->list->parseTree(); $this->list->parseTree();
} }
private bool $running = true; /**
* Run the editor
*
* @return void
*/
public function run() public function run()
{ {
$this->list->parseTree(); $this->list->parseTree();
@ -95,45 +117,11 @@ class Editor
break; break;
case 'E': case 'E':
//$coll = $this->list->findNearestCollection($this->currentRow); $this->doEditKey();
$entry = $this->list->getEntryForIndex($this->currentRow);
$path = $this->list->getPathForIndex($this->currentRow);
$parentIndex = $this->list->getIndexForPath(dirname($path));
$parent = $this->list->getEntryForIndex($parentIndex);
if ($parent->node instanceof ObjectNode) {
$newVal = $this->ask("\e[0;33mnew key:\e[0m ", $entry->key);
if ($newVal !== null) {
$entry->key = $newVal;
$this->redrawEditor();
}
} else {
$this->term->setCursor(1, $h);
echo "\e[97;41mCan only edit keys on objects\e[K\e[0m";
}
break; break;
case 'e': case 'e':
//$coll = $this->list->findNearestCollection($this->currentRow); $this->doEditValue();
$node = $this->list->getNodeForIndex($this->currentRow);
if ($node instanceof ValueNode) {
$val = json_encode($node->value, JSON_UNESCAPED_SLASHES);
$newVal = $this->ask("\e[33;1mnew value:\e[0m ", $val);
if ($newVal !== null) {
$val = json_decode($newVal);
// If the string decodes to null, but isn't 'null', treat it as a string
if ($val === null && $newVal !== 'null') {
$val = $newVal;
}
$node->value = $val;
$this->redrawEditor();
} else {
$this->redrawInfoBar();
}
} else {
$this->term->setCursor(1, $h);
echo "\e[97;41mCan not edit array/object\e[K\e[0m";
}
break; break;
case '[': case '[':
@ -207,66 +195,11 @@ class Editor
break; break;
case "\x12": // ctrl-r case "\x12": // ctrl-r
$readFrom = $this->ask("\e[33mRead from:\e[0m ", ""); $this->doReadFile();
$this->term->setCursor(1, $h);
if (!file_exists($readFrom)) {
echo "\e[97;41mFile does not exist\e[K\e[0m";
break;
}
if (!is_readable($readFrom)) {
echo "\e[97;41mFile not readable\e[K\e[0m";
break;
}
$ext = strtolower(pathinfo($readFrom, PATHINFO_EXTENSION));
switch ($ext) {
case 'json':
$doc = json_decode(file_get_contents($readFrom));
break;
case 'yml':
case 'yaml':
$doc = Yaml::parseFile($readFrom);
break;
default:
echo "\e[97;41mUnable to read format: {$ext}\e[K\e[0m";
break(2);
}
$this->filename = $readFrom;
$this->shortfilename = basename($readFrom);
$this->document->load($doc);
$this->currentRow = 0;
$this->list->parseTree();
$this->redrawEditor();
$this->term->setCursor(1, $h);
echo "\e[97;42mLoaded {$readFrom}\e[K\e[0m";
break; break;
case "\x17": // ctrl-w case "\x17": // ctrl-w
$saveTo = $this->ask("\e[33mWrite to:\e[0m ", $this->filename); $this->doWriteFile();
$doc = $this->document->save();
$this->term->setCursor(1, $h);
$ext = strtolower(pathinfo($saveTo, PATHINFO_EXTENSION));
switch ($ext) {
case 'json':
file_put_contents($saveTo, json_encode($doc, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)."\n");
break;
case 'yml':
case 'yaml':
$doc = json_decode(json_encode($doc), true);
file_put_contents($saveTo, Yaml::dump($doc));
break;
default:
echo "\e[97;41mUnable to write format: {$ext}\e[K\e[0m";
}
echo "\e[97;42mWrote to {$saveTo}\e[K\e[0m";
break; break;
case null: case null:
@ -286,6 +219,150 @@ class Editor
} }
/**
* Handler for read file command (ctrl-R)
*
* @return void
*/
private function doReadFile(): void
{
[$w,$h] = $this->term->getSize();
$readFrom = $this->ask("\e[33mRead from:\e[0m ", "");
$this->term->setCursor(1, $h);
if (!file_exists($readFrom)) {
echo "\e[97;41mFile does not exist\e[K\e[0m";
break;
}
if (!is_readable($readFrom)) {
echo "\e[97;41mFile not readable\e[K\e[0m";
break;
}
$ext = strtolower(pathinfo($readFrom, PATHINFO_EXTENSION));
switch ($ext) {
case 'json':
$doc = json_decode(file_get_contents($readFrom));
break;
case 'yml':
case 'yaml':
$doc = Yaml::parseFile($readFrom);
break;
default:
echo "\e[97;41mUnable to read format: {$ext}\e[K\e[0m";
break(2);
}
$this->filename = $readFrom;
$this->shortfilename = basename($readFrom);
$this->document->load($doc);
$this->currentRow = 0;
$this->list->parseTree();
$this->redrawEditor();
$this->term->setCursor(1, $h);
echo "\e[97;42mLoaded {$readFrom}\e[K\e[0m";
}
/**
* Handler for the write file command (ctrl-W)
*
* @return void
*/
private function doWriteFile(): void
{
[$w,$h] = $this->term->getSize();
$saveTo = $this->ask("\e[33mWrite to:\e[0m ", $this->filename);
$doc = $this->document->save();
$this->term->setCursor(1, $h);
$ext = strtolower(pathinfo($saveTo, PATHINFO_EXTENSION));
switch ($ext) {
case 'json':
file_put_contents($saveTo, json_encode($doc, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)."\n");
break;
case 'yml':
case 'yaml':
$doc = json_decode(json_encode($doc), true);
file_put_contents($saveTo, Yaml::dump($doc));
break;
default:
echo "\e[97;41mUnable to write format: {$ext}\e[K\e[0m";
}
echo "\e[97;42mWrote to {$saveTo}\e[K\e[0m";
}
/**
* Edit selected key
*
* @return void
*/
private function doEditKey(): void
{
[$w,$h] = $this->term->getSize();
//$coll = $this->list->findNearestCollection($this->currentRow);
$entry = $this->list->getEntryForIndex($this->currentRow);
$path = $this->list->getPathForIndex($this->currentRow);
$parentIndex = $this->list->getIndexForPath(dirname($path));
$parent = $this->list->getEntryForIndex($parentIndex);
if ($parent->node instanceof ObjectNode) {
$newVal = $this->ask("\e[0;33mnew key:\e[0m ", $entry->key);
if ($newVal !== null) {
$entry->key = $newVal;
$this->redrawEditor();
}
} else {
$this->term->setCursor(1, $h);
echo "\e[97;41mCan only edit keys on objects\e[K\e[0m";
}
}
/**
* Edit selected value
*
* @return void
*/
private function doEditValue(): void
{
[$w,$h] = $this->term->getSize();
//$coll = $this->list->findNearestCollection($this->currentRow);
$node = $this->list->getNodeForIndex($this->currentRow);
if ($node instanceof ValueNode) {
$val = json_encode($node->value, JSON_UNESCAPED_SLASHES);
$newVal = $this->ask("\e[33;1mnew value:\e[0m ", $val);
if ($newVal !== null) {
$val = json_decode($newVal);
// If the string decodes to null, but isn't 'null', treat it as a string
if ($val === null && $newVal !== 'null') {
$val = $newVal;
}
$node->value = $val;
$this->redrawEditor();
} else {
$this->redrawInfoBar();
}
} else {
$this->term->setCursor(1, $h);
echo "\e[97;41mCan not edit array/object\e[K\e[0m";
}
}
/**
* Insert a new value
*
* @param mixed $value
* @return void
*/
private function doInsertValue(mixed $value = null): void private function doInsertValue(mixed $value = null): void
{ {
$coll = $this->list->findNearestCollection($this->currentRow); $coll = $this->list->findNearestCollection($this->currentRow);
@ -325,6 +402,13 @@ class Editor
} }
} }
/**
* Ask for input
*
* @param string $prompt
* @param string $value
* @return string|null
*/
public function ask(string $prompt, $value = ''): ?string public function ask(string $prompt, $value = ''): ?string
{ {
$plainPrompt = preg_replace('<\e\[.+?m>', '', $prompt); $plainPrompt = preg_replace('<\e\[.+?m>', '', $prompt);
@ -378,6 +462,11 @@ class Editor
} }
/**
* Redraw the editor
*
* @return void
*/
public function redrawEditor() public function redrawEditor()
{ {
[$w,$h] = $this->term->getSize(); [$w,$h] = $this->term->getSize();
@ -414,6 +503,11 @@ class Editor
// echo "\e[90;3m«Empty»\e[0m"; // echo "\e[90;3m«Empty»\e[0m";
} }
/**
* Redraw the info bar
*
* @return void
*/
private function redrawInfoBar() private function redrawInfoBar()
{ {
[$w,$h] = $this->term->getSize(); [$w,$h] = $this->term->getSize();