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 9 10 10 const usage = 11 11 \\Usage: 12 - \\ lsr [options] [path] 12 + \\ lsr [options] [path...] 13 13 \\ 14 14 \\ --help Print this message and exit 15 15 \\ --version Print the version string ··· 43 43 sort_by_mod_time: bool = false, 44 44 reverse_sort: bool = false, 45 45 46 - directory: [:0]const u8 = ".", 46 + directories: std.ArrayListUnmanaged([:0]const u8) = .empty, 47 47 file: ?[]const u8 = null, 48 48 49 49 winsize: ?posix.winsize = null, ··· 253 253 } 254 254 }, 255 255 .positional => { 256 - cmd.opts.directory = arg; 256 + try cmd.opts.directories.append(allocator, arg); 257 257 }, 258 258 } 259 259 } ··· 262 262 cmd.opts.colors = .default; 263 263 } 264 264 265 - var ring: ourio.Ring = try .init(allocator, queue_size); 266 - defer ring.deinit(); 265 + if (cmd.opts.directories.items.len == 0) { 266 + try cmd.opts.directories.append(allocator, "."); 267 + } 267 268 268 - _ = try ring.open(cmd.opts.directory, .{ .DIRECTORY = true, .CLOEXEC = true }, 0, .{ 269 - .ptr = &cmd, 270 - .cb = onCompletion, 271 - .msg = @intFromEnum(Msg.cwd), 272 - }); 269 + const multiple_dirs = cmd.opts.directories.items.len > 1; 273 270 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, .{ 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, .{ 286 285 .ptr = &cmd, 287 286 .cb = onCompletion, 288 - .msg = @intFromEnum(Msg.group), 287 + .msg = @intFromEnum(Msg.cwd), 289 288 }); 290 - } 291 289 292 - try ring.run(.until_done); 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); 293 309 294 - if (cmd.entries.len == 0) return; 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 + } 295 316 296 - std.sort.pdq(Entry, cmd.entries, cmd.opts, Entry.lessThan); 317 + std.sort.pdq(Entry, cmd.entries, cmd.opts, Entry.lessThan); 297 318 298 - if (cmd.opts.reverse_sort) { 299 - std.mem.reverse(Entry, cmd.entries); 300 - } 319 + if (cmd.opts.reverse_sort) { 320 + std.mem.reverse(Entry, cmd.entries); 321 + } 301 322 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()), 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 + } 307 334 } 308 335 try bw.flush(); 309 336 } ··· 420 447 } 421 448 422 449 if (opts.useHyperlinks()) { 423 - const path = try std.fs.path.join(cmd.arena, &.{ opts.directory, entry.name }); 450 + const path = try std.fs.path.join(cmd.arena, &.{ cmd.current_directory, entry.name }); 424 451 try writer.print("\x1b]8;;file://{s}\x1b\\", .{path}); 425 452 try writer.writeAll(entry.name); 426 453 try writer.writeAll("\x1b]8;;\x1b\\"); ··· 562 589 } 563 590 564 591 if (cmd.opts.useHyperlinks()) { 565 - const path = try std.fs.path.join(cmd.arena, &.{ cmd.opts.directory, entry.name }); 592 + const path = try std.fs.path.join(cmd.arena, &.{ cmd.current_directory, entry.name }); 566 593 try writer.print("\x1b]8;;file://{s}\x1b\\", .{path}); 567 594 try writer.writeAll(entry.name); 568 595 try writer.writeAll("\x1b]8;;\x1b\\"); ··· 606 633 entries: []Entry = &.{}, 607 634 entry_idx: usize = 0, 608 635 symlinks: std.StringHashMapUnmanaged(Symlink) = .empty, 636 + current_directory: [:0]const u8 = ".", 609 637 610 638 tz: ?zeit.TimeZone = null, 611 639 groups: std.ArrayListUnmanaged(Group) = .empty, ··· 786 814 787 815 // if the user specified a file (or something that couldn't be opened as a 788 816 // 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); 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); 792 820 _ = try io.open( 793 - cmd.opts.directory, 821 + cmd.current_directory, 794 822 .{ .DIRECTORY = true, .CLOEXEC = true }, 795 823 0, 796 824 .{ ··· 811 839 if (cmd.opts.useHyperlinks()) { 812 840 var buf: [std.fs.max_path_bytes]u8 = undefined; 813 841 const cwd = try std.os.getFdPath(fd, &buf); 814 - cmd.opts.directory = try cmd.arena.dupeZ(u8, cwd); 842 + cmd.current_directory = try cmd.arena.dupeZ(u8, cwd); 815 843 } 816 844 817 845 var temp_results: std.ArrayListUnmanaged(MinimalEntry) = .empty; ··· 873 901 } 874 902 const path = try std.fs.path.joinZ( 875 903 cmd.arena, 876 - &.{ cmd.opts.directory, entry.name }, 904 + &.{ cmd.current_directory, entry.name }, 877 905 ); 878 906 879 907 if (entry.kind == .sym_link) { ··· 1040 1068 cmd.entry_idx += 1; 1041 1069 const path = try std.fs.path.joinZ( 1042 1070 cmd.arena, 1043 - &.{ cmd.opts.directory, entry.name }, 1071 + &.{ cmd.current_directory, entry.name }, 1044 1072 ); 1045 1073 1046 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