summary refs log tree commit diff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig184
1 files changed, 134 insertions, 50 deletions
diff --git a/src/main.zig b/src/main.zig
index aec275c..c2d9d12 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -4,23 +4,40 @@
 
 const Allocator = std.mem.Allocator;
 const DebugAllocator = std.heap.DebugAllocator;
+const argsAlloc = std.process.argsAlloc;
+const argsFree = std.process.argsFree;
 const builtin = @import("builtin");
+const cwd = std.fs.cwd;
 const eql = std.mem.eql;
+const maxInt = std.math.maxInt;
 const ns_per_s = std.time.ns_per_s;
 const smp_allocator = std.heap.smp_allocator;
 const std = @import("std");
 
 const Key = vaxis.Key;
 const Loop = vaxis.Loop;
+const Style = vaxis.Cell.Style;
 const Tty = vaxis.Tty;
 const Unicode = vaxis.Unicode;
+const Window = vaxis.Window;
 const Winsize = vaxis.Winsize;
 const gwidth = vaxis.gwidth.gwidth;
+const Vaxis = vaxis.Vaxis;
 const vaxis = @import("vaxis");
+
+const Parser = tree_sitter.Parser;
+const tree_sitter = @import("tree-sitter");
+
 const zsanett = @import("zsanett");
+pub fn zsanettIntern(T: type) bool {
+    return switch (T) {
+        Environment, Key, Loop(Event) => true,
+        else => false,
+    };
+}
 
 const Config = @import("Config.zig");
-const Token = @import("Token.zig");
+const selection = @import("selection.zig");
 const languages = @import("languages");
 
 const Event = union(enum) {
@@ -28,6 +45,88 @@ const Event = union(enum) {
     winsize: Winsize,
 };
 
+const Environment = struct {
+    allocator: Allocator,
+    loop: *Loop(Event),
+    parser: *Parser,
+    span: *selection.Span,
+    text: []const u8,
+    tty: *Tty,
+    vaxis: *Vaxis,
+
+    pub fn nextEvent(self: Environment) !Event {
+        while (true) {
+            const event = self.loop.nextEvent();
+            switch (event) {
+                .key_press => return event,
+                .winsize => |ws| {
+                    try self.vaxis.resize(self.allocator,
+                                          self.tty.anyWriter(), ws);
+                    try self.render();
+                },
+            }
+        }
+    }
+
+    pub fn render(self: Environment) !void {
+        const window = self.vaxis.window();
+        window.clear();
+        var col: u16 = 0;
+        var row: u16 = 0;
+        var graphemes = self.vaxis.unicode.graphemeIterator(self.text);
+        while (graphemes.next()) |grapheme| {
+            const style = Style {
+                .reverse = self.span.contains(grapheme),
+            };
+            const bytes = grapheme.bytes(self.text);
+            if (eql(u8, bytes, "\n")) {
+                const width = window.gwidth("$");
+                defer col = 0;
+                defer row += 1;
+                window.writeCell(col, row, .{
+                    .char = .{ .grapheme = "$", .width = @intCast(width) },
+                    .style = style,
+                });
+            } else if (eql(u8, bytes, "\t")) {
+                var tab = self.vaxis.unicode.graphemeIterator("  ");
+                while (tab.next()) |g| {
+                    const b = g.bytes("  ");
+                    const width = window.gwidth(b);
+                    defer col += width;
+                    window.writeCell(col, row, .{
+                        .char = .{ .grapheme = b, .width = @intCast(width) },
+                        .style = style,
+                    });
+                }
+            } else {
+                const width = window.gwidth(bytes);
+                defer col += width;
+                window.writeCell(col, row, .{
+                    .char = .{ .grapheme = bytes, .width = @intCast(width) },
+                    .style = style,
+                });
+            }
+        }
+        try self.vaxis.render(self.tty.anyWriter());
+    }
+
+    pub fn goUp(self: Environment) void {
+        self.span.goUp();
+    }
+
+    pub fn goRight(self: Environment) void {
+        self.span.goRight(self.vaxis.unicode.width_data.graphemes, self.text);
+    }
+
+    pub fn goLeft(self: Environment) void {
+        self.span.goLeft(self.vaxis.unicode.width_data.graphemes, self.text);
+    }
+
+    pub fn goDown(self: Environment) void {
+        self.span.goDown(self.vaxis.unicode.width_data.graphemes, self.text);
+    }
+};
+
 pub fn main() !void {
     var debug_allocator = DebugAllocator(.{}).init;
     defer _ = debug_allocator.deinit();
@@ -36,64 +135,49 @@ pub fn main() !void {
         .ReleaseFast, .ReleaseSmall => smp_allocator,
     };
 
-    zsanett.init();
-    defer zsanett.deinit();
-    const janet_env = zsanett.Environment.init(null);
-    const config = try Config.parse(allocator, janet_env);
-
     var tty = try Tty.init();
     defer tty.deinit();
     var vx = try vaxis.init(allocator, .{});
     defer vx.deinit(allocator, tty.anyWriter());
+
     var loop = Loop(Event){ .tty = &tty, .vaxis = &vx };
     try loop.init();
     try loop.start();
     defer loop.stop();
 
+    const parser = Parser.create();
+    defer parser.destroy();
+
+    const args = try argsAlloc(allocator);
+    defer argsFree(allocator, args);
+    const text = try cwd().readFileAlloc(allocator, args[1], maxInt(u32));
+    defer allocator.free(text);
     try vx.enterAltScreen(tty.anyWriter());
-    // For the alternate screen
-    try vx.queryTerminal(tty.anyWriter(), 1 * ns_per_s);
-
-    const text = "int main()\n{\n\treturn 0;\n}\n";
-    var tokens = try Token.ize(text, languages.c);
-    defer tokens.deinit();
-
-    while (true) {
-        switch (loop.nextEvent()) {
-            .key_press => |key| {
-                if (key.matches('c', .{ .ctrl = true })) {
-                    break;
-                }
-            },
-            .winsize => |ws| try vx.resize(allocator, tty.anyWriter(), ws),
-        }
-        const window = vx.window();
-        window.clear();
-        var col: u16 = 0;
-        var row: u16 = 0;
-        tokens.reset();
-        while (tokens.next()) |token| {
-            var graphemes = vx.unicode.graphemeIterator(token.text);
-            while (graphemes.next()) |grapheme| {
-                const bytes = grapheme.bytes(token.text);
-                if (eql(u8, bytes, "\r\n")
-                    or eql(u8, bytes, "\r")
-                    or eql(u8, bytes, "\n")) {
-                    col = 0;
-                    row += 1;
-                    continue;
-                }
-                const width: u8 = if (eql(u8, bytes, "\t"))
-                    config.tab_width
-                else
-                    @intCast(gwidth(bytes, vx.caps.unicode,
-                                    &vx.unicode.width_data));
-                defer col += width;
-                window.writeCell(col, row, .{
-                    .char = .{ .grapheme = bytes, .width = width },
-                });
-            }
-        }
-        try vx.render(tty.anyWriter());
+    try vx.queryTerminal(tty.anyWriter(), 1 * ns_per_s); // for alt screen
+
+    const language = languages.c();
+    defer language.destroy();
+    try parser.setLanguage(language);
+    const tree = parser.parseString(text, null).?;
+    defer tree.destroy();
+
+    zsanett.init();
+    defer zsanett.deinit();
+    var span = selection.Span{
+        .head = .{ .node = tree.rootNode() },
+        .tail = .{ .node = tree.rootNode() },
+    };
+    try zsanett.def("env", Environment{
+        .allocator = allocator,
+        .loop = &loop,
+        .parser = parser,
+        .span = &span,
+        .text = text,
+        .tty = &tty,
+        .vaxis = &vx,
+    }, "eval environment");
+    switch (try zsanett.eval(void, @embedFile("main.janet"), "main.janet")) {
+        .ret => {},
+        .err => |err| @panic(err),
     }
 }