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