commit 4940f97f8cc9ad33079dec85720f8eef0f2a2a0f
parent 47ff0ed3be44c1ebe20aad21033e3e372d1c64ec
Author: Martin Ashby <martin@ashbysoft.com>
Date: Sat, 13 Jan 2024 09:04:32 +0000
Step 70
Diffstat:
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;