a modern tui library written in zig

refactor: rename anyWriter() to writer()

Now that the writer interfaces are no longer generic, the anyWriter term does not
make sense. This commit renames it to just writer() to match idiomatic zig usage.

authored by neurocyte.flow-control.dev and committed by rockorager.dev 3bf62964 2cbb665c

+5 -5
README.md
··· 297 297 var vx = try vaxis.init(alloc, .{}); 298 298 // deinit takes an optional allocator. If your program is exiting, you can 299 299 // choose to pass a null allocator to save some exit time. 300 - defer vx.deinit(alloc, tty.anyWriter()); 300 + defer vx.deinit(alloc, tty.writer()); 301 301 302 302 303 303 // The event loop requires an intrusive init. We create an instance with ··· 317 317 defer loop.stop(); 318 318 319 319 // Optionally enter the alternate screen 320 - try vx.enterAltScreen(tty.anyWriter()); 320 + try vx.enterAltScreen(tty.writer()); 321 321 322 322 // We'll adjust the color index every keypress for the border 323 323 var color_idx: u8 = 0; ··· 329 329 330 330 // Sends queries to terminal to detect certain features. This should always 331 331 // be called after entering the alt screen, if you are using the alt screen 332 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 332 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 333 333 334 334 while (true) { 335 335 // nextEvent blocks until an event is in the queue ··· 365 365 // more than one byte will incur an allocation on the first render 366 366 // after it is drawn. Thereafter, it will not allocate unless the 367 367 // screen is resized 368 - .winsize => |ws| try vx.resize(alloc, tty.anyWriter(), ws), 368 + .winsize => |ws| try vx.resize(alloc, tty.writer(), ws), 369 369 else => {}, 370 370 } 371 371 ··· 401 401 402 402 // Render the screen. Using a buffered writer will offer much better 403 403 // performance, but is not required 404 - try vx.render(tty.anyWriter()); 404 + try vx.render(tty.writer()); 405 405 } 406 406 } 407 407 ```
+2 -2
USAGE.md
··· 247 247 self.vx.caps.color_scheme_updates = true; 248 248 }, 249 249 .cap_da1 => { 250 - self.vx.enableDetectedFeatures(self.tty.anyWriter()) catch |err| { 250 + self.vx.enableDetectedFeatures(self.tty.writer()) catch |err| { 251 251 log.err("couldn't enable features: {}", .{err}); 252 252 }; 253 253 }, ··· 328 328 } 329 329 330 330 pub fn deinit(self: *@This(), vx: *vaxis.Vaxis, tty: *vaxis.Tty) void { 331 - vx.deviceStatusReport(tty.anyWriter()) catch {}; 331 + vx.deviceStatusReport(tty.writer()) catch {}; 332 332 if (self.winsize_task) |task| task.cancel(); 333 333 if (self.reader_task) |task| task.cancel(); 334 334 self.source.deinit();
+4 -4
examples/cli.zig
··· 19 19 defer tty.deinit(); 20 20 21 21 var vx = try vaxis.init(alloc, .{}); 22 - defer vx.deinit(alloc, tty.anyWriter()); 22 + defer vx.deinit(alloc, tty.writer()); 23 23 24 24 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 25 25 try loop.init(); ··· 27 27 try loop.start(); 28 28 defer loop.stop(); 29 29 30 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 30 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 31 31 32 32 var text_input = TextInput.init(alloc, &vx.unicode); 33 33 defer text_input.deinit(); ··· 75 75 } 76 76 }, 77 77 .winsize => |ws| { 78 - try vx.resize(alloc, tty.anyWriter(), ws); 78 + try vx.resize(alloc, tty.writer(), ws); 79 79 }, 80 80 else => {}, 81 81 } ··· 96 96 _ = win.print(&seg, .{ .row_offset = @intCast(j + 1) }); 97 97 } 98 98 } 99 - try vx.render(tty.anyWriter()); 99 + try vx.render(tty.writer()); 100 100 } 101 101 } 102 102
+10 -10
examples/image.zig
··· 23 23 defer tty.deinit(); 24 24 25 25 var vx = try vaxis.init(alloc, .{}); 26 - defer vx.deinit(alloc, tty.anyWriter()); 26 + defer vx.deinit(alloc, tty.writer()); 27 27 28 28 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 29 29 try loop.init(); ··· 31 31 try loop.start(); 32 32 defer loop.stop(); 33 33 34 - try vx.enterAltScreen(tty.anyWriter()); 35 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 34 + try vx.enterAltScreen(tty.writer()); 35 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 36 36 37 37 var read_buffer: [1024 * 1024]u8 = undefined; // 1MB buffer 38 38 var img1 = try vaxis.zigimg.Image.fromFilePath(alloc, "examples/zig.png", &read_buffer); 39 39 defer img1.deinit(); 40 40 41 41 const imgs = [_]vaxis.Image{ 42 - try vx.transmitImage(alloc, tty.anyWriter(), &img1, .rgba), 42 + try vx.transmitImage(alloc, tty.writer(), &img1, .rgba), 43 43 // var img1 = try vaxis.zigimg.Image.fromFilePath(alloc, "examples/zig.png"); 44 - // try vx.loadImage(alloc, tty.anyWriter(), .{ .path = "examples/zig.png" }), 45 - try vx.loadImage(alloc, tty.anyWriter(), .{ .path = "examples/vaxis.png" }), 44 + // try vx.loadImage(alloc, tty.writer(), .{ .path = "examples/zig.png" }), 45 + try vx.loadImage(alloc, tty.writer(), .{ .path = "examples/vaxis.png" }), 46 46 }; 47 - defer vx.freeImage(tty.anyWriter(), imgs[0].id); 48 - defer vx.freeImage(tty.anyWriter(), imgs[1].id); 47 + defer vx.freeImage(tty.writer(), imgs[0].id); 48 + defer vx.freeImage(tty.writer(), imgs[1].id); 49 49 50 50 var n: usize = 0; 51 51 ··· 64 64 else if (key.matches('k', .{})) 65 65 clip_y -|= 1; 66 66 }, 67 - .winsize => |ws| try vx.resize(alloc, tty.anyWriter(), ws), 67 + .winsize => |ws| try vx.resize(alloc, tty.writer(), ws), 68 68 } 69 69 70 70 n = (n + 1) % imgs.len; ··· 78 78 .y = clip_y, 79 79 } }); 80 80 81 - try vx.render(tty.anyWriter()); 81 + try vx.render(tty.writer()); 82 82 } 83 83 }
+5 -5
examples/main.zig
··· 19 19 defer tty.deinit(); 20 20 21 21 var vx = try vaxis.init(alloc, .{}); 22 - defer vx.deinit(alloc, tty.anyWriter()); 22 + defer vx.deinit(alloc, tty.writer()); 23 23 24 24 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 25 25 try loop.init(); ··· 28 28 defer loop.stop(); 29 29 30 30 // Optionally enter the alternate screen 31 - try vx.enterAltScreen(tty.anyWriter()); 32 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 31 + try vx.enterAltScreen(tty.writer()); 32 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 33 33 34 34 // We'll adjust the color index every keypress 35 35 var color_idx: u8 = 0; ··· 66 66 } 67 67 }, 68 68 .winsize => |ws| { 69 - try vx.resize(alloc, tty.anyWriter(), ws); 69 + try vx.resize(alloc, tty.writer(), ws); 70 70 }, 71 71 else => {}, 72 72 } ··· 114 114 child.writeCell(@intCast(i), scale, second_cell); 115 115 } 116 116 // Render the screen 117 - try vx.render(tty.anyWriter()); 117 + try vx.render(tty.writer()); 118 118 } 119 119 } 120 120
+5 -5
examples/table.zig
··· 30 30 var buffer: [1024]u8 = undefined; 31 31 var tty = try vaxis.Tty.init(&buffer); 32 32 defer tty.deinit(); 33 - const tty_writer = tty.anyWriter(); 33 + const tty_writer = tty.writer(); 34 34 var vx = try vaxis.init(alloc, .{ 35 35 .kitty_keyboard_flags = .{ .report_events = true }, 36 36 }); 37 - defer vx.deinit(alloc, tty.anyWriter()); 37 + defer vx.deinit(alloc, tty.writer()); 38 38 39 39 var loop: vaxis.Loop(union(enum) { 40 40 key_press: vaxis.Key, ··· 44 44 try loop.init(); 45 45 try loop.start(); 46 46 defer loop.stop(); 47 - try vx.enterAltScreen(tty.anyWriter()); 48 - try vx.queryTerminal(tty.anyWriter(), 250 * std.time.ns_per_ms); 47 + try vx.enterAltScreen(tty.writer()); 48 + try vx.queryTerminal(tty.writer(), 250 * std.time.ns_per_ms); 49 49 50 50 const logo = 51 51 \\░█░█░█▀█░█░█░▀█▀░█▀▀░░░▀█▀░█▀█░█▀▄░█░░░█▀▀░ ··· 191 191 } 192 192 moving = false; 193 193 }, 194 - .winsize => |ws| try vx.resize(alloc, tty.anyWriter(), ws), 194 + .winsize => |ws| try vx.resize(alloc, tty.writer(), ws), 195 195 else => {}, 196 196 } 197 197
+6 -6
examples/text_input.zig
··· 36 36 37 37 // Use a buffered writer for better performance. There are a lot of writes 38 38 // in the render loop and this can have a significant savings 39 - const writer = tty.anyWriter(); 39 + const writer = tty.writer(); 40 40 41 41 // Initialize Vaxis 42 42 var vx = try vaxis.init(alloc, .{ 43 43 .kitty_keyboard_flags = .{ .report_events = true }, 44 44 }); 45 - defer vx.deinit(alloc, tty.anyWriter()); 45 + defer vx.deinit(alloc, tty.writer()); 46 46 47 47 var loop: vaxis.Loop(Event) = .{ 48 48 .vaxis = &vx, ··· 71 71 try writer.flush(); 72 72 // Sends queries to terminal to detect certain features. This should 73 73 // _always_ be called, but is left to the application to decide when 74 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 74 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 75 75 76 76 // The main event loop. Vaxis provides a thread safe, blocking, buffered 77 77 // queue which can serve as the primary event queue for an application ··· 92 92 } else if (key.matches('l', .{ .ctrl = true })) { 93 93 vx.queueRefresh(); 94 94 } else if (key.matches('n', .{ .ctrl = true })) { 95 - try vx.notify(tty.anyWriter(), "vaxis", "hello from vaxis"); 95 + try vx.notify(tty.writer(), "vaxis", "hello from vaxis"); 96 96 loop.stop(); 97 97 var child = std.process.Child.init(&.{"nvim"}, alloc); 98 98 _ = try child.spawnAndWait(); 99 99 try loop.start(); 100 - try vx.enterAltScreen(tty.anyWriter()); 100 + try vx.enterAltScreen(tty.writer()); 101 101 vx.queueRefresh(); 102 102 } else if (key.matches(vaxis.Key.enter, .{}) or key.matches('j', .{ .ctrl = true })) { 103 103 text_input.clearAndFree(); ··· 121 121 // more than one byte will incur an allocation on the first render 122 122 // after it is drawn. Thereafter, it will not allocate unless the 123 123 // screen is resized 124 - .winsize => |ws| try vx.resize(alloc, tty.anyWriter(), ws), 124 + .winsize => |ws| try vx.resize(alloc, tty.writer(), ws), 125 125 else => {}, 126 126 } 127 127
+8 -8
examples/vaxis.zig
··· 25 25 defer tty.deinit(); 26 26 27 27 var vx = try vaxis.init(alloc, .{}); 28 - defer vx.deinit(alloc, tty.anyWriter()); 28 + defer vx.deinit(alloc, tty.writer()); 29 29 30 30 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 31 31 try loop.init(); ··· 33 33 try loop.start(); 34 34 defer loop.stop(); 35 35 36 - try vx.enterAltScreen(tty.anyWriter()); 37 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 36 + try vx.enterAltScreen(tty.writer()); 37 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 38 38 39 - try vx.queryColor(tty.anyWriter(), .fg); 40 - try vx.queryColor(tty.anyWriter(), .bg); 39 + try vx.queryColor(tty.writer(), .fg); 40 + try vx.queryColor(tty.writer(), .bg); 41 41 var pct: u8 = 0; 42 42 var dir: enum { 43 43 up, ··· 53 53 switch (event) { 54 54 .key_press => |key| if (key.matches('c', .{ .ctrl = true })) return, 55 55 .winsize => |ws| { 56 - try vx.resize(alloc, tty.anyWriter(), ws); 56 + try vx.resize(alloc, tty.writer(), ws); 57 57 break; 58 58 }, 59 59 } ··· 63 63 while (loop.tryEvent()) |event| { 64 64 switch (event) { 65 65 .key_press => |key| if (key.matches('c', .{ .ctrl = true })) return, 66 - .winsize => |ws| try vx.resize(alloc, tty.anyWriter(), ws), 66 + .winsize => |ws| try vx.resize(alloc, tty.writer(), ws), 67 67 } 68 68 } 69 69 ··· 83 83 // var bw = tty.bufferedWriter(); 84 84 // try vx.render(bw.writer().any()); 85 85 // try bw.flush(); 86 - try vx.render(tty.anyWriter()); 86 + try vx.render(tty.writer()); 87 87 std.Thread.sleep(16 * std.time.ns_per_ms); 88 88 switch (dir) { 89 89 .up => {
+4 -4
examples/view.zig
··· 48 48 var tty = try vaxis.Tty.init(&buffer); 49 49 defer tty.deinit(); 50 50 51 - const writer = tty.anyWriter(); 51 + const writer = tty.writer(); 52 52 53 53 // Initialize Vaxis 54 54 var vx = try vaxis.init(alloc, .{ 55 55 .kitty_keyboard_flags = .{ .report_events = true }, 56 56 }); 57 - defer vx.deinit(alloc, tty.anyWriter()); 57 + defer vx.deinit(alloc, tty.writer()); 58 58 var loop: vaxis.Loop(Event) = .{ 59 59 .vaxis = &vx, 60 60 .tty = &tty, ··· 64 64 defer loop.stop(); 65 65 try vx.enterAltScreen(writer); 66 66 try writer.flush(); 67 - try vx.queryTerminal(tty.anyWriter(), 20 * std.time.ns_per_s); 67 + try vx.queryTerminal(tty.writer(), 20 * std.time.ns_per_s); 68 68 69 69 // Initialize Views 70 70 // - Large Map ··· 128 128 // Mini View (Forced Width & Height Limits) 129 129 if (key.matches('m', .{})) use_mini_view = !use_mini_view; 130 130 }, 131 - .winsize => |ws| try vx.resize(alloc, tty.anyWriter(), ws), 131 + .winsize => |ws| try vx.resize(alloc, tty.writer(), ws), 132 132 } 133 133 134 134 const win = vx.window();
+4 -4
examples/vt.zig
··· 23 23 var buffer: [1024]u8 = undefined; 24 24 var tty = try vaxis.Tty.init(&buffer); 25 25 var vx = try vaxis.init(alloc, .{}); 26 - defer vx.deinit(alloc, tty.anyWriter()); 26 + defer vx.deinit(alloc, tty.writer()); 27 27 28 28 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 29 29 try loop.init(); ··· 33 33 34 34 var buffered = tty.bufferedWriter(); 35 35 36 - try vx.enterAltScreen(tty.anyWriter()); 37 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 36 + try vx.enterAltScreen(tty.writer()); 37 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 38 38 var env = try std.process.getEnvMap(alloc); 39 39 defer env.deinit(); 40 40 ··· 82 82 try vt.update(.{ .key_press = key }); 83 83 }, 84 84 .winsize => |ws| { 85 - try vx.resize(alloc, tty.anyWriter(), ws); 85 + try vx.resize(alloc, tty.writer(), ws); 86 86 }, 87 87 } 88 88 }
+4 -4
src/Loop.zig
··· 58 58 if (self.thread == null) return; 59 59 self.should_quit = true; 60 60 // trigger a read 61 - self.vaxis.deviceStatusReport(self.tty.anyWriter()) catch {}; 61 + self.vaxis.deviceStatusReport(self.tty.writer()) catch {}; 62 62 63 63 if (self.thread) |thread| { 64 64 thread.join(); ··· 398 398 defer tty.deinit(); 399 399 400 400 var vx = try vaxis.init(std.testing.allocator, .{}); 401 - defer vx.deinit(std.testing.allocator, tty.anyWriter()); 401 + defer vx.deinit(std.testing.allocator, tty.writer()); 402 402 403 403 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 404 404 try loop.init(); ··· 407 407 defer loop.stop(); 408 408 409 409 // Optionally enter the alternate screen 410 - try vx.enterAltScreen(tty.anyWriter()); 411 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_ms); 410 + try vx.enterAltScreen(tty.writer()); 411 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_ms); 412 412 }
+1 -1
src/main.zig
··· 73 73 ctlseqs.bp_reset ++ 74 74 ctlseqs.rmcup; 75 75 76 - gty.anyWriter().writeAll(reset) catch {}; 76 + gty.writer().writeAll(reset) catch {}; 77 77 78 78 gty.deinit(); 79 79 }
+13 -13
src/tty.zig
··· 36 36 reader: std.fs.File.Reader, 37 37 38 38 /// File.Writer for efficient buffered writing 39 - writer: std.fs.File.Writer, 39 + tty_writer: std.fs.File.Writer, 40 40 41 41 pub const SignalHandler = struct { 42 42 context: *anyopaque, ··· 77 77 .fd = fd, 78 78 .termios = termios, 79 79 .reader = file.reader(buffer), 80 - .writer = .initStreaming(file, buffer), 80 + .tty_writer = .initStreaming(file, buffer), 81 81 }; 82 82 83 83 global_tty = self; ··· 109 109 posix.sigaction(posix.SIG.WINCH, &act, null); 110 110 } 111 111 112 - pub fn anyWriter(self: *PosixTty) *std.Io.Writer { 113 - return &self.writer.interface; 112 + pub fn writer(self: *PosixTty) *std.Io.Writer { 113 + return &self.tty_writer.interface; 114 114 } 115 115 116 116 pub fn read(self: *const PosixTty, buf: []u8) !usize { ··· 202 202 203 203 /// File.Writer for efficient buffered writing 204 204 reader: std.fs.File.Writer, 205 - writer: std.fs.File.Writer, 205 + tty_writer: std.fs.File.Writer, 206 206 207 207 /// The last mouse button that was pressed. We store the previous state of button presses on each 208 208 /// mouse event so we can detect which button was released ··· 301 301 }; 302 302 } 303 303 304 - pub fn anyWriter(self: *Tty) *std.Io.Writer { 305 - return &self.writer.interface; 304 + pub fn writer(self: *Tty) *std.Io.Writer { 305 + return &self.tty_writer.interface; 306 306 } 307 307 308 308 pub fn read(self: *const Tty, buf: []u8) !usize { ··· 699 699 fd: posix.fd_t, 700 700 pipe_read: posix.fd_t, 701 701 pipe_write: posix.fd_t, 702 - writer: *std.Io.Writer.Allocating, 702 + tty_writer: *std.Io.Writer.Allocating, 703 703 704 704 /// Initializes a TestTty. 705 705 pub fn init(buffer: []u8) !TestTty { ··· 713 713 .fd = r, 714 714 .pipe_read = r, 715 715 .pipe_write = w, 716 - .writer = list, 716 + .tty_writer = list, 717 717 }; 718 718 } 719 719 720 720 pub fn deinit(self: TestTty) void { 721 721 std.posix.close(self.pipe_read); 722 722 std.posix.close(self.pipe_write); 723 - self.writer.deinit(); 724 - std.testing.allocator.destroy(self.writer); 723 + self.tty_writer.deinit(); 724 + std.testing.allocator.destroy(self.tty_writer); 725 725 } 726 726 727 - pub fn anyWriter(self: *TestTty) *std.Io.Writer { 728 - return &self.writer.writer; 727 + pub fn writer(self: *TestTty) *std.Io.Writer { 728 + return &self.tty_writer.writer; 729 729 } 730 730 731 731 pub fn read(self: *const TestTty, buf: []u8) !usize {
+12 -12
src/vxfw/App.zig
··· 47 47 48 48 pub fn deinit(self: *App) void { 49 49 self.timers.deinit(self.allocator); 50 - self.vx.deinit(self.allocator, self.tty.anyWriter()); 50 + self.vx.deinit(self.allocator, self.tty.writer()); 51 51 self.tty.deinit(); 52 52 } 53 53 ··· 64 64 // Also always initialize the app with a focus event 65 65 loop.postEvent(.focus_in); 66 66 67 - try vx.enterAltScreen(tty.anyWriter()); 68 - try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 69 - try vx.setBracketedPaste(tty.anyWriter(), true); 70 - try vx.subscribeToColorSchemeUpdates(tty.anyWriter()); 67 + try vx.enterAltScreen(tty.writer()); 68 + try vx.queryTerminal(tty.writer(), 1 * std.time.ns_per_s); 69 + try vx.setBracketedPaste(tty.writer(), true); 70 + try vx.subscribeToColorSchemeUpdates(tty.writer()); 71 71 72 72 { 73 73 // This part deserves a comment. loop.init installs a signal handler for the tty. We wait to ··· 78 78 79 79 // NOTE: We don't use pixel mouse anywhere 80 80 vx.caps.sgr_pixels = false; 81 - try vx.setMouseMode(tty.anyWriter(), true); 81 + try vx.setMouseMode(tty.writer(), true); 82 82 83 83 // Give DrawContext the unicode data 84 84 vxfw.DrawContext.init(&vx.unicode, vx.screen.width_method); ··· 149 149 }, 150 150 .mouse => |mouse| try mouse_handler.handleMouse(self, &ctx, mouse), 151 151 .winsize => |ws| { 152 - try vx.resize(self.allocator, tty.anyWriter(), ws); 152 + try vx.resize(self.allocator, tty.writer(), ws); 153 153 ctx.redraw = true; 154 154 }, 155 155 else => { ··· 246 246 }); 247 247 surface.render(root_win, focused_widget); 248 248 249 - try vx.render(tty.anyWriter()); 249 + try vx.render(tty.writer()); 250 250 } 251 251 252 252 fn addTick(self: *App, tick: vxfw.Tick) Allocator.Error!void { ··· 262 262 .set_mouse_shape => |shape| self.vx.setMouseShape(shape), 263 263 .request_focus => |widget| self.wants_focus = widget, 264 264 .copy_to_clipboard => |content| { 265 - self.vx.copyToSystemClipboard(self.tty.anyWriter(), content, self.allocator) catch |err| { 265 + self.vx.copyToSystemClipboard(self.tty.writer(), content, self.allocator) catch |err| { 266 266 switch (err) { 267 267 error.OutOfMemory => return Allocator.Error.OutOfMemory, 268 268 else => std.log.err("copy error: {}", .{err}), ··· 270 270 }; 271 271 }, 272 272 .set_title => |title| { 273 - self.vx.setTitle(self.tty.anyWriter(), title) catch |err| { 273 + self.vx.setTitle(self.tty.writer(), title) catch |err| { 274 274 std.log.err("set_title error: {}", .{err}); 275 275 }; 276 276 }, 277 277 .queue_refresh => self.vx.queueRefresh(), 278 278 .notify => |notification| { 279 - self.vx.notify(self.tty.anyWriter(), notification.title, notification.body) catch |err| { 279 + self.vx.notify(self.tty.writer(), notification.title, notification.body) catch |err| { 280 280 std.log.err("notify error: {}", .{err}); 281 281 }; 282 282 const alloc = self.allocator; ··· 286 286 alloc.free(notification.body); 287 287 }, 288 288 .query_color => |kind| { 289 - self.vx.queryColor(self.tty.anyWriter(), kind) catch |err| { 289 + self.vx.queryColor(self.tty.writer(), kind) catch |err| { 290 290 std.log.err("queryColor error: {}", .{err}); 291 291 }; 292 292 },
+16 -14
src/widgets/terminal/Terminal.zig
··· 241 241 242 242 pub fn update(self: *Terminal, event: InputEvent) !void { 243 243 switch (event) { 244 - .key_press => |k| try key.encode(self.anyWriter(), k, true, self.back_screen.csi_u_flags), 244 + .key_press => |k| try key.encode(self.writer(), k, true, self.back_screen.csi_u_flags), 245 245 } 246 246 } 247 247 ··· 250 250 return posix.write(self.pty.pty, buf); 251 251 } 252 252 253 - pub fn anyWriter(self: *const Terminal) *std.io.Writer { 254 - const writer: std.io.Writer = .{ 255 - .context = self, 256 - .writeFn = Terminal.opaqueWrite, 253 + pub fn writer(self: *const Terminal) *std.io.Writer { 254 + const local = struct { 255 + var writer: std.io.Writer = .{ 256 + .context = self, 257 + .writeFn = Terminal.opaqueWrite, 258 + }; 257 259 }; 258 - return @constCast(&writer); 260 + return &local.writer; 259 261 } 260 262 261 263 fn opaqueRead(ptr: *const anyopaque, buf: []u8) !usize { ··· 521 523 if (seq.private_marker) |pm| { 522 524 switch (pm) { 523 525 // Secondary 524 - '>' => try self.anyWriter().writeAll("\x1B[>1;69;0c"), 525 - '=' => try self.anyWriter().writeAll("\x1B[=0000c"), 526 + '>' => try self.writer().writeAll("\x1B[>1;69;0c"), 527 + '=' => try self.writer().writeAll("\x1B[=0000c"), 526 528 else => log.info("unhandled CSI: {}", .{seq}), 527 529 } 528 530 } else { 529 531 // Primary 530 - try self.anyWriter().writeAll("\x1B[?62;22c"); 532 + try self.writer().writeAll("\x1B[?62;22c"); 531 533 } 532 534 }, 533 535 // Cursor Vertical Position Absolute ··· 592 594 const ps = iter.next() orelse 0; 593 595 if (seq.intermediate == null and seq.private_marker == null) { 594 596 switch (ps) { 595 - 5 => try self.anyWriter().writeAll("\x1b[0n"), 596 - 6 => try self.anyWriter().print("\x1b[{d};{d}R", .{ 597 + 5 => try self.writer().writeAll("\x1b[0n"), 598 + 6 => try self.writer().print("\x1b[{d};{d}R", .{ 597 599 self.back_screen.cursor.row + 1, 598 600 self.back_screen.cursor.col + 1, 599 601 }), ··· 609 611 // report mode 610 612 '$' => { 611 613 switch (ps) { 612 - 2026 => try self.anyWriter().writeAll("\x1b[?2026;2$p"), 614 + 2026 => try self.writer().writeAll("\x1b[?2026;2$p"), 613 615 else => { 614 616 std.log.warn("unhandled mode: {}", .{ps}); 615 - try self.anyWriter().print("\x1b[?{d};0$p", .{ps}); 617 + try self.writer().print("\x1b[?{d};0$p", .{ps}); 616 618 }, 617 619 } 618 620 }, ··· 634 636 if (seq.private_marker) |pm| { 635 637 switch (pm) { 636 638 // XTVERSION 637 - '>' => try self.anyWriter().print( 639 + '>' => try self.writer().print( 638 640 "\x1bP>|libvaxis {s}\x1B\\", 639 641 .{"dev"}, 640 642 ),