Clean up code, add comments
This commit is contained in:
parent
338449824f
commit
9ca53df0ec
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user