kiloz

Following through https://viewsourcecode.org/snaptoken/kilo/index.html in Zig
git clone git://code.mfashby.net:/kiloz
Log | Files | Refs | README

commit 47ff0ed3be44c1ebe20aad21033e3e372d1c64ec
parent d16a87f06db376f22748512a41d2d7b088545765
Author: Martin Ashby <martin@ashbysoft.com>
Date:   Sat, 13 Jan 2024 08:45:01 +0000

Step 65

Diffstat:
Msrc/main.zig | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 55 insertions(+), 10 deletions(-)

diff --git a/src/main.zig b/src/main.zig @@ -14,7 +14,12 @@ pub fn main() !void { defer clearScreen(); try initEditor(&es); - + const args = try std.process.argsAlloc(es.a); + defer std.process.argsFree(es.a, args); + if (args.len > 1) { + try editorOpen(&es, args[1]); + } + while (true) { try editorRefreshScreen(&es); @@ -35,15 +40,22 @@ const EditorState = struct { screencols: u16 = 0, cx: u16 = 10, cy: u16 = 10, + erow: []ERow = &[_]ERow{}, fn init(a: std.mem.Allocator) EditorState { return .{ .a = a }; } fn deinit(self: *EditorState) void { self.screen_buf.deinit(self.a); + for (self.erow) |erow| { + self.a.free(erow); + } + self.a.free(self.erow); } }; +const ERow = []u8; + //// Terminal handling // Returns the original termios setting for restoring terminal function at exit. @@ -177,6 +189,34 @@ fn getWindowSize() !Size { } } +//// Row operations + +fn editorAppendRow(es: *EditorState, line: []u8) !void { + const numrows = es.erow.len; + es.erow = try es.a.realloc(es.erow, numrows + 1); + es.erow[numrows] = line; +} + +//// File i/o + +fn editorOpen(es: *EditorState, filename: []const u8) !void { + const f = try std.fs.cwd().openFile(filename, .{}); + defer f.close(); + var br = std.io.bufferedReader(f.reader()); + var rdr = br.reader(); + var al = std.ArrayList(u8).init(es.a); + defer al.deinit(); + lp: while (true) { + rdr.streamUntilDelimiter(al.writer(), '\n', null) catch |e| switch (e) { + error.EndOfStream => break :lp, + else => return e, + }; + const line = try al.toOwnedSlice(); + errdefer es.a.free(line); + try editorAppendRow(es, line); + } +} + //// Output fn clearScreen() void { @@ -206,20 +246,25 @@ fn editorDrawRows(es: *const EditorState, wtr: anytype) !void { var lw = limitedWriter(wtr, es.screencols); // Never write more than we have columns const wtr2 = lw.writer(); - if (y == es.screenrows / 3) { - const welcome_msg = try std.fmt.allocPrint(es.a, "Kilo editor -- version {s}", .{version}); // TODO don't allocate every time... - defer es.a.free(welcome_msg); - const padding = (es.screencols - welcome_msg.len) / 2; - for (0..padding) |y2| { - try wtr2.writeByte(if (y2 == 0) '~' else ' '); + if (y >= es.erow.len) { + if (es.erow.len == 0 and y == es.screenrows / 3) { + const welcome_msg = try std.fmt.allocPrint(es.a, "Kilo editor -- version {s}", .{version}); // TODO don't allocate every time... + defer es.a.free(welcome_msg); + const padding = (es.screencols - welcome_msg.len) / 2; + for (0..padding) |y2| { + try wtr2.writeByte(if (y2 == 0) '~' else ' '); + } + try wtr2.writeAll(welcome_msg); + } else { + try wtr2.writeAll("~"); } - try wtr2.writeAll(welcome_msg); } else { - try wtr2.writeAll("~"); + try wtr2.writeAll(es.erow[y]); } - if (y < es.screenrows-1) + if (y < es.screenrows-1) { try wtr.writeAll("\r\n"); + } } }