地圖 (Jido) is a lightweight Unix TUI file explorer designed for speed and simplicity.
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}