libvaxis/src/InternalScreen.zig
Jora Troosh 4a463cfa3a
refactor: make code more idiomatic
- Added standard .gitattributes file for Zig projects.
- Reworked build.zig a little, hopefully it's a bit clearer. Also, now zig build will run all steps.
- outer: while in examples was redundant since there's only one loop to break from. switch expressions don't allow breaking from them, so breaking is only for loops, i.e. while and for.
- When returning a struct instance from a function, the compiler infers the return type from function signature, so instead of return MyType{...}; , it's more idiomatic to write return .{...};.
- Logging adds a new line by default, so you don't usually need to write \n like here: log.debug("event: {}\r\n", .{event});.
2024-02-11 12:59:33 -06:00

95 lines
2.6 KiB
Zig

const std = @import("std");
const assert = std.debug.assert;
const Style = @import("Cell.zig").Style;
const Cell = @import("Cell.zig");
const Shape = @import("Mouse.zig").Shape;
const log = std.log.scoped(.internal_screen);
const InternalScreen = @This();
pub const InternalCell = struct {
char: std.ArrayList(u8) = undefined,
style: Style = .{},
uri: std.ArrayList(u8) = undefined,
uri_id: std.ArrayList(u8) = undefined,
// if we got skipped because of a wide character
skipped: bool = false,
pub fn eql(self: InternalCell, cell: Cell) bool {
return std.mem.eql(u8, self.char.items, cell.char.grapheme) and
std.meta.eql(self.style, cell.style) and
std.mem.eql(u8, self.uri.items, cell.link.uri) and
std.mem.eql(u8, self.uri_id.items, cell.link.params);
}
};
width: usize = 0,
height: usize = 0,
buf: []InternalCell = undefined,
cursor_row: usize = 0,
cursor_col: usize = 0,
cursor_vis: bool = false,
mouse_shape: Shape = .default,
/// sets each cell to the default cell
pub fn init(alloc: std.mem.Allocator, w: usize, h: usize) !InternalScreen {
var screen = InternalScreen{
.buf = try alloc.alloc(InternalCell, w * h),
};
for (screen.buf, 0..) |_, i| {
screen.buf[i] = .{
.char = try std.ArrayList(u8).initCapacity(alloc, 1),
.uri = std.ArrayList(u8).init(alloc),
.uri_id = std.ArrayList(u8).init(alloc),
};
}
screen.width = w;
screen.height = h;
return screen;
}
pub fn deinit(self: *InternalScreen, alloc: std.mem.Allocator) void {
for (self.buf, 0..) |_, i| {
self.buf[i].char.deinit();
self.buf[i].uri.deinit();
self.buf[i].uri_id.deinit();
}
alloc.free(self.buf);
}
/// writes a cell to a location. 0 indexed
pub fn writeCell(
self: *InternalScreen,
col: usize,
row: usize,
cell: Cell,
) void {
if (self.width < col) {
// column out of bounds
return;
}
if (self.height < row) {
// height out of bounds
return;
}
const i = (row * self.width) + col;
assert(i < self.buf.len);
self.buf[i].char.clearRetainingCapacity();
self.buf[i].char.appendSlice(cell.char.grapheme) catch {
log.warn("couldn't write grapheme", .{});
};
self.buf[i].uri.clearRetainingCapacity();
self.buf[i].uri.appendSlice(cell.link.uri) catch {
log.warn("couldn't write uri", .{});
};
self.buf[i].uri.clearRetainingCapacity();
self.buf[i].uri_id.appendSlice(cell.link.params) catch {
log.warn("couldn't write uri_id", .{});
};
self.buf[i].style = cell.style;
}