Something went wrong. Try again.
地圖 (Jido) is a lightweight Unix TUI file explorer designed for speed and simplicity.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156const std = @import("std");
const vaxis = @import("vaxis");
pub fn List(comptime T: type) type { return struct { const Self = @This();
alloc: std.mem.Allocator, items: std.ArrayList(T), selected: usize,
pub fn init(alloc: std.mem.Allocator) Self { return Self{ .alloc = alloc, .items = .empty, .selected = 0, }; }
pub fn deinit(self: *Self) void { self.items.deinit(self.alloc); }
pub fn append(self: *Self, item: T) !void { try self.items.append(self.alloc, item); }
pub fn clear(self: *Self) void { self.items.clearAndFree(self.alloc); self.selected = 0; }
pub fn fromArray(self: *Self, array: []const T) !void { for (array) |item| { try self.append(item); } }
pub fn get(self: Self, index: usize) !T { if (index + 1 > self.len()) { return error.OutOfBounds; }
return self.all()[index]; }
pub fn getSelected(self: *Self) !?T { if (self.len() > 0) { if (self.selected >= self.len()) { self.selected = self.len() - 1; }
return try self.get(self.selected); }
return null; }
pub fn all(self: Self) []T { return self.items.items; }
pub fn len(self: Self) usize { return self.items.items.len; }
pub fn next(self: *Self) void { if (self.selected + 1 < self.len()) { self.selected += 1; } }
pub fn previous(self: *Self) void { if (self.selected > 0) { self.selected -= 1; } }
pub fn selectLast(self: *Self) void { self.selected = self.len() - 1; }
pub fn selectFirst(self: *Self) void { self.selected = 0; } };}
const testing = std.testing;
test "List: navigation respects bounds" { var list = List(u32).init(testing.allocator); defer list.deinit();
try list.append(1); try list.append(2); try list.append(3);
try testing.expectEqual(@as(usize, 0), list.selected);
list.next(); try testing.expectEqual(@as(usize, 1), list.selected);
list.next(); list.next(); // Try to go past end list.next(); // Should stay at last try testing.expectEqual(@as(usize, 2), list.selected);
list.previous(); try testing.expectEqual(@as(usize, 1), list.selected);
list.previous(); // Try to go before start list.previous(); // Should stay at first try testing.expectEqual(@as(usize, 0), list.selected);}
test "List: getSelected handles empty list" { var list = List(u32).init(testing.allocator); defer list.deinit();
const result = try list.getSelected(); try testing.expect(result == null);}
test "List: append and get operations" { var list = List(u32).init(testing.allocator); defer list.deinit();
try list.append(42); try list.append(84);
try testing.expectEqual(@as(usize, 2), list.len()); try testing.expectEqual(@as(u32, 42), try list.get(0)); try testing.expectEqual(@as(u32, 84), try list.get(1));}
test "List: selectFirst and selectLast" { var list = List(u32).init(testing.allocator); defer list.deinit();
try list.append(1); try list.append(2); try list.append(3);
list.selectLast(); try testing.expectEqual(@as(usize, 2), list.selected);
list.selectFirst(); try testing.expectEqual(@as(usize, 0), list.selected);}