···66const Event = @import("event.zig").Event;
77const parser = @import("parser.zig");
88const Key = vaxis.Key;
99+const GraphemeCache = @import("GraphemeCache.zig");
9101011const log = std.log.scoped(.tty);
1112···112113 };
113114 try WinchHandler.init(vx, self.fd);
114115116116+ // initialize a grapheme cache
117117+ var cache: GraphemeCache = .{};
118118+115119 // Set up fds for polling
116120 var pollfds: [2]std.os.pollfd = .{
117121 .{ .fd = self.fd, .events = std.os.POLL.IN, .revents = undefined },
···132136 var start: usize = 0;
133137 while (start < n) {
134138 const result = try parser.parse(buf[start..n]);
135135- start = result.n;
139139+ start += result.n;
136140 // TODO: if we get 0 byte read, copy the remaining bytes to the
137141 // beginning of the buffer and read mmore? this should only happen
138142 // if we are in the middle of a grapheme at and filled our
···143147 switch (event) {
144148 .key_press => |key| {
145149 if (@hasField(EventType, "key_press")) {
146146- vx.postEvent(.{ .key_press = key });
150150+ // HACK: yuck. there has to be a better way
151151+ var mut_key = key;
152152+ if (key.text) |text| {
153153+ mut_key.text = cache.put(text);
154154+ }
155155+ vx.postEvent(.{ .key_press = mut_key });
147156 }
148157 },
149158 .focus_in => {
···99const Window = @import("Window.zig");
1010const Options = @import("Options.zig");
1111const Style = @import("cell.zig").Style;
1212-const GraphemeCache = @import("GraphemeCache.zig");
13121413/// Vaxis is the entrypoint for a Vaxis application. The provided type T should
1514/// be a tagged union which contains all of the events the application will
···4645 // statistics
4746 renders: usize = 0,
4847 render_dur: i128 = 0,
4949-5050- // grapheme cache
5151- g_cache: GraphemeCache = .{},
52485349 /// Initialize Vaxis with runtime options
5450 pub fn init(_: Options) !Self {