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});.
This commit is contained in:
Jora Troosh 2024-02-11 21:59:33 +03:00 committed by GitHub
parent a733860a21
commit 4a463cfa3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 115 additions and 160 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
*.zig text eol=lf
*.zon text eol=lf

View file

@ -53,7 +53,7 @@ const border = vaxis.widgets.border;
const log = std.log.scoped(.main); const log = std.log.scoped(.main);
// Our EventType. This can contain internal events as well as Vaxis events. // This can contain internal events as well as Vaxis events.
// Internal events can be posted into the same queue as vaxis events to allow // Internal events can be posted into the same queue as vaxis events to allow
// for a single event loop with exhaustive switching. Booya // for a single event loop with exhaustive switching. Booya
const Event = union(enum) { const Event = union(enum) {
@ -102,12 +102,12 @@ pub fn main() !void {
// The main event loop. Vaxis provides a thread safe, blocking, buffered // The main event loop. Vaxis provides a thread safe, blocking, buffered
// queue which can serve as the primary event queue for an application // queue which can serve as the primary event queue for an application
outer: while (true) { while (true) {
// nextEvent blocks until an event is in the queue // nextEvent blocks until an event is in the queue
const event = vx.nextEvent(); const event = vx.nextEvent();
log.debug("event: {}\r\n", .{event}); log.debug("event: {}", .{event});
// exhaustive switching ftw. Vaxis will send events if your EventType // exhaustive switching ftw. Vaxis will send events if your Event enum
// enum has the fields for those events (ie "key_press", "winsize") // has the fields for those events (ie "key_press", "winsize")
switch (event) { switch (event) {
.key_press => |key| { .key_press => |key| {
color_idx = switch (color_idx) { color_idx = switch (color_idx) {
@ -115,7 +115,7 @@ pub fn main() !void {
else => color_idx + 1, else => color_idx + 1,
}; };
if (key.matches('c', .{ .ctrl = true })) { if (key.matches('c', .{ .ctrl = true })) {
break :outer; break;
} else if (key.matches('l', .{ .ctrl = true })) { } else if (key.matches('l', .{ .ctrl = true })) {
vx.queueRefresh(); vx.queueRefresh();
} else { } else {

View file

@ -3,52 +3,61 @@ const std = @import("std");
pub fn build(b: *std.Build) void { pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{}); const optimize = b.standardOptimizeOption(.{});
const root_source_file = std.Build.LazyPath.relative("src/main.zig");
const vaxis = b.addModule("vaxis", .{ .root_source_file = .{ .path = "src/main.zig" } }); // Dependencies
const ziglyph_dep = b.dependency("ziglyph", .{
const ziglyph = b.dependency("ziglyph", .{
.optimize = optimize, .optimize = optimize,
.target = target, .target = target,
}); });
vaxis.addImport("ziglyph", ziglyph.module("ziglyph")); const zigimg_dep = b.dependency("zigimg", .{
const zigimg = b.dependency("zigimg", .{
.optimize = optimize, .optimize = optimize,
.target = target, .target = target,
}); });
vaxis.addImport("zigimg", zigimg.module("zigimg"));
const exe = b.addExecutable(.{ // Module
.name = "vaxis", const vaxis_mod = b.addModule("vaxis", .{ .root_source_file = root_source_file });
.root_source_file = .{ .path = "examples/pathological.zig" }, vaxis_mod.addImport("ziglyph", ziglyph_dep.module("ziglyph"));
vaxis_mod.addImport("zigimg", zigimg_dep.module("zigimg"));
// Examples
const example_step = b.step("example", "Run examples");
const example = b.addExecutable(.{
.name = "vaxis_pathological_example",
.root_source_file = std.Build.LazyPath.relative("examples/pathological.zig"),
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
}); });
exe.root_module.addImport("vaxis", vaxis); example.root_module.addImport("vaxis", vaxis_mod);
const run_cmd = b.addRunArtifact(exe); const example_run = b.addRunArtifact(example);
example_step.dependOn(&example_run.step);
b.default_step.dependOn(example_step);
run_cmd.step.dependOn(b.getInstallStep()); // Tests
const tests_step = b.step("test", "Run tests");
if (b.args) |args| { const tests = b.addTest(.{
run_cmd.addArgs(args); .root_source_file = root_source_file,
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
// Creates a step for unit testing. This only builds the test executable
// but does not run it.
const lib_unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
}); });
lib_unit_tests.root_module.addImport("ziglyph", ziglyph.module("ziglyph")); tests.root_module.addImport("ziglyph", ziglyph_dep.module("ziglyph"));
lib_unit_tests.root_module.addImport("zigimg", zigimg.module("zigimg")); tests.root_module.addImport("zigimg", zigimg_dep.module("zigimg"));
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); const tests_run = b.addRunArtifact(tests);
tests_step.dependOn(&tests_run.step);
b.default_step.dependOn(tests_step);
const test_step = b.step("test", "Run unit tests"); // Lints
test_step.dependOn(&run_lib_unit_tests.step); const lints_step = b.step("lint", "Run lints");
const lints = b.addFmt(.{
.paths = &.{ "src", "build.zig" },
.check = true,
});
lints_step.dependOn(&lints.step);
b.default_step.dependOn(lints_step);
} }

View file

@ -1,36 +1,15 @@
.{ .{
.name = "vaxis", .name = "vaxis",
// This is a [Semantic Version](https://semver.org/).
// In a future version of Zig it will be used for package deduplication.
.version = "0.1.0", .version = "0.1.0",
.paths = .{""},
// This field is optional.
// This is currently advisory only; Zig does not yet do anything
// with this value.
//.minimum_zig_version = "0.11.0",
.dependencies = .{ .dependencies = .{
.ziglyph = .{ .ziglyph = .{
.url = "https://codeberg.org/dude_the_builder/ziglyph/archive/ac50ab06c91d2dd632ff4573c035dafe3b374aba.tar.gz", .url = "https://codeberg.org/dude_the_builder/ziglyph/archive/ac50ab06c9.tar.gz",
.hash = "1220e097fbfb3a15a6f3484cf507f1f10ab571d1bcf519c3b5447ca727782b7a5264", .hash = "1220e097fbfb3a15a6f3484cf507f1f10ab571d1bcf519c3b5447ca727782b7a5264",
},
.zigimg = .{
.url = "https://github.com/zigimg/zigimg/archive/2224f91.tar.gz",
.hash = "12207067e4892c48369415268648380859baa89c324748ae5bfda414a12868c9fc8b",
}, },
.zigimg = .{
.url = "https://github.com/zigimg/zigimg/archive/f6998808f283f8d3c2ef34e8b4af423bc1786f32.tar.gz",
.hash = "12202ee5d22ade0c300e9e7eae4c1951bda3d5f236fe1a139eb3613b43e2f12a88db",
}
},
.paths = .{
// This makes *all* files, recursively, included in this package. It is generally
// better to explicitly list the files and directories instead, to insure that
// fetching from tarballs, file system paths, and version control all result
// in the same contents hash.
"",
// For example...
//"build.zig",
//"build.zig.zon",
//"src",
//"LICENSE",
//"README.md",
}, },
} }

View file

@ -56,7 +56,7 @@ pub fn main() !void {
const img = imgs[n]; const img = imgs[n];
const dims = try img.cellSize(win); const dims = try img.cellSize(win);
const center = vaxis.alignment.center(win, dims.cols, dims.rows); const center = vaxis.widgets.alignment.center(win, dims.cols, dims.rows);
const scale = false; const scale = false;
const z_index = 0; const z_index = 0;
img.draw(center, scale, z_index); img.draw(center, scale, z_index);

View file

@ -32,11 +32,11 @@ pub fn main() !void {
// The main event loop. Vaxis provides a thread safe, blocking, buffered // The main event loop. Vaxis provides a thread safe, blocking, buffered
// queue which can serve as the primary event queue for an application // queue which can serve as the primary event queue for an application
outer: while (true) { while (true) {
// nextEvent blocks until an event is in the queue // nextEvent blocks until an event is in the queue
const event = vx.nextEvent(); const event = vx.nextEvent();
log.debug("event: {}\r\n", .{event}); log.debug("event: {}", .{event});
// exhaustive switching ftw. Vaxis will send events if your EventType // exhaustive switching ftw. Vaxis will send events if your Event
// enum has the fields for those events (ie "key_press", "winsize") // enum has the fields for those events (ie "key_press", "winsize")
switch (event) { switch (event) {
.key_press => |key| { .key_press => |key| {
@ -45,7 +45,7 @@ pub fn main() !void {
else => color_idx + 1, else => color_idx + 1,
}; };
if (key.codepoint == 'c' and key.mods.ctrl) { if (key.codepoint == 'c' and key.mods.ctrl) {
break :outer; break;
} }
}, },
.winsize => |ws| { .winsize => |ws| {
@ -87,7 +87,7 @@ pub fn main() !void {
} }
} }
// Our EventType. This can contain internal events as well as Vaxis events. // Our Event. This can contain internal events as well as Vaxis events.
// Internal events can be posted into the same queue as vaxis events to allow // Internal events can be posted into the same queue as vaxis events to allow
// for a single event loop with exhaustive switching. Booya // for a single event loop with exhaustive switching. Booya
const Event = union(enum) { const Event = union(enum) {

View file

@ -19,12 +19,12 @@ pub fn main() !void {
try vx.enterAltScreen(); try vx.enterAltScreen();
try vx.queryTerminal(); try vx.queryTerminal();
outer: while (true) { while (true) {
const event = vx.nextEvent(); const event = vx.nextEvent();
switch (event) { switch (event) {
.winsize => |ws| { .winsize => |ws| {
try vx.resize(alloc, ws); try vx.resize(alloc, ws);
break :outer; break;
}, },
} }
} }

View file

@ -6,7 +6,7 @@ const border = vaxis.widgets.border;
const log = std.log.scoped(.main); const log = std.log.scoped(.main);
// Our EventType. This can contain internal events as well as Vaxis events. // Our Event. This can contain internal events as well as Vaxis events.
// Internal events can be posted into the same queue as vaxis events to allow // Internal events can be posted into the same queue as vaxis events to allow
// for a single event loop with exhaustive switching. Booya // for a single event loop with exhaustive switching. Booya
const Event = union(enum) { const Event = union(enum) {
@ -59,11 +59,11 @@ pub fn main() !void {
// The main event loop. Vaxis provides a thread safe, blocking, buffered // The main event loop. Vaxis provides a thread safe, blocking, buffered
// queue which can serve as the primary event queue for an application // queue which can serve as the primary event queue for an application
outer: while (true) { while (true) {
// nextEvent blocks until an event is in the queue // nextEvent blocks until an event is in the queue
const event = vx.nextEvent(); const event = vx.nextEvent();
log.debug("event: {}\r\n", .{event}); log.debug("event: {}", .{event});
// exhaustive switching ftw. Vaxis will send events if your EventType // exhaustive switching ftw. Vaxis will send events if your Event
// enum has the fields for those events (ie "key_press", "winsize") // enum has the fields for those events (ie "key_press", "winsize")
switch (event) { switch (event) {
.key_press => |key| { .key_press => |key| {
@ -72,7 +72,7 @@ pub fn main() !void {
else => color_idx + 1, else => color_idx + 1,
}; };
if (key.matches('c', .{ .ctrl = true })) { if (key.matches('c', .{ .ctrl = true })) {
break :outer; break;
} else if (key.matches('l', .{ .ctrl = true })) { } else if (key.matches('l', .{ .ctrl = true })) {
vx.queueRefresh(); vx.queueRefresh();
} else if (key.matches('n', .{ .ctrl = true })) { } else if (key.matches('n', .{ .ctrl = true })) {

View file

@ -1,11 +1,9 @@
const Image = @import("Image.zig"); const Image = @import("Image.zig");
pub const Cell = struct { char: Character = .{},
char: Character = .{}, style: Style = .{},
style: Style = .{}, link: Hyperlink = .{},
link: Hyperlink = .{}, image: ?Image.Placement = null,
image: ?Image.Placement = null,
};
/// Segment is a contiguous run of text that has a constant style /// Segment is a contiguous run of text that has a constant style
pub const Segment = struct { pub const Segment = struct {
@ -17,7 +15,7 @@ pub const Segment = struct {
pub const Character = struct { pub const Character = struct {
grapheme: []const u8 = " ", grapheme: []const u8 = " ",
/// width should only be provided when the application is sure the terminal /// width should only be provided when the application is sure the terminal
/// will meeasure the same width. This can be ensure by using the gwidth method /// will measure the same width. This can be ensure by using the gwidth method
/// included in libvaxis. If width is 0, libvaxis will measure the glyph at /// included in libvaxis. If width is 0, libvaxis will measure the glyph at
/// render time /// render time
width: usize = 1, width: usize = 1,

View file

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const assert = std.debug.assert; const assert = std.debug.assert;
const Style = @import("cell.zig").Style; const Style = @import("Cell.zig").Style;
const Cell = @import("cell.zig").Cell; const Cell = @import("Cell.zig");
const Shape = @import("Mouse.zig").Shape; const Shape = @import("Mouse.zig").Shape;
const log = std.log.scoped(.internal_screen); const log = std.log.scoped(.internal_screen);

View file

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const assert = std.debug.assert; const assert = std.debug.assert;
const Cell = @import("cell.zig").Cell; const Cell = @import("Cell.zig");
const Shape = @import("Mouse.zig").Shape; const Shape = @import("Mouse.zig").Shape;
const Image = @import("Image.zig"); const Image = @import("Image.zig");
const Winsize = @import("Tty.zig").Winsize; const Winsize = @import("Tty.zig").Winsize;

View file

@ -1,11 +1,8 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const os = std.os; const os = std.os;
const vaxis = @import("main.zig"); const Vaxis = @import("vaxis.zig").Vaxis;
const Vaxis = vaxis.Vaxis;
const Event = @import("event.zig").Event;
const Parser = @import("Parser.zig"); const Parser = @import("Parser.zig");
const Key = vaxis.Key;
const GraphemeCache = @import("GraphemeCache.zig"); const GraphemeCache = @import("GraphemeCache.zig");
const log = std.log.scoped(.tty); const log = std.log.scoped(.tty);
@ -68,8 +65,8 @@ pub fn stop(self: *Tty) void {
/// read input from the tty /// read input from the tty
pub fn run( pub fn run(
self: *Tty, self: *Tty,
comptime EventType: type, comptime Event: type,
vx: *Vaxis(EventType), vx: *Vaxis(Event),
) !void { ) !void {
// create a pipe so we can signal to exit the run loop // create a pipe so we can signal to exit the run loop
const pipe = try os.pipe(); const pipe = try os.pipe();
@ -78,7 +75,7 @@ pub fn run(
// get our initial winsize // get our initial winsize
const winsize = try getWinsize(self.fd); const winsize = try getWinsize(self.fd);
if (@hasField(EventType, "winsize")) { if (@hasField(Event, "winsize")) {
vx.postEvent(.{ .winsize = winsize }); vx.postEvent(.{ .winsize = winsize });
} }
@ -91,10 +88,10 @@ pub fn run(
const WinchHandler = struct { const WinchHandler = struct {
const Self = @This(); const Self = @This();
var vx_winch: *Vaxis(EventType) = undefined; var vx_winch: *Vaxis(Event) = undefined;
var fd: os.fd_t = undefined; var fd: os.fd_t = undefined;
fn init(vx_arg: *Vaxis(EventType), fd_arg: os.fd_t) !void { fn init(vx_arg: *Vaxis(Event), fd_arg: os.fd_t) !void {
vx_winch = vx_arg; vx_winch = vx_arg;
fd = fd_arg; fd = fd_arg;
var act = os.Sigaction{ var act = os.Sigaction{
@ -114,7 +111,7 @@ pub fn run(
const ws = getWinsize(fd) catch { const ws = getWinsize(fd) catch {
return; return;
}; };
if (@hasField(EventType, "winsize")) { if (@hasField(Event, "winsize")) {
vx_winch.postEvent(.{ .winsize = ws }); vx_winch.postEvent(.{ .winsize = ws });
} }
} }
@ -156,7 +153,7 @@ pub fn run(
const event = result.event orelse continue; const event = result.event orelse continue;
switch (event) { switch (event) {
.key_press => |key| { .key_press => |key| {
if (@hasField(EventType, "key_press")) { if (@hasField(Event, "key_press")) {
// HACK: yuck. there has to be a better way // HACK: yuck. there has to be a better way
var mut_key = key; var mut_key = key;
if (key.text) |text| { if (key.text) |text| {
@ -166,27 +163,27 @@ pub fn run(
} }
}, },
.mouse => |mouse| { .mouse => |mouse| {
if (@hasField(EventType, "mouse")) { if (@hasField(Event, "mouse")) {
vx.postEvent(.{ .mouse = mouse }); vx.postEvent(.{ .mouse = mouse });
} }
}, },
.focus_in => { .focus_in => {
if (@hasField(EventType, "focus_in")) { if (@hasField(Event, "focus_in")) {
vx.postEvent(.focus_in); vx.postEvent(.focus_in);
} }
}, },
.focus_out => { .focus_out => {
if (@hasField(EventType, "focus_out")) { if (@hasField(Event, "focus_out")) {
vx.postEvent(.focus_out); vx.postEvent(.focus_out);
} }
}, },
.paste_start => { .paste_start => {
if (@hasField(EventType, "paste_start")) { if (@hasField(Event, "paste_start")) {
vx.postEvent(.paste_start); vx.postEvent(.paste_start);
} }
}, },
.paste_end => { .paste_end => {
if (@hasField(EventType, "paste_end")) { if (@hasField(Event, "paste_end")) {
vx.postEvent(.paste_end); vx.postEvent(.paste_end);
} }
}, },

View file

@ -4,8 +4,8 @@ const WordIterator = ziglyph.WordIterator;
const GraphemeIterator = ziglyph.GraphemeIterator; const GraphemeIterator = ziglyph.GraphemeIterator;
const Screen = @import("Screen.zig"); const Screen = @import("Screen.zig");
const Cell = @import("cell.zig").Cell; const Cell = @import("Cell.zig");
const Segment = @import("cell.zig").Segment; const Segment = @import("Cell.zig").Segment;
const gw = @import("gwidth.zig"); const gw = @import("gwidth.zig");
const log = std.log.scoped(.window); const log = std.log.scoped(.window);
@ -118,7 +118,7 @@ pub fn wrap(self: Window, segments: []Segment) !void {
var word_iter = try WordIterator.init(segment.text); var word_iter = try WordIterator.init(segment.text);
while (word_iter.next()) |word| { while (word_iter.next()) |word| {
// break lines when we need // break lines when we need
if (isLineBreak(word.bytes)) { if (word.bytes[0] == '\r' or word.bytes[0] == '\n') {
row += 1; row += 1;
col = 0; col = 0;
wrapped = false; wrapped = false;
@ -158,18 +158,6 @@ pub fn wrap(self: Window, segments: []Segment) !void {
} }
} }
fn isLineBreak(str: []const u8) bool {
if (std.mem.eql(u8, str, "\r\n")) {
return true;
} else if (std.mem.eql(u8, str, "\r")) {
return true;
} else if (std.mem.eql(u8, str, "\n")) {
return true;
} else {
return false;
}
}
test "Window size set" { test "Window size set" {
var parent = Window{ var parent = Window{
.x_off = 0, .x_off = 0,

View file

@ -1,40 +1,21 @@
const std = @import("std");
pub const Vaxis = @import("vaxis.zig").Vaxis; pub const Vaxis = @import("vaxis.zig").Vaxis;
pub const Options = @import("Options.zig"); pub const Options = @import("Options.zig");
const cell = @import("cell.zig");
pub const Cell = cell.Cell;
pub const Style = cell.Style;
pub const Segment = cell.Segment;
pub const Color = cell.Color;
pub const Key = @import("Key.zig"); pub const Key = @import("Key.zig");
pub const Cell = @import("Cell.zig");
pub const Image = @import("Image.zig");
pub const Mouse = @import("Mouse.zig"); pub const Mouse = @import("Mouse.zig");
pub const Winsize = @import("Tty.zig").Winsize; pub const Winsize = @import("Tty.zig").Winsize;
pub const widgets = @import("widgets/main.zig"); pub const widgets = @import("widgets.zig");
pub const alignment = widgets.alignment;
pub const border = widgets.border;
pub const Image = @import("Image.zig");
/// Initialize a Vaxis application. /// Initialize a Vaxis application.
pub fn init(comptime EventType: type, opts: Options) !Vaxis(EventType) { pub fn init(comptime Event: type, opts: Options) !Vaxis(Event) {
return Vaxis(EventType).init(opts); return Vaxis(Event).init(opts);
} }
test { test {
_ = @import("GraphemeCache.zig"); std.testing.refAllDecls(@This());
_ = @import("Key.zig");
_ = @import("Mouse.zig");
_ = @import("Options.zig");
_ = @import("Parser.zig");
_ = @import("Screen.zig");
_ = @import("Tty.zig");
_ = @import("Window.zig");
_ = @import("cell.zig");
_ = @import("ctlseqs.zig");
_ = @import("event.zig");
_ = @import("gwidth.zig");
_ = @import("queue.zig");
_ = @import("vaxis.zig");
} }

View file

@ -11,8 +11,8 @@ const Screen = @import("Screen.zig");
const InternalScreen = @import("InternalScreen.zig"); const InternalScreen = @import("InternalScreen.zig");
const Window = @import("Window.zig"); const Window = @import("Window.zig");
const Options = @import("Options.zig"); const Options = @import("Options.zig");
const Style = @import("cell.zig").Style; const Style = @import("Cell.zig").Style;
const Hyperlink = @import("cell.zig").Hyperlink; const Hyperlink = @import("Cell.zig").Hyperlink;
const gwidth = @import("gwidth.zig"); const gwidth = @import("gwidth.zig");
const Shape = @import("Mouse.zig").Shape; const Shape = @import("Mouse.zig").Shape;
const Image = @import("Image.zig"); const Image = @import("Image.zig");
@ -34,7 +34,7 @@ pub fn Vaxis(comptime T: type) type {
const log = std.log.scoped(.vaxis); const log = std.log.scoped(.vaxis);
pub const EventType = T; pub const Event = T;
pub const Capabilities = struct { pub const Capabilities = struct {
kitty_keyboard: bool = false, kitty_keyboard: bool = false,
@ -83,7 +83,7 @@ pub fn Vaxis(comptime T: type) type {
/// Initialize Vaxis with runtime options /// Initialize Vaxis with runtime options
pub fn init(_: Options) !Self { pub fn init(_: Options) !Self {
return Self{ return .{
.queue = .{}, .queue = .{},
.tty = null, .tty = null,
.screen = .{}, .screen = .{},
@ -151,7 +151,7 @@ pub fn Vaxis(comptime T: type) type {
self.queue.push(event); self.queue.push(event);
} }
/// resize allocates a slice of cellsequal to the number of cells /// resize allocates a slice of cells equal to the number of cells
/// required to display the screen (ie width x height). Any previous screen is /// required to display the screen (ie width x height). Any previous screen is
/// freed when resizing /// freed when resizing
pub fn resize(self: *Self, alloc: std.mem.Allocator, winsize: Winsize) !void { pub fn resize(self: *Self, alloc: std.mem.Allocator, winsize: Winsize) !void {
@ -169,7 +169,7 @@ pub fn Vaxis(comptime T: type) type {
/// returns a Window comprising of the entire terminal screen /// returns a Window comprising of the entire terminal screen
pub fn window(self: *Self) Window { pub fn window(self: *Self) Window {
return Window{ return .{
.x_off = 0, .x_off = 0,
.y_off = 0, .y_off = 0,
.width = self.screen.width, .width = self.screen.width,
@ -207,7 +207,7 @@ pub fn Vaxis(comptime T: type) type {
if (std.mem.eql(u8, colorterm, "truecolor") or if (std.mem.eql(u8, colorterm, "truecolor") or
std.mem.eql(u8, colorterm, "24bit")) std.mem.eql(u8, colorterm, "24bit"))
{ {
if (@hasField(EventType, "cap_rgb")) { if (@hasField(Event, "cap_rgb")) {
self.postEvent(.cap_rgb); self.postEvent(.cap_rgb);
} }
} }
@ -348,7 +348,7 @@ pub fn Vaxis(comptime T: type) type {
} }
} }
// something is different, so let's loop throuugh everything and // something is different, so let's loop through everything and
// find out what // find out what
// foreground // foreground
@ -642,7 +642,7 @@ pub fn Vaxis(comptime T: type) type {
} }
} }
try tty.buffered_writer.flush(); try tty.buffered_writer.flush();
return Image{ return .{
.id = id, .id = id,
.width = img.width, .width = img.width,
.height = img.height, .height = img.height,

3
src/widgets.zig Normal file
View file

@ -0,0 +1,3 @@
pub const border = @import("widgets/border.zig");
pub const alignment = @import("widgets/alignment.zig");
pub const TextInput = @import("widgets/TextInput.zig");

View file

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const Cell = @import("../cell.zig").Cell;
const Key = @import("../Key.zig"); const Key = @import("../Key.zig");
const Cell = @import("../Cell.zig");
const Window = @import("../Window.zig"); const Window = @import("../Window.zig");
const GraphemeIterator = @import("ziglyph").GraphemeIterator; const GraphemeIterator = @import("ziglyph").GraphemeIterator;

View file

@ -1,7 +1,8 @@
const Cell = @import("../Cell.zig");
const Window = @import("../Window.zig"); const Window = @import("../Window.zig");
const cell = @import("../cell.zig");
const Character = cell.Character; const Style = Cell.Style;
const Style = cell.Style; const Character = Cell.Character;
const horizontal = Character{ .grapheme = "", .width = 1 }; const horizontal = Character{ .grapheme = "", .width = 1 };
const vertical = Character{ .grapheme = "", .width = 1 }; const vertical = Character{ .grapheme = "", .width = 1 };

View file

@ -1,3 +0,0 @@
pub const TextInput = @import("TextInput.zig");
pub const border = @import("border.zig");
pub const alignment = @import("align.zig");