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

feat: File permissions are now displayed in the file information bar to the bottom of Jido.

+41 -5
+4
CHANGELOG.md
··· 1 # Changelog 2 3 ## v0.9.0 (2025-03-21) 4 - New Keybinds: 5 - Added keybind `<CTRL-r>` to reload config while Jido is running.
··· 1 # Changelog 2 3 + ## v0.9.1 (2025-03-23) 4 + - feat: File permissions are now displayed in the file information bar to the 5 + bottom of Jido. 6 + 7 ## v0.9.0 (2025-03-21) 8 - New Keybinds: 9 - Added keybind `<CTRL-r>` to reload config while Jido is running.
+1 -1
build.zig.zon
··· 1 .{ 2 .name = .jido, 3 .fingerprint = 0xee45eabe36cafb57, 4 - .version = "0.9.0", 5 .minimum_zig_version = "0.14.0", 6 7 .dependencies = .{
··· 1 .{ 2 .name = .jido, 3 .fingerprint = 0xee45eabe36cafb57, 4 + .version = "0.9.1", 5 .minimum_zig_version = "0.14.0", 6 7 .dependencies = .{
+36 -4
src/drawer.zig
··· 255 .{ directories.entries.selected + 1, directories.entries.len() }, 256 ); 257 258 if (entry.kind == .directory) { 259 _ = file_info_win.printSegment(.{ 260 .text = fbs.getWritten(), ··· 264 } 265 266 const file_size: u64 = lbl: { 267 - const formatted_size = directories.dir.statFile(entry.name) catch break :lbl 0; 268 - break :lbl formatted_size.size; 269 }; 270 271 const extension = std.fs.path.extension(entry.name); 272 if (extension.len > 0) try fbs.writer().print("{s} ", .{extension}); 273 - 274 - try fbs.writer().print("{:.2}", .{std.fmt.fmtIntSizeDec(file_size)}); 275 276 _ = file_info_win.printSegment(.{ 277 .text = fbs.getWritten(),
··· 255 .{ directories.entries.selected + 1, directories.entries.len() }, 256 ); 257 258 + var file_perm_buf: [11]u8 = undefined; 259 + const file_perms: ?usize = lbl: { 260 + var file_perm_fbs = std.io.fixedBufferStream(&file_perm_buf); 261 + 262 + if (entry.kind == .directory) { 263 + _ = try file_perm_fbs.write("d"); 264 + } 265 + 266 + const perm_strings = [_][]const u8{ 267 + "---", "--x", "-w-", "-wx", 268 + "r--", "r-x", "rw-", "rwx", 269 + }; 270 + 271 + const stat = directories.dir.statFile(entry.name) catch break :lbl null; 272 + // Ignore upper bytes as they represent file type. 273 + const perms = @as(u9, @truncate(stat.mode)); 274 + 275 + for (0..3) |group| { 276 + const shift: u4 = @truncate((2 - group) * 3); // Extract from left to right 277 + const perm = @as(u3, @truncate((perms >> shift) & 0b111)); 278 + _ = try file_perm_fbs.write(perm_strings[perm]); 279 + } 280 + 281 + _ = try file_perm_fbs.write(" "); 282 + 283 + if (entry.kind == .directory) { 284 + break :lbl 11; 285 + } else { 286 + break :lbl 10; 287 + } 288 + }; 289 + if (file_perms) |perms_bytes| try fbs.writer().writeAll(file_perm_buf[0..perms_bytes]); 290 + 291 if (entry.kind == .directory) { 292 _ = file_info_win.printSegment(.{ 293 .text = fbs.getWritten(), ··· 297 } 298 299 const file_size: u64 = lbl: { 300 + const stat = directories.dir.statFile(entry.name) catch break :lbl 0; 301 + break :lbl stat.size; 302 }; 303 + try fbs.writer().print("{:.2} ", .{std.fmt.fmtIntSizeDec(file_size)}); 304 305 const extension = std.fs.path.extension(entry.name); 306 if (extension.len > 0) try fbs.writer().print("{s} ", .{extension}); 307 308 _ = file_info_win.printSegment(.{ 309 .text = fbs.getWritten(),