Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/widgets.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ pub const CodeView = @import("widgets/CodeView.zig");
pub const Terminal = @import("widgets/terminal/Terminal.zig");
pub const TextInput = @import("widgets/TextInput.zig");
pub const View = @import("widgets/View.zig");

test {
const std = @import("std");
std.testing.refAllDecls(TextView);
}
88 changes: 69 additions & 19 deletions src/widgets/TextView.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,56 @@ const Grapheme = struct {
};

pub const BufferWriter = struct {
pub const Error = error{OutOfMemory};
pub const Writer = std.io.GenericWriter(@This(), Error, write);
pub const Writer = std.Io.Writer;
pub const Error = Writer.Error;

const vtable: std.Io.Writer.VTable = .{
.drain = drain,
.sendFile = std.Io.Writer.unimplementedSendFile,
.flush = std.Io.Writer.noopFlush,
.rebase = noopRebase,
};

allocator: std.mem.Allocator,
buffer: *Buffer,
fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
std.debug.assert(data.len != 0);

pub fn write(self: @This(), bytes: []const u8) Error!usize {
try self.buffer.append(self.allocator, .{
.bytes = bytes,
});
return bytes.len;
const bw: *BufferWriter = @fieldParentPtr("writer", w);
const start_len = bw.writer.end;

for (data) |bytes| {
bw.buffer.append(bw.gpa, .{ .bytes = bytes }) catch return Error.WriteFailed;
bw.writer.end += bytes.len;
}

const pattern = data[data.len - 1];
if (splat > 1) {
for (0..splat - 1) |_| {
bw.writer.end += pattern.len;
bw.buffer.append(bw.gpa, .{ .bytes = pattern }) catch return Error.WriteFailed;
}
}
return bw.writer.end - start_len;
}

fn noopRebase(w: *Writer, preserve: usize, minimum_len: usize) Error!void {
_ = w;
_ = preserve;
_ = minimum_len;
}

pub fn writer(self: @This()) Writer {
return .{ .context = self };
gpa: std.mem.Allocator,
buffer: *Buffer,
writer: Writer,

pub fn init(gpa: std.mem.Allocator, buffer: *Buffer) BufferWriter {
return .{
.gpa = gpa,
.buffer = buffer,
.writer = .{
.buffer = &.{},
.vtable = &vtable,
},
};
}
};

Expand Down Expand Up @@ -160,14 +195,9 @@ pub const Buffer = struct {

pub fn writer(
self: *@This(),
allocator: std.mem.Allocator,
) BufferWriter.Writer {
return .{
.context = .{
.allocator = allocator,
.buffer = self,
},
};
gpa: std.mem.Allocator,
) BufferWriter {
return .init(gpa, self);
}
};

Expand Down Expand Up @@ -222,3 +252,23 @@ pub fn draw(self: *@This(), win: vaxis.Window, buffer: Buffer) void {
});
}
}

const testing = std.testing;

test BufferWriter {
const gpa = testing.allocator;

var buffer: Buffer = .{};
defer buffer.deinit(gpa);

var buffer_writer: BufferWriter = buffer.writer(gpa);
const writer = &buffer_writer.writer;

try writer.print("hello\n", .{});
try writer.print("world!\n", .{});
try writer.print("{d}\n", .{42});

try testing.expectEqualStrings("hello\nworld!\n42\n", buffer.content.items);
try testing.expectEqual(3, buffer.rows);
try testing.expectEqual(6, buffer.cols);
}
Loading