From ec9ce614d87a47137cfbbb0f6d13aa30e4a1239c Mon Sep 17 00:00:00 2001
From: Holden Rohrer <hr@hrhr.dev>
Date: Sat, 14 Aug 2021 17:37:56 -0400
Subject: completed save/load feature

---
 source/app.d   | 109 ++++++++++++---------------------------------------------
 source/spots.d |  25 +++++++------
 2 files changed, 37 insertions(+), 97 deletions(-)

(limited to 'source')

diff --git a/source/app.d b/source/app.d
index 52074b1..1d04fc9 100644
--- a/source/app.d
+++ b/source/app.d
@@ -78,12 +78,11 @@ void main()
                 file.writefln!"%s %s"(disp.y, disp.x);
                 file.writefln!"%d"(rocks);
                 overlay.save(file);
+                disp.print();
             }
             catch (Exception e)
             {
-                // TODO: log the error in a user-visible way
             }
-            disp.print();
             break;
         case 'l':
             auto filename = stdscr.readquery("Load:");
@@ -114,81 +113,6 @@ void main()
     }
 }
 
-import std.range.interfaces : InputRange;
-
-class Reader : InputRange!char
-{
-
-    private int _front;
-    private bool _empty;
-    // Might could be implemented with a larger getnstr
-
-    this()
-    {
-        _front = getch();
-    }
-
-    char moveFront()
-    in
-    {
-        assert(!_empty);
-    }
-    do
-    {
-        auto ret = front();
-        popFront();
-        return ret;
-    }
-
-    @property char front()
-    in
-    {
-        assert(!_empty);
-    }
-    do
-    {
-        return cast(char) _front;
-    }
-
-    void popFront()
-    in
-    {
-        assert(!_empty);
-    }
-    do
-    {
-        _front = getch();
-        if (_front == -1)
-            _empty = true;
-    }
-
-    @property bool empty()
-    {
-        return _empty;
-    }
-
-    int opApply(scope int delegate(char) run)
-    {
-        for (; !_empty; popFront())
-        {
-            if (run(front()))
-                return 1;
-        }
-
-        return 0;
-    }
-
-    int opApply(scope int delegate(size_t, char) run)
-    {
-        for (size_t i = 0; !_empty; popFront(), i++)
-        {
-            if (run(i, front()))
-                return 1;
-        }
-        return 0;
-    }
-}
-
 string readquery(WINDOW* stdscr, string query)
 {
     import std.range : replicate;
@@ -202,19 +126,32 @@ string readquery(WINDOW* stdscr, string query)
     mvprintw(height, 0, toStringz(query ~ " ".replicate(width - query.length)));
     move(height, cast(int) query.length + 1);
 
-    echo();
     scrollok(stdscr, false);
-    auto build = appender!string;
+    auto build = appender!(char[]);
 
-    auto reader = new Reader();
-
-    while (!reader.empty && reader.front != '\r')
+    int p = cast(int) query.length + 1;
+    while (auto ch = getch())
     {
-        build ~= reader.front;
-        reader.popFront;
+        if (ch == '\r' || ch == EOF)
+            break;
+        if (ch == '\b' || ch == KEY_BACKSPACE || ch == 127)
+        {
+            if (build[].length > 0)
+            {
+                p--;
+                mvaddch(height, p, ' ');
+                build.shrinkTo(build[].length - 1);
+                move(height, p);
+            }
+        }
+        else
+        {
+            build ~= cast(char) ch;
+            addch(ch);
+            p++;
+        }
     }
-    noecho();
     scrollok(stdscr, true);
 
-    return build.data;
+    return cast(string) build[];
 }
diff --git a/source/spots.d b/source/spots.d
index f57ba8f..49b9c85 100644
--- a/source/spots.d
+++ b/source/spots.d
@@ -28,16 +28,17 @@ struct Spot
         _contents = c;
     }
 
+    import std.format : format, formattedRead;
+
     string toString()
     {
-        import std.format : format;
 
-        return format("'%c'", _contents);
+        return format!`'%c'`(_contents);
     }
 
-    void fromString(S)(S s) if (isSomeString!S)
+    void fromString(Range)(auto ref Range s)
     {
-        _contents = cast(char) s[1];
+        s.formattedRead!`'%c'`(_contents);
     }
 
     @property contents()
@@ -165,7 +166,7 @@ class OverlaySource : SpotSource
         _base.save(f);
         foreach (coord; _overlay.keys())
         {
-            f.writefln!"%s, %s: %s"(coord[0], coord[1], _overlay[coord]);
+            f.writefln!"%s %s: %s"(coord[0], coord[1], _overlay[coord]);
         }
         f.write(terminator);
     }
@@ -173,21 +174,23 @@ class OverlaySource : SpotSource
     void load(File f)
     {
         import std.conv : to;
-        import std.algorithm.iteration;
+        import std.algorithm;
 
+        //_overlay = _overlay.init;
         _base.load(f);
         foreach (char[] line; f.lines)
         {
             if (line == terminator)
                 break;
-            auto trim = line.filter!(a => a == ' ' || a == '\r' || a == '\n').array;
-            auto parts = trim.splitter(':');
-            auto ints = parts.moveFront.splitter(',').map!(to!BigInt);
+
+            auto ints = line.until(':').array.splitter(' ').map!(to!BigInt);
             BigInt[2] coord;
-            coord[0] = ints.moveFront;
+            coord[0] = ints.front;
+            ints.popFront;
             coord[1] = ints.front;
+
             auto s = new Spot();
-            (*s).fromString(parts.front);
+            (*s).fromString(line.find(':').find('\''));
             _overlay[coord] = *s;
         }
     }
-- 
cgit