地圖 (Jido) is a lightweight Unix TUI file explorer designed for speed and simplicity.
at main 108 lines 2.9 kB view raw
1const std = @import("std"); 2const builtin = @import("builtin"); 3 4const zuid = @import("zuid"); 5 6pub fn getHomeDir() !?std.fs.Dir { 7 return try std.fs.openDirAbsolute(std.posix.getenv("HOME") orelse { 8 return null; 9 }, .{ .iterate = true }); 10} 11 12pub fn getXdgConfigHomeDir() !?std.fs.Dir { 13 return try std.fs.openDirAbsolute(std.posix.getenv("XDG_CONFIG_HOME") orelse { 14 return null; 15 }, .{ .iterate = true }); 16} 17 18pub fn getEditor() ?[]const u8 { 19 const editor = std.posix.getenv("EDITOR"); 20 if (editor) |e| { 21 if (std.mem.trim(u8, e, " ").len > 0) { 22 return e; 23 } 24 } 25 return null; 26} 27 28pub fn checkDuplicatePath( 29 buf: []u8, 30 dir: std.fs.Dir, 31 relative_path: []const u8, 32) error{NoSpaceLeft}!struct { 33 path: []const u8, 34 had_duplicate: bool, 35} { 36 var had_duplicate = false; 37 const new_path = if (fileExists(dir, relative_path)) lbl: { 38 had_duplicate = true; 39 const extension = std.fs.path.extension(relative_path); 40 break :lbl try std.fmt.bufPrint( 41 buf, 42 "{s}-{f}{s}", 43 .{ relative_path[0 .. relative_path.len - extension.len], zuid.new.v4(), extension }, 44 ); 45 } else lbl: { 46 break :lbl try std.fmt.bufPrint(buf, "{s}", .{relative_path}); 47 }; 48 49 return .{ .path = new_path, .had_duplicate = had_duplicate }; 50} 51 52pub fn openFile( 53 alloc: std.mem.Allocator, 54 dir: std.fs.Dir, 55 file: []const u8, 56 editor: []const u8, 57) !void { 58 var path_buf: [std.fs.max_path_bytes]u8 = undefined; 59 const path = try dir.realpath(file, &path_buf); 60 61 var child = std.process.Child.init(&.{ editor, path }, alloc); 62 _ = try child.spawnAndWait(); 63} 64 65pub fn fileExists(dir: std.fs.Dir, path: []const u8) bool { 66 const result = blk: { 67 _ = dir.openFile(path, .{}) catch |err| { 68 switch (err) { 69 error.FileNotFound => break :blk false, 70 else => { 71 std.log.info("{}", .{err}); 72 break :blk true; 73 }, 74 } 75 }; 76 break :blk true; 77 }; 78 return result; 79} 80 81pub fn dirExists(dir: std.fs.Dir, path: []const u8) bool { 82 const result = blk: { 83 _ = dir.openDir(path, .{}) catch |err| { 84 switch (err) { 85 error.FileNotFound => break :blk false, 86 else => { 87 std.log.info("{}", .{err}); 88 break :blk true; 89 }, 90 } 91 }; 92 break :blk true; 93 }; 94 return result; 95} 96 97///Deletes the contents of a directory but not the directory itself. 98///Returns the amount of files failed to be delete. 99pub fn deleteContents(dir: std.fs.Dir) !usize { 100 var failed: usize = 0; 101 var it = dir.iterate(); 102 while (try it.next()) |entry| { 103 dir.deleteTree(entry.name) catch { 104 failed += 1; 105 }; 106 } 107 return failed; 108}