From b44227992f79b1a635d44a07fc8601fd418984bc Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 16 Jun 2026 09:39:24 -0300 Subject: scrolling --- main.zig | 109 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 40 deletions(-) (limited to 'main.zig') diff --git a/main.zig b/main.zig index db0cda14..0c7b780e 100644 --- a/main.zig +++ b/main.zig @@ -26,6 +26,7 @@ pub const Command = struct { const Loop = vaxis.Loop(@TypeOf(Command.value)); const MAX_FILES: usize = 0x200; +var rendered_lines: usize = 8; fn ticker(io: std.Io, loop: *Loop) void { while (true) { @@ -40,24 +41,36 @@ pub fn main(init: std.process.Init) !void { const io = init.io; const gpa = init.gpa; + var scroll_off: u32 = 0; + + const MAX_LEN: usize = 0x100; var tty_buf: [0x10000]u8 = undefined; - var lines: [0x1000][0x1000]u8 = undefined; - @memcpy(lines[0][0..2], ".."); - lines[0][2] = 0; + var lines: [0x1000][MAX_LEN]u8 = undefined; + const lstart = 5; const dir = std.Io.Dir.cwd(); var cwd = try std.Io.Dir.openDir(dir, io, ".", .{ .iterate = true }); + const cwd_len = try cwd.realPath(io, &lines[2]); + + @memcpy(lines[0][0..1], "."); + lines[0][1] = 0; + @memcpy(lines[1][0..2], ".."); + lines[1][2] = 0; + lines[2][cwd_len] = 0; + lines[3][0] = 0; + lines[4][0] = 0; { var i: usize = 0; - var walk = try cwd.walk(gpa); + var walk = try cwd.walkSelectively(gpa); defer walk.deinit(); while (try walk.next(io)) |e| : (i += 1) { if (i > MAX_FILES) break; - @memcpy(lines[i + 1][0..e.path.len], e.path); - lines[i + 1][e.path.len] = 0; + @memcpy(lines[i + lstart][0..e.path.len], e.path); + lines[i + lstart][e.path.len] = 0; } + rendered_lines = i; } var tty = try vaxis.Tty.init(io, &tty_buf); @@ -80,57 +93,53 @@ pub fn main(init: std.process.Init) !void { while (true) { const event = try loop.nextEvent(); const win = vx.window(); - - for (0..MAX_FILES) |i| { - if (i > MAX_FILES) break; - - // const str: [:0]u8 = std.mem.absorbSentinel(&line); - const len = std.mem.findSentinel(u8, 0, @ptrCast(&lines[i])); - _ = win.printSegment(.{ .text = lines[i][0..len] }, .{ - .row_offset = @intCast(i), - .col_offset = 4, - .wrap = .none, - }); - } + var arena: std.heap.ArenaAllocator = .init(gpa); + defer arena.deinit(); switch (event) { .key_press => |key| { - if (key.matches('c', .{ .ctrl = true })) { + if (key.matches('c', .{ .ctrl = true }) or key.matches(vaxis.Key.escape, .{})) { break; } }, .mouse => |m| { - if (m.type == .press) { + if (m.type == .press and m.button == .wheel_down) { + scroll_off += 1; + win.clear(); + } + if (m.type == .press and m.button == .wheel_up) { + if (scroll_off > 0) { + scroll_off -= 1; + win.clear(); + } + continue; + } + + const line_idx = @as(usize, @intCast(m.row)) + scroll_off; + _ = try std.fmt.bufPrintSentinel(&lines[3], "{} {any}", .{ rendered_lines, m }, 0); + + if (m.type == .press and (m.button == .right or m.button == .left)) { // const txt = try std.fmt.allocPrint(gpa, "col={} row={} xo={} yo={}", .{ m.col, m.row, m.xoffset, m.yoffset }); - const len = std.mem.findSentinel(u8, 0, @ptrCast(&lines[@intCast(m.row)])); - _ = win.printSegment( - .{ - .text = lines[@intCast(m.row)][0..len], - .style = .{ .fg = .{ .rgb = .{ 0x00, 0xd0, 0xaa } } }, - }, - .{ - .col_offset = @as(u16, @intCast(m.col)), - .row_offset = @as(u16, @intCast(m.row)), - .wrap = .none, - }, - ); - - if (cwd.openDir(io, lines[@intCast(m.row)][0..len], .{ .iterate = true })) |d| { + const len = std.mem.findSentinel(u8, 0, @ptrCast(&lines[line_idx])); + const selected_line = lines[line_idx][0..len]; + + if (cwd.openDir(io, selected_line, .{ .iterate = true })) |d| { cwd = d; - var walk = try cwd.walk(gpa); + var walk = try cwd.walkSelectively(gpa); defer walk.deinit(); var i: usize = 0; while (try walk.next(io)) |e| : (i += 1) { if (i > MAX_FILES) break; - @memcpy(lines[i + 1][0..e.path.len], e.path); - lines[i + 1][e.path.len] = 0; + @memcpy(lines[i + lstart][0..e.path.len], e.path); + lines[i + lstart][e.path.len] = 0; } + rendered_lines = i; win.clear(); // if it's not a dir maybe it's a file } else |_| { - if (cwd.openFile(io, lines[@intCast(m.row)][0..len], .{ .mode = .read_only })) |f| { + if (cwd.openFile(io, selected_line, .{ .mode = .read_only })) |f| { var buf: [0x100]u8 = undefined; const flen = try f.length(io); var reader = f.reader(io, &buf); @@ -140,18 +149,38 @@ pub fn main(init: std.process.Init) !void { while (iter.next()) |line| : (i += 1) { if (i > MAX_FILES) break; - @memcpy(lines[i + 1][0..line.len], line); - lines[i + 1][line.len] = 0; + @memcpy(lines[i + lstart][0..line.len], line); + lines[i + lstart][line.len] = 0; } + rendered_lines = i; win.clear(); } else |_| {} } + + scroll_off = 0; } }, .winsize => |ws| try vx.resize(gpa, tty.writer(), ws), else => {}, } + for (0..@min(MAX_FILES, rendered_lines + lstart)) |i| { + const len = @min(std.mem.findSentinel(u8, 0, @ptrCast(&lines[i + scroll_off])), MAX_LEN - 1); + + _ = win.printSegment(.{ .text = lines[i + scroll_off][0..len] }, .{ + .row_offset = @intCast(i), + .col_offset = 4, + .wrap = .none, + }); + + const num = try std.fmt.allocPrintSentinel(arena.allocator(), "{:02}", .{i + scroll_off}, 0); + _ = win.printSegment(.{ .text = num }, .{ + .row_offset = @intCast(i), + .col_offset = 0, + .wrap = .none, + }); + } + try vx.render(tty.writer()); } } -- cgit v1.3