ls but with io_uring

feature: support listing multiple directories #14

merged opened by themackabu.dev targeting main

meow

Labels

None yet.

Participants 2
AT URI
at://did:plc:ud7nokqso5d6ao46ao6nlsu6/sh.tangled.repo.pull/3lu7hos47pg22
+72 -44
Diff #0
+72 -44
src/main.zig
··· 9 10 const usage = 11 \\Usage: 12 - \\ lsr [options] [path] 13 \\ 14 \\ --help Print this message and exit 15 \\ --version Print the version string ··· 43 sort_by_mod_time: bool = false, 44 reverse_sort: bool = false, 45 46 - directory: [:0]const u8 = ".", 47 file: ?[]const u8 = null, 48 49 winsize: ?posix.winsize = null, ··· 253 } 254 }, 255 .positional => { 256 - cmd.opts.directory = arg; 257 }, 258 } 259 } ··· 262 cmd.opts.colors = .default; 263 } 264 265 - var ring: ourio.Ring = try .init(allocator, queue_size); 266 - defer ring.deinit(); 267 268 - _ = try ring.open(cmd.opts.directory, .{ .DIRECTORY = true, .CLOEXEC = true }, 0, .{ 269 - .ptr = &cmd, 270 - .cb = onCompletion, 271 - .msg = @intFromEnum(Msg.cwd), 272 - }); 273 274 - if (cmd.opts.long) { 275 - _ = try ring.open("/etc/localtime", .{ .CLOEXEC = true }, 0, .{ 276 - .ptr = &cmd, 277 - .cb = onCompletion, 278 - .msg = @intFromEnum(Msg.localtime), 279 - }); 280 - _ = try ring.open("/etc/passwd", .{ .CLOEXEC = true }, 0, .{ 281 - .ptr = &cmd, 282 - .cb = onCompletion, 283 - .msg = @intFromEnum(Msg.passwd), 284 - }); 285 - _ = try ring.open("/etc/group", .{ .CLOEXEC = true }, 0, .{ 286 .ptr = &cmd, 287 .cb = onCompletion, 288 - .msg = @intFromEnum(Msg.group), 289 }); 290 - } 291 292 - try ring.run(.until_done); 293 294 - if (cmd.entries.len == 0) return; 295 296 - std.sort.pdq(Entry, cmd.entries, cmd.opts, Entry.lessThan); 297 298 - if (cmd.opts.reverse_sort) { 299 - std.mem.reverse(Entry, cmd.entries); 300 - } 301 302 - if (cmd.opts.long) { 303 - try printLong(cmd, bw.writer()); 304 - } else switch (cmd.opts.shortview) { 305 - .columns => try printShortColumns(cmd, bw.writer()), 306 - .oneline => try printShortOnePerLine(cmd, bw.writer()), 307 } 308 try bw.flush(); 309 } ··· 420 } 421 422 if (opts.useHyperlinks()) { 423 - const path = try std.fs.path.join(cmd.arena, &.{ opts.directory, entry.name }); 424 try writer.print("\x1b]8;;file://{s}\x1b\\", .{path}); 425 try writer.writeAll(entry.name); 426 try writer.writeAll("\x1b]8;;\x1b\\"); ··· 562 } 563 564 if (cmd.opts.useHyperlinks()) { 565 - const path = try std.fs.path.join(cmd.arena, &.{ cmd.opts.directory, entry.name }); 566 try writer.print("\x1b]8;;file://{s}\x1b\\", .{path}); 567 try writer.writeAll(entry.name); 568 try writer.writeAll("\x1b]8;;\x1b\\"); ··· 606 entries: []Entry = &.{}, 607 entry_idx: usize = 0, 608 symlinks: std.StringHashMapUnmanaged(Symlink) = .empty, 609 610 tz: ?zeit.TimeZone = null, 611 groups: std.ArrayListUnmanaged(Group) = .empty, ··· 786 787 // if the user specified a file (or something that couldn't be opened as a 788 // directory), then we open it's parent and apply a filter 789 - const dirname = std.fs.path.dirname(cmd.opts.directory) orelse "."; 790 - cmd.opts.file = std.fs.path.basename(cmd.opts.directory); 791 - cmd.opts.directory = try cmd.arena.dupeZ(u8, dirname); 792 _ = try io.open( 793 - cmd.opts.directory, 794 .{ .DIRECTORY = true, .CLOEXEC = true }, 795 0, 796 .{ ··· 811 if (cmd.opts.useHyperlinks()) { 812 var buf: [std.fs.max_path_bytes]u8 = undefined; 813 const cwd = try std.os.getFdPath(fd, &buf); 814 - cmd.opts.directory = try cmd.arena.dupeZ(u8, cwd); 815 } 816 817 var temp_results: std.ArrayListUnmanaged(MinimalEntry) = .empty; ··· 873 } 874 const path = try std.fs.path.joinZ( 875 cmd.arena, 876 - &.{ cmd.opts.directory, entry.name }, 877 ); 878 879 if (entry.kind == .sym_link) { ··· 1040 cmd.entry_idx += 1; 1041 const path = try std.fs.path.joinZ( 1042 cmd.arena, 1043 - &.{ cmd.opts.directory, entry.name }, 1044 ); 1045 1046 if (entry.kind == .sym_link) {
··· 9 10 const usage = 11 \\Usage: 12 + \\ lsr [options] [path...] 13 \\ 14 \\ --help Print this message and exit 15 \\ --version Print the version string ··· 43 sort_by_mod_time: bool = false, 44 reverse_sort: bool = false, 45 46 + directories: std.ArrayListUnmanaged([:0]const u8) = .empty, 47 file: ?[]const u8 = null, 48 49 winsize: ?posix.winsize = null, ··· 253 } 254 }, 255 .positional => { 256 + try cmd.opts.directories.append(allocator, arg); 257 }, 258 } 259 } ··· 262 cmd.opts.colors = .default; 263 } 264 265 + if (cmd.opts.directories.items.len == 0) { 266 + try cmd.opts.directories.append(allocator, "."); 267 + } 268 269 + const multiple_dirs = cmd.opts.directories.items.len > 1; 270 271 + for (cmd.opts.directories.items, 0..) |directory, dir_idx| { 272 + cmd.entries = &.{}; 273 + cmd.entry_idx = 0; 274 + cmd.symlinks.clearRetainingCapacity(); 275 + cmd.groups.clearRetainingCapacity(); 276 + cmd.users.clearRetainingCapacity(); 277 + cmd.tz = null; 278 + cmd.opts.file = null; 279 + cmd.current_directory = directory; 280 + 281 + var ring: ourio.Ring = try .init(allocator, queue_size); 282 + defer ring.deinit(); 283 + 284 + _ = try ring.open(directory, .{ .DIRECTORY = true, .CLOEXEC = true }, 0, .{ 285 .ptr = &cmd, 286 .cb = onCompletion, 287 + .msg = @intFromEnum(Msg.cwd), 288 }); 289 290 + if (cmd.opts.long) { 291 + _ = try ring.open("/etc/localtime", .{ .CLOEXEC = true }, 0, .{ 292 + .ptr = &cmd, 293 + .cb = onCompletion, 294 + .msg = @intFromEnum(Msg.localtime), 295 + }); 296 + _ = try ring.open("/etc/passwd", .{ .CLOEXEC = true }, 0, .{ 297 + .ptr = &cmd, 298 + .cb = onCompletion, 299 + .msg = @intFromEnum(Msg.passwd), 300 + }); 301 + _ = try ring.open("/etc/group", .{ .CLOEXEC = true }, 0, .{ 302 + .ptr = &cmd, 303 + .cb = onCompletion, 304 + .msg = @intFromEnum(Msg.group), 305 + }); 306 + } 307 + 308 + try ring.run(.until_done); 309 310 + if (cmd.entries.len == 0) { 311 + if (multiple_dirs and dir_idx < cmd.opts.directories.items.len - 1) { 312 + try bw.writer().writeAll("\r\n"); 313 + } 314 + continue; 315 + } 316 317 + std.sort.pdq(Entry, cmd.entries, cmd.opts, Entry.lessThan); 318 319 + if (cmd.opts.reverse_sort) { 320 + std.mem.reverse(Entry, cmd.entries); 321 + } 322 323 + if (multiple_dirs) { 324 + if (dir_idx > 0) try bw.writer().writeAll("\r\n"); 325 + try bw.writer().print("{s}:\r\n", .{directory}); 326 + } 327 + 328 + if (cmd.opts.long) { 329 + try printLong(cmd, bw.writer()); 330 + } else switch (cmd.opts.shortview) { 331 + .columns => try printShortColumns(cmd, bw.writer()), 332 + .oneline => try printShortOnePerLine(cmd, bw.writer()), 333 + } 334 } 335 try bw.flush(); 336 } ··· 447 } 448 449 if (opts.useHyperlinks()) { 450 + const path = try std.fs.path.join(cmd.arena, &.{ cmd.current_directory, entry.name }); 451 try writer.print("\x1b]8;;file://{s}\x1b\\", .{path}); 452 try writer.writeAll(entry.name); 453 try writer.writeAll("\x1b]8;;\x1b\\"); ··· 589 } 590 591 if (cmd.opts.useHyperlinks()) { 592 + const path = try std.fs.path.join(cmd.arena, &.{ cmd.current_directory, entry.name }); 593 try writer.print("\x1b]8;;file://{s}\x1b\\", .{path}); 594 try writer.writeAll(entry.name); 595 try writer.writeAll("\x1b]8;;\x1b\\"); ··· 633 entries: []Entry = &.{}, 634 entry_idx: usize = 0, 635 symlinks: std.StringHashMapUnmanaged(Symlink) = .empty, 636 + current_directory: [:0]const u8 = ".", 637 638 tz: ?zeit.TimeZone = null, 639 groups: std.ArrayListUnmanaged(Group) = .empty, ··· 814 815 // if the user specified a file (or something that couldn't be opened as a 816 // directory), then we open it's parent and apply a filter 817 + const dirname = std.fs.path.dirname(cmd.current_directory) orelse "."; 818 + cmd.opts.file = std.fs.path.basename(cmd.current_directory); 819 + cmd.current_directory = try cmd.arena.dupeZ(u8, dirname); 820 _ = try io.open( 821 + cmd.current_directory, 822 .{ .DIRECTORY = true, .CLOEXEC = true }, 823 0, 824 .{ ··· 839 if (cmd.opts.useHyperlinks()) { 840 var buf: [std.fs.max_path_bytes]u8 = undefined; 841 const cwd = try std.os.getFdPath(fd, &buf); 842 + cmd.current_directory = try cmd.arena.dupeZ(u8, cwd); 843 } 844 845 var temp_results: std.ArrayListUnmanaged(MinimalEntry) = .empty; ··· 901 } 902 const path = try std.fs.path.joinZ( 903 cmd.arena, 904 + &.{ cmd.current_directory, entry.name }, 905 ); 906 907 if (entry.kind == .sym_link) { ··· 1068 cmd.entry_idx += 1; 1069 const path = try std.fs.path.joinZ( 1070 cmd.arena, 1071 + &.{ cmd.current_directory, entry.name }, 1072 ); 1073 1074 if (entry.kind == .sym_link) {

History

1 round 1 comment
sign up or login to add to the discussion
themackabu.dev submitted #0
1 commit
expand
416908bf
feature: support listing multiple directories
expand 1 comment

Awesome work, thanks!

pull request successfully merged