this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

embed std.io.Writer in WindowsTty with 4096-byte buffer

Apply the same Writer API integration to WindowsTty that was done for
PosixTty. This provides consistent buffered writing capabilities across
both Windows and POSIX platforms using Zig 0.15.1's new Writer API.

The embedded writer uses @fieldParentPtr to access the parent WindowsTty
instance from the drain function, enabling efficient writes to the
Windows console handle when the buffer is full or flushed.

Add write() method and update opaqueWrite() to use the embedded writer
instead of direct windows.WriteFile() calls, providing automatic
buffering for better performance by reducing system call overhead.

Amp-Thread-ID: https://ampcode.com/threads/T-e1192d32-b3c3-43a6-b434-33fe5664bf0a
Co-authored-by: Amp <amp@ampcode.com>

+58 -6
+58 -6
src/tty.zig
··· 267 267 // a buffer to write key text into 268 268 buf: [4]u8 = undefined, 269 269 270 + /// Write buffer 271 + buffer: [4096]u8, 272 + 273 + /// Embedded writer 274 + writer: std.io.Writer, 275 + 270 276 /// The last mouse button that was pressed. We store the previous state of button presses on each 271 277 /// mouse event so we can detect which button was released 272 278 last_mouse_button_press: u16 = 0, 273 279 280 + /// VTable for embedded writer 281 + const vtable = std.io.Writer.VTable{ 282 + .drain = drainVTable, 283 + }; 284 + 285 + fn drainVTable(w: *std.io.Writer, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { 286 + const self: *WindowsTty = @fieldParentPtr("writer", w); 287 + 288 + // First write any buffered data 289 + if (w.end > 0) { 290 + _ = windows.WriteFile(self.stdout, w.buffer[0..w.end], null) catch return error.WriteFailed; 291 + w.end = 0; 292 + } 293 + 294 + // Write each slice in data 295 + var total: usize = 0; 296 + for (data[0..data.len-1]) |slice| { 297 + const n = windows.WriteFile(self.stdout, slice, null) catch return error.WriteFailed; 298 + total += n; 299 + } 300 + 301 + // Write the last slice `splat` times 302 + const pattern = data[data.len - 1]; 303 + for (0..splat) |_| { 304 + const n = windows.WriteFile(self.stdout, pattern, null) catch return error.WriteFailed; 305 + total += n; 306 + } 307 + 308 + return total; 309 + } 310 + 274 311 const utf8_codepage: c_uint = 65001; 275 312 276 313 /// The input mode set by init ··· 303 340 if (windows.kernel32.SetConsoleOutputCP(utf8_codepage) == 0) 304 341 return windows.unexpectedError(windows.kernel32.GetLastError()); 305 342 306 - const self: Tty = .{ 343 + var self: Tty = .{ 307 344 .stdin = stdin, 308 345 .stdout = stdout, 309 346 .initial_codepage = initial_output_codepage, 310 347 .initial_input_mode = initial_input_mode, 311 348 .initial_output_mode = initial_output_mode, 349 + .buffer = undefined, 350 + .writer = undefined, // Will be set after self is created 351 + }; 352 + 353 + // Initialize the writer to use our embedded buffer 354 + self.writer = .{ 355 + .vtable = &vtable, 356 + .buffer = &self.buffer, 357 + .end = 0, 312 358 }; 313 359 314 360 // save a copy of this tty as the global_tty for panic handling ··· 363 409 }; 364 410 } 365 411 412 + /// Write bytes to the tty 413 + pub fn write(self: *Tty, bytes: []const u8) !usize { 414 + return self.writer.write(bytes); 415 + } 416 + 366 417 pub fn opaqueWrite(ptr: *const anyopaque, bytes: []const u8) !usize { 367 - const self: *const Tty = @ptrCast(@alignCast(ptr)); 368 - return windows.WriteFile(self.stdout, bytes, null); 418 + const self: *Tty = @ptrCast(@alignCast(ptr)); 419 + return self.writer.write(bytes); 369 420 } 370 421 371 - pub fn anyWriter(self: *const Tty) std.io.AnyWriter { 422 + pub fn anyWriter(self: *Tty) std.io.AnyWriter { 372 423 return .{ 373 424 .context = self, 374 425 .writeFn = Tty.opaqueWrite, 375 426 }; 376 427 } 377 428 378 - pub fn bufferedWriter(self: *const Tty) std.io.BufferedWriter(4096, std.io.AnyWriter) { 379 - return std.io.bufferedWriter(self.anyWriter()); 429 + pub fn bufferedWriter(self: *Tty) *std.io.Writer { 430 + // The embedded writer is already buffered with a 4096-byte buffer 431 + return &self.writer; 380 432 } 381 433 382 434 pub fn nextEvent(self: *Tty, parser: *Parser, paste_allocator: ?std.mem.Allocator) !Event {