Add save to json/yaml (ctrl-w)
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +1,2 @@
 | 
				
			|||||||
/vendor/
 | 
					/vendor/
 | 
				
			||||||
 | 
					/*.phar
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "name": "noccylabs/jedit",
 | 
					    "name": "noccylabs/jedit",
 | 
				
			||||||
    "description": "JSON/YAML editor for the terminal",
 | 
					    "description": "JSON/YAML editor for terminal junkies",
 | 
				
			||||||
    "type": "application",
 | 
					    "type": "application",
 | 
				
			||||||
    "license": "GPL-3.0-or-later",
 | 
					    "license": "GPL-3.0-or-later",
 | 
				
			||||||
    "autoload": {
 | 
					    "autoload": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,15 +204,78 @@ class Editor
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case 'Q':
 | 
					                case 'Q':
 | 
				
			||||||
                case "\x03":
 | 
					                case "\x03": // ctrl-w
 | 
				
			||||||
                    $this->running = false;
 | 
					                    $this->running = false;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "\x12": // ctrl-r
 | 
				
			||||||
 | 
					                    $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";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "\x17": // ctrl-w
 | 
				
			||||||
 | 
					                    $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";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case null:
 | 
					                case null:
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    $this->term->setCursor(1, $h, true);
 | 
					                    $this->term->setCursor(1, $h, true);
 | 
				
			||||||
                    echo $read; 
 | 
					                    echo sprintf("%s %02x %03d", ctype_print($read)?$read:'.', ord($read), ord($read));
 | 
				
			||||||
                    sleep(1);
 | 
					                    sleep(1);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -248,6 +311,7 @@ class Editor
 | 
				
			|||||||
                        return $value;
 | 
					                        return $value;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (ord($ch) == 3) {
 | 
					                    if (ord($ch) == 3) {
 | 
				
			||||||
 | 
					                        // ctrl-c
 | 
				
			||||||
                        $this->term->setCursor(1, $h);
 | 
					                        $this->term->setCursor(1, $h);
 | 
				
			||||||
                        echo "\e[0m\e[K";
 | 
					                        echo "\e[0m\e[K";
 | 
				
			||||||
                        return null;
 | 
					                        return null;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,7 +154,7 @@ class TreeList implements Countable
 | 
				
			|||||||
        if (!is_null($entry->key)) {
 | 
					        if (!is_null($entry->key)) {
 | 
				
			||||||
            echo (is_int($entry->key)
 | 
					            echo (is_int($entry->key)
 | 
				
			||||||
                ?"\e[36;2m\u{e0b6}\e[7m#{$entry->key}\e[27m\u{e0b4}\e[22m "
 | 
					                ?"\e[36;2m\u{e0b6}\e[7m#{$entry->key}\e[27m\u{e0b4}\e[22m "
 | 
				
			||||||
                :"\e[36m\"{$entry->key}\":\e[37m ");
 | 
					                :"\e[36m{$entry->key}:\e[37m ");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($entry->node instanceof ArrayNode) {
 | 
					        if ($entry->node instanceof ArrayNode) {
 | 
				
			||||||
            echo "[";
 | 
					            echo "[";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace NoccyLabs\JEdit\Terminal;
 | 
					namespace NoccyLabs\JEdit\Terminal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Terminal
 | 
					class Terminal
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private static int $init = 0;
 | 
					    private static int $init = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,5 +27,10 @@ class ArrayNode extends Node implements CollapsibleNode
 | 
				
			|||||||
        return new ArrayNode($items);
 | 
					        return new ArrayNode($items);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jsonSerialize(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array_values($this->items);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace NoccyLabs\JEdit\Tree;
 | 
					namespace NoccyLabs\JEdit\Tree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class Node
 | 
					use JsonSerializable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract class Node implements JsonSerializable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,5 +29,10 @@ class ObjectNode extends Node implements CollapsibleNode
 | 
				
			|||||||
        return new ObjectNode($properties);
 | 
					        return new ObjectNode($properties);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jsonSerialize(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->properties;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,18 @@ class Tree
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function save(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->root) 
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return json_decode(
 | 
				
			||||||
 | 
					            json_encode(
 | 
				
			||||||
 | 
					                $this->root
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function parseNode(mixed $node): Node
 | 
					    private function parseNode(mixed $node): Node
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (is_array($node) && array_is_list($node)) {
 | 
					        if (is_array($node) && array_is_list($node)) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,5 +7,10 @@ class ValueNode extends Node
 | 
				
			|||||||
    public function __construct(public mixed $value)
 | 
					    public function __construct(public mixed $value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jsonSerialize(): mixed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user