Andrea Feletto: 1 draw both source and target for symlinks 4 files changed, 41 insertions(+), 5 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~leon_plickat/nfm/patches/36330/mbox | git am -3Learn more about email & git
--- src/Dir.zig | 9 +++++++++ src/DirMap.zig | 14 ++++++++++++++ src/File.zig | 13 +++++++++---- src/UserInterface.zig | 10 +++++++++- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/Dir.zig b/src/Dir.zig index 376cb66..ab59f27 100644 --- a/src/Dir.zig +++ b/src/Dir.zig @@ -52,6 +52,15 @@ pub fn init(self: *Self, map: *DirMap, alloc: mem.Allocator, dir: fs.Dir, name: file.kind = entry.kind; file.mark = false; file.text = null; + + if (file.kind == .SymLink) { + var buf: [1024]u8 = undefined; + const target_path = try dir.readLink(entry.name, &buf); + file.target_path = try alloc.dupeZ(u8, target_path); + } else { + file.target_path = try alloc.dupeZ(u8, ""); + } +
* This should probably live inside of File.updateStats(). * The target of a link can change, so check if file.target_path already has a string and free that. * Should probably be nullable for the above point. * Rename target_path to link_target.
file.id = map.genId(); file.updateStats(); } diff --git a/src/DirMap.zig b/src/DirMap.zig index 64336b1..4f3d5ef 100644 --- a/src/DirMap.zig +++ b/src/DirMap.zig @@ -489,8 +489,22 @@ fn addNewFileToDir(self: *Self, dir: *Dir, name: []const u8) !void { .id = self.genId(), .stat = undefined, .kind = undefined, + .lstat = undefined, + .target_path = undefined,
Since we get the target path with dir.readLink(), we don't need lstat anymore, I think.
}; f.updateStats(); + + if (f.kind == .SymLink) { + var fs_dir = try fs.openDirAbsolute(dir.name, .{}); + defer fs_dir.close(); + + var buf: [1024]u8 = undefined; + const target_path = try fs_dir.readLink(name, &buf); + f.target_path = try alloc.dupeZ(u8, target_path); + } else { + f.target_path = try alloc.dupeZ(u8, ""); + } +
Can be removed if this logic is moved to File.updateStats().
try dir.files.append(alloc, f); // If the dir is visible, we need to update the DirView. diff --git a/src/File.zig b/src/File.zig index 385ec23..360e604 100644 --- a/src/File.zig +++ b/src/File.zig @@ -37,21 +37,25 @@ text: ?bool, id: usize, stat: os.system.Stat, +// usefull only if kind == .SymLink +lstat: os.system.Stat, +target_path: [:0]const u8, + pub fn updateStats(self: *Self) void { if (self.dir.visible and context.dirmap.dirViewByDir(self.dir) == context.dirmap.focusedDirView().?) { // The file is in our current cwd. _ = os.system.stat(self.name, &self.stat); - self.kind = fileKindFromStatMode(self.stat.mode); - self.text = null; + _ = os.system.lstat(self.name, &self.lstat); } else { var buf: [1024]u8 = undefined; var fba = heap.FixedBufferAllocator.init(buf[0..]); const falloc = fba.allocator(); const path = fmt.allocPrintZ(falloc, "{s}/{s}", .{ self.dir.name, self.name }) catch return; _ = os.system.stat(path, &self.stat); - self.kind = fileKindFromStatMode(self.stat.mode); - self.text = null; + _ = os.system.lstat(path, &self.lstat); } + self.kind = fileKindFromStatMode(self.lstat.mode); + self.text = null; } fn fileKindFromStatMode(mode: u32) fs.Dir.Entry.Kind { @@ -71,6 +75,7 @@ fn fileKindFromStatMode(mode: u32) fs.Dir.Entry.Kind { pub fn deinit(self: *const Self) void { const alloc = context.gpa.allocator(); alloc.free(self.name); + alloc.free(self.target_path); } pub fn rename(self: *Self, new_name: []const u8) !void { diff --git a/src/UserInterface.zig b/src/UserInterface.zig index 32c7c96..c07c891 100644 --- a/src/UserInterface.zig +++ b/src/UserInterface.zig @@ -509,7 +509,15 @@ fn drawFileName(_: *Self, rc: *spoon.Term.RenderContext, y: usize, x: usize, _wi var rpw = rc.restrictedPaddingWriter(width); const writer = rpw.writer(); try writer.writeAll(prefix); - try writer.writeAll(file.name); + if (file.kind == .SymLink) { + if (file.name.len + " -> ".len + file.target_path.len < try rpw.getRemaining()) {
You can get roughly the same result a bit simpler by just checking if the combined lengths are longer than the width variable. Friendly greetings, Leon Henrik Plickat
+ try writer.print("{s} -> {s}", .{ file.name, file.target_path }); + } else { + try writer.print("-> {s}", .{file.target_path}); + } + } else { + try writer.writeAll(file.name); + } if (file.kind == .Directory) { try writer.writeByte('/'); } -- 2.38.1
Thanks for working on this! Managed to find some review time today already.