widgets(terminal): use buffered reader in parser
Use a buffered reader so we can inspect the read state. We need this to know if we have a finished read on a printable byte
This commit is contained in:
parent
9f2af4d5ee
commit
b688732f56
2 changed files with 15 additions and 8 deletions
|
@ -4,6 +4,7 @@ const Parser = @This();
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Reader = std.io.AnyReader;
|
const Reader = std.io.AnyReader;
|
||||||
const ansi = @import("ansi.zig");
|
const ansi = @import("ansi.zig");
|
||||||
|
const BufferedReader = std.io.BufferedReader(4096, std.io.AnyReader);
|
||||||
|
|
||||||
/// A terminal event
|
/// A terminal event
|
||||||
const Event = union(enum) {
|
const Event = union(enum) {
|
||||||
|
@ -21,7 +22,8 @@ buf: std.ArrayList(u8),
|
||||||
/// a leftover byte from a ground event
|
/// a leftover byte from a ground event
|
||||||
pending_byte: ?u8 = null,
|
pending_byte: ?u8 = null,
|
||||||
|
|
||||||
pub fn parseReader(self: *Parser, reader: Reader) !Event {
|
pub fn parseReader(self: *Parser, buffered: *BufferedReader) !Event {
|
||||||
|
const reader = buffered.reader().any();
|
||||||
self.buf.clearRetainingCapacity();
|
self.buf.clearRetainingCapacity();
|
||||||
while (true) {
|
while (true) {
|
||||||
const b = if (self.pending_byte) |p| p else try reader.readByte();
|
const b = if (self.pending_byte) |p| p else try reader.readByte();
|
||||||
|
@ -56,21 +58,27 @@ pub fn parseReader(self: *Parser, reader: Reader) !Event {
|
||||||
=> return .{ .c0 = @enumFromInt(b) },
|
=> return .{ .c0 = @enumFromInt(b) },
|
||||||
else => {
|
else => {
|
||||||
try self.buf.append(b);
|
try self.buf.append(b);
|
||||||
return self.parseGround(reader);
|
return self.parseGround(buffered);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn parseGround(self: *Parser, reader: Reader) !Event {
|
inline fn parseGround(self: *Parser, reader: *BufferedReader) !Event {
|
||||||
|
var buf: [1]u8 = undefined;
|
||||||
while (true) {
|
while (true) {
|
||||||
const b = try reader.readByte();
|
if (reader.start == reader.end) return .{ .print = self.buf.items };
|
||||||
|
const n = try reader.read(&buf);
|
||||||
|
if (n == 0) return error.EOF;
|
||||||
|
const b = buf[0];
|
||||||
switch (b) {
|
switch (b) {
|
||||||
0x00...0x1f => {
|
0x00...0x1f => {
|
||||||
self.pending_byte = b;
|
self.pending_byte = b;
|
||||||
return .{ .print = self.buf.items };
|
return .{ .print = self.buf.items };
|
||||||
},
|
},
|
||||||
else => try self.buf.append(b),
|
else => {
|
||||||
|
try self.buf.append(b);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,11 +251,10 @@ fn run(self: *Terminal) !void {
|
||||||
defer parser.buf.deinit();
|
defer parser.buf.deinit();
|
||||||
|
|
||||||
// Use our anyReader to make a buffered reader, then get *that* any reader
|
// Use our anyReader to make a buffered reader, then get *that* any reader
|
||||||
var buffered = std.io.bufferedReader(self.anyReader());
|
var reader = std.io.bufferedReader(self.anyReader());
|
||||||
const reader = buffered.reader().any();
|
|
||||||
|
|
||||||
while (!self.should_quit) {
|
while (!self.should_quit) {
|
||||||
const event = try parser.parseReader(reader);
|
const event = try parser.parseReader(&reader);
|
||||||
self.back_mutex.lock();
|
self.back_mutex.lock();
|
||||||
defer self.back_mutex.unlock();
|
defer self.back_mutex.unlock();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue