地圖 (Jido) is a lightweight Unix TUI file explorer designed for speed and simplicity.

fix: update majority of breaking changes from zig v0.14.0 -> v0.15.2 upgrade

+8 -10
src/app.zig
··· 94 94 pub fn deinit(self: @This(), alloc: std.mem.Allocator) void { 95 95 if (self.data) |data| { 96 96 var d = data; 97 - d.deinit(); 97 + d.deinit(alloc); 98 98 } 99 99 if (self.path) |path| alloc.free(path); 100 100 } ··· 108 108 alloc: std.mem.Allocator, 109 109 should_quit: bool, 110 110 vx: vaxis.Vaxis = undefined, 111 + tty_buffer: [1024]u8 = undefined, 111 112 tty: vaxis.Tty = undefined, 112 113 loop: vaxis.Loop(Event) = undefined, 113 114 state: State = .normal, ··· 149 150 .alloc = alloc, 150 151 .should_quit = false, 151 152 .vx = vx, 152 - .tty = try vaxis.Tty.init(), 153 153 .directories = try Directories.init(alloc, entry_dir), 154 154 .help_menu = help_menu, 155 - .text_input = vaxis.widgets.TextInput.init(alloc, &vx.unicode), 155 + .text_input = vaxis.widgets.TextInput.init(alloc), 156 156 .actions = CircStack(Action, actions_len).init(), 157 157 .last_known_height = vx.window().height, 158 158 .images = .{ .cache = .init(alloc) }, 159 159 }; 160 - 160 + app.tty = try vaxis.Tty.init(&app.tty_buffer); 161 161 app.loop = vaxis.Loop(Event){ 162 162 .vaxis = &app.vx, 163 163 .tty = &app.tty, ··· 191 191 self.help_menu.deinit(); 192 192 self.directories.deinit(); 193 193 self.text_input.deinit(); 194 - self.vx.deinit(self.alloc, self.tty.anyWriter()); 194 + self.vx.deinit(self.alloc, self.tty.writer()); 195 195 self.tty.deinit(); 196 196 if (self.file_logger) |file_logger| file_logger.deinit(); 197 197 ··· 222 222 try self.loop.start(); 223 223 defer self.loop.stop(); 224 224 225 - try self.vx.enterAltScreen(self.tty.anyWriter()); 226 - try self.vx.queryTerminal(self.tty.anyWriter(), 1 * std.time.ns_per_s); 225 + try self.vx.enterAltScreen(self.tty.writer()); 226 + try self.vx.queryTerminal(self.tty.writer(), 1 * std.time.ns_per_s); 227 227 self.vx.caps.kitty_graphics = true; 228 228 229 229 while (!self.should_quit) { ··· 248 248 249 249 try self.drawer.draw(self); 250 250 251 - var buffered = self.tty.bufferedWriter(); 252 - try self.vx.render(buffered.writer().any()); 253 - try buffered.flush(); 251 + try self.vx.render(self.tty.writer()); 254 252 } 255 253 256 254 if (config.empty_trash_on_exit) {
+17 -14
src/drawer.zig
··· 224 224 } else { 225 225 if (cache_entry.data == null) { 226 226 const path = try app.alloc.dupe(u8, self.current_item_path); 227 - processImage(app, path) catch break :unsupported; 227 + var buffer: [1024]u8 = undefined; 228 + processImage(app, path, &buffer) catch break :unsupported; 228 229 } 229 230 230 - if (app.vx.transmitImage(app.alloc, app.tty.anyWriter(), &cache_entry.data.?, .rgba)) |img| { 231 + if (app.vx.transmitImage(app.alloc, app.tty.writer(), &cache_entry.data.?, .rgba)) |img| { 231 232 img.draw(preview_win, .{ .scale = .contain }) catch |err| { 232 233 const message = try std.fmt.allocPrint(app.alloc, "Failed to draw image to screen - {}.", .{err}); 233 234 defer app.alloc.free(message); ··· 240 241 break :file; 241 242 }; 242 243 cache_entry.image = img; 243 - cache_entry.data.?.deinit(); 244 + cache_entry.data.?.deinit(app.alloc); 244 245 cache_entry.data = null; 245 246 } else |_| { 246 247 break :unsupported; ··· 250 251 break :file; 251 252 } else { 252 253 const path = try app.alloc.dupe(u8, self.current_item_path); 253 - processImage(app, path) catch break :unsupported; 254 + var buffer: [1024]u8 = undefined; 255 + processImage(app, path, &buffer) catch break :unsupported; 254 256 } 255 257 256 258 break :file; ··· 350 352 351 353 // Time created / last modified 352 354 if (self.verbose) lbl: { 353 - var maybe_meta: ?std.fs.File.Metadata = null; 355 + var maybe_meta: ?std.fs.File.Stat = null; 354 356 if (entry.kind == .directory) { 355 - maybe_meta = directories.dir.metadata() catch break :lbl; 357 + maybe_meta = directories.dir.stat() catch break :lbl; 356 358 } else if (entry.kind == .file) { 357 359 var file = directories.dir.openFile(entry.name, .{}) catch break :lbl; 358 - maybe_meta = file.metadata() catch break :lbl; 360 + maybe_meta = file.stat() catch break :lbl; 359 361 } 360 362 361 363 const meta = maybe_meta orelse break :lbl; ··· 365 367 defer local.deinit(); 366 368 367 369 const ctime_instant = zeit.instant(.{ 368 - .source = .{ .unix_nano = meta.created().? }, 370 + .source = .{ .unix_nano = meta.ctime }, 369 371 .timezone = &local, 370 372 }) catch break :lbl; 371 373 const ctime = ctime_instant.time(); 372 374 ctime.strftime(fbs.writer().any(), "Created: %Y-%m-%d %H:%M:%S\n") catch break :lbl; 373 375 374 376 const mtime_instant = zeit.instant(.{ 375 - .source = .{ .unix_nano = meta.modified() }, 377 + .source = .{ .unix_nano = meta.mtime }, 376 378 .timezone = &local, 377 379 }) catch break :lbl; 378 380 const mtime = mtime_instant.time(); ··· 441 443 442 444 break :lbl 0; 443 445 }; 444 - if (size) |s| try fbs.writer().print("{s}{:.2}\n", .{ 446 + if (size) |s| try fbs.writer().print("{s}{B:.2}\n", .{ 445 447 if (self.verbose) "Size: " else "", 446 - std.fmt.fmtIntSizeDec(s), 448 + s, 447 449 }); 448 450 449 451 // Extension. ··· 628 630 }, .{ .wrap = .word }); 629 631 } 630 632 631 - fn processImage(app: *App, path: []const u8) error{ Unsupported, OutOfMemory }!void { 633 + fn processImage(app: *App, path: []const u8, buffer: *[1024]u8) error{ Unsupported, OutOfMemory }!void { 632 634 app.images.cache.put(path, .{ .path = path, .status = .processing }) catch { 633 635 const message = try std.fmt.allocPrint(app.alloc, "Failed to load image '{s}' - error occurred while attempting to add image to cache.", .{path}); 634 636 defer app.alloc.free(message); ··· 640 642 const load_img_thread = std.Thread.spawn(.{}, loadImage, .{ 641 643 app, 642 644 path, 645 + buffer, 643 646 }) catch return error.Unsupported; 644 647 load_img_thread.detach(); 645 648 } 646 649 647 - fn loadImage(app: *App, path: []const u8) error{ Unsupported, OutOfMemory }!void { 648 - const data = vaxis.zigimg.Image.fromFilePath(app.alloc, path) catch { 650 + fn loadImage(app: *App, path: []const u8, buffer: *[1024]u8) error{ Unsupported, OutOfMemory }!void { 651 + const data = vaxis.zigimg.Image.fromFilePath(app.alloc, path, buffer) catch { 649 652 const message = try std.fmt.allocPrint(app.alloc, "Failed to load image '{s}' - error occurred while attempting to read image from path.", .{path}); 650 653 defer app.alloc.free(message); 651 654 app.notification.write(message, .err) catch {};
+3 -3
src/event_handlers.zig
··· 133 133 } 134 134 }, 135 135 .image_ready => {}, 136 - .winsize => |ws| try app.vx.resize(app.alloc, app.tty.anyWriter(), ws), 136 + .winsize => |ws| try app.vx.resize(app.alloc, app.tty.writer(), ws), 137 137 } 138 138 } 139 139 ··· 283 283 } 284 284 }, 285 285 .image_ready => {}, 286 - .winsize => |ws| try app.vx.resize(app.alloc, app.tty.anyWriter(), ws), 286 + .winsize => |ws| try app.vx.resize(app.alloc, app.tty.writer(), ws), 287 287 } 288 288 } 289 289 ··· 298 298 } 299 299 }, 300 300 .image_ready => {}, 301 - .winsize => |ws| try app.vx.resize(app.alloc, app.tty.anyWriter(), ws), 301 + .winsize => |ws| try app.vx.resize(app.alloc, app.tty.writer(), ws), 302 302 } 303 303 }
+4 -4
src/events.zig
··· 419 419 }, 420 420 .file => { 421 421 if (environment.getEditor()) |editor| { 422 - try app.vx.exitAltScreen(app.tty.anyWriter()); 423 - try app.vx.resetState(app.tty.anyWriter()); 422 + try app.vx.exitAltScreen(app.tty.writer()); 423 + try app.vx.resetState(app.tty.writer()); 424 424 app.loop.stop(); 425 425 426 426 environment.openFile(app.alloc, app.directories.dir, entry.name, editor) catch |err| { ··· 430 430 }; 431 431 432 432 try app.loop.start(); 433 - try app.vx.enterAltScreen(app.tty.anyWriter()); 434 - try app.vx.enableDetectedFeatures(app.tty.anyWriter()); 433 + try app.vx.enterAltScreen(app.tty.writer()); 434 + try app.vx.enableDetectedFeatures(app.tty.writer()); 435 435 app.vx.queueRefresh(); 436 436 } else { 437 437 app.notification.write("Can not open file - $EDITOR not set.", .warn) catch {};
+3 -1
src/file_logger.zig
··· 53 53 defer file.unlock(); 54 54 try file.seekFromEnd(0); 55 55 56 - try file.writer().print( 56 + var buffer: [1024]u8 = undefined; 57 + var file_writer = file.writer(&buffer).interface; 58 + try file_writer.print( 57 59 "({d}) {s}: {s}\n", 58 60 .{ std.time.timestamp(), LogLevel.toString(level), msg }, 59 61 );
+4 -4
src/list.zig
··· 12 12 pub fn init(alloc: std.mem.Allocator) Self { 13 13 return Self{ 14 14 .alloc = alloc, 15 - .items = std.ArrayList(T).init(alloc), 15 + .items = .empty, 16 16 .selected = 0, 17 17 }; 18 18 } 19 19 20 20 pub fn deinit(self: *Self) void { 21 - self.items.deinit(); 21 + self.items.deinit(self.alloc); 22 22 } 23 23 24 24 pub fn append(self: *Self, item: T) !void { 25 - try self.items.append(item); 25 + try self.items.append(self.alloc, item); 26 26 } 27 27 28 28 pub fn clear(self: *Self) void { 29 - self.items.clearAndFree(); 29 + self.items.clearAndFree(self.alloc); 30 30 self.selected = 0; 31 31 } 32 32
+6 -2
src/main.zig
··· 104 104 } 105 105 106 106 if (opts.version) { 107 - std.debug.print("jido v{}\n", .{options.version}); 107 + std.debug.print("jido v{f}\n", .{options.version}); 108 108 return; 109 109 } 110 110 ··· 151 151 // Must be printed after app has deinit as part of that process clears 152 152 // the screen. 153 153 if (last_dir) |path| { 154 - const stdout = std.io.getStdOut().writer(); 154 + var stdout_buffer: [std.fs.max_path_bytes]u8 = undefined; 155 + var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); 156 + const stdout = &stdout_writer.interface; 155 157 stdout.print("{s}\n", .{path}) catch {}; 158 + stdout.flush() catch {}; 159 + 156 160 alloc.free(path); 157 161 } 158 162 }