widgets(terminal): read full codepoints

Only read full codepoints. Some programs will split codepoints between
reads, which can mess with our parser (looking at you, btop)
This commit is contained in:
Tim Culverhouse 2024-06-11 13:59:07 -05:00
parent eeb69f012a
commit 37b0d5c69d

View file

@ -66,6 +66,17 @@ pub fn parseReader(self: *Parser, buffered: *BufferedReader) !Event {
inline fn parseGround(self: *Parser, reader: *BufferedReader) !Event { inline fn parseGround(self: *Parser, reader: *BufferedReader) !Event {
var buf: [1]u8 = undefined; var buf: [1]u8 = undefined;
{
std.debug.assert(self.buf.items.len > 0);
// Handle first byte
const len = try std.unicode.utf8ByteSequenceLength(self.buf.items[0]);
var i: usize = 1;
while (i < len) : (i += 1) {
const read = try reader.read(&buf);
if (read == 0) return error.EOF;
try self.buf.append(buf[0]);
}
}
while (true) { while (true) {
if (reader.start == reader.end) return .{ .print = self.buf.items }; if (reader.start == reader.end) return .{ .print = self.buf.items };
const n = try reader.read(&buf); const n = try reader.read(&buf);
@ -78,6 +89,14 @@ inline fn parseGround(self: *Parser, reader: *BufferedReader) !Event {
}, },
else => { else => {
try self.buf.append(b); try self.buf.append(b);
const len = try std.unicode.utf8ByteSequenceLength(b);
var i: usize = 1;
while (i < len) : (i += 1) {
const read = try reader.read(&buf);
if (read == 0) return error.EOF;
try self.buf.append(buf[0]);
}
}, },
} }
} }