kiloz

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

commit 4940f97f8cc9ad33079dec85720f8eef0f2a2a0f
parent 47ff0ed3be44c1ebe20aad21033e3e372d1c64ec
Author: Martin Ashby <martin@ashbysoft.com>
Date:   Sat, 13 Jan 2024 09:04:32 +0000

Step 70

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

diff --git a/src/main.zig b/src/main.zig @@ -36,10 +36,11 @@ const EditorState = struct { a: std.mem.Allocator, screen_buf: std.ArrayListUnmanaged(u8) = .{}, termios_orig: std.os.linux.termios = undefined, - screenrows: u16 = 0, - screencols: u16 = 0, - cx: u16 = 10, - cy: u16 = 10, + screenrows: usize = 0, + screencols: usize = 0, + cx: usize = 0, + cy: usize = 0, + rowoff: usize = 0, erow: []ERow = &[_]ERow{}, fn init(a: std.mem.Allocator) EditorState { @@ -226,6 +227,8 @@ fn clearScreen() void { } fn editorRefreshScreen(es: *EditorState) !void { + editorScroll(es); + // Use a buffer to avoid multiple write() calls to the actual terminal device // Reduces rendering artifacts / flickering es.screen_buf.clearRetainingCapacity(); @@ -235,7 +238,7 @@ fn editorRefreshScreen(es: *EditorState) !void { //try wtr.writeAll("\x1b[2J"); // J clear 2 whole screen try wtr.writeAll("\x1b[H"); // Reset cursor (to 1:1) try editorDrawRows(es, wtr); - try std.fmt.format(wtr, "\x1b[{};{}H", .{ es.cy + 1, es.cx + 1 }); // Move the cursor to our stored position + try std.fmt.format(wtr, "\x1b[{};{}H", .{ es.cy - es.rowoff + 1, es.cx + 1 }); // Move the cursor to our stored position try wtr.writeAll("\x1b[?25h"); // Show the cursor again try std.io.getStdOut().writeAll(es.screen_buf.items); } @@ -246,7 +249,8 @@ 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.erow.len) { + const filerow = y + es.rowoff; + if (filerow >= 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); @@ -259,7 +263,7 @@ fn editorDrawRows(es: *const EditorState, wtr: anytype) !void { try wtr2.writeAll("~"); } } else { - try wtr2.writeAll(es.erow[y]); + try wtr2.writeAll(es.erow[filerow]); } if (y < es.screenrows-1) { @@ -268,6 +272,15 @@ fn editorDrawRows(es: *const EditorState, wtr: anytype) !void { } } +fn editorScroll(es: *EditorState) void { + if (es.cy < es.rowoff) { + es.rowoff = es.cy; + } + if (es.cy >= es.rowoff + es.screenrows) { + es.rowoff = es.cy - es.screenrows + 1; + } +} + //// Input fn editorProcessKeyPress(es: *EditorState) !void { @@ -294,7 +307,7 @@ fn editorMoveCursor(key: editorKey, es: *EditorState) !void { if (es.cy > 0) es.cy -= 1; }, .ARROW_DOWN => { - if (es.cy < (es.screenrows - 1)) es.cy += 1; + if (es.cy < es.erow.len) es.cy += 1; }, .ARROW_LEFT => { if (es.cx > 0) es.cx -= 1; @@ -303,10 +316,10 @@ fn editorMoveCursor(key: editorKey, es: *EditorState) !void { if (es.cx < (es.screencols - 1)) es.cx += 1; }, .PAGE_UP => { - es.cy = 0; + es.cy = std.math.sub(usize, es.cy, es.screenrows) catch 0; }, .PAGE_DOWN => { - es.cy = es.screenrows-1; + es.cy = @min(es.cy+es.screenrows, es.erow.len-1); }, .HOME => { es.cx = 0;