main.zig (4091B)
1 const std = @import("std"); 2 const cli = @import("cli.zig"); 3 const cfg = @import("cfg.zig"); 4 const fzf = @import("fzf.zig"); 5 const hist = @import("db.zig"); 6 const io = @import("io.zig"); 7 8 test { 9 _ = cli; 10 _ = cfg; 11 _ = fzf; 12 _ = hist; 13 } 14 15 pub fn main(init: std.process.Init) void { 16 io.init(init.io, init.environ_map); 17 const allocator = init.gpa; 18 19 const args = cli.parseArgs(allocator, init.minimal.args) catch |err| { 20 io.fatal("failed to parse arguments: {}", .{err}); 21 }; 22 defer args.deinit(); 23 24 if (args.action == .help) { 25 cli.printUsage() catch |err| { 26 io.fatal("failed to print usage: {}", .{err}); 27 }; 28 return; 29 } 30 31 const parsed_config = cfg.loadConfig(allocator); 32 defer if (parsed_config) |c| c.deinit(); 33 const default_config = cfg.Config{}; 34 const base_config = if (parsed_config) |c| c.value else default_config; 35 36 var cwd_buf: [std.fs.max_path_bytes]u8 = undefined; 37 const cwd = blk: { 38 const n = std.process.currentPath(io.rt(), &cwd_buf) catch |err| { 39 io.warn("failed to get cwd for folder overrides: {}\n", .{err}); 40 break :blk ""; 41 }; 42 break :blk cwd_buf[0..n]; 43 }; 44 const config = cfg.applyFolderOverride(base_config, cwd); 45 46 const db_path = hist.getDefaultDbPath(allocator) catch |err| { 47 io.fatal("failed to get database path: {}", .{err}); 48 }; 49 defer allocator.free(db_path); 50 51 var db = hist.Db.init(allocator, db_path) catch |err| { 52 io.fatal("failed to initialize database: {}", .{err}); 53 }; 54 defer db.deinit(); 55 56 runAction(allocator, &db, args, &config) catch |err| { 57 if (err == error.UserAbort) { 58 std.process.exit(1); 59 } 60 io.fatal("action failed: {}", .{err}); 61 }; 62 } 63 64 fn runAction(allocator: std.mem.Allocator, db: *hist.Db, args: cli.Args, config: *const cfg.Config) !void { 65 var buf: [4096]u8 = undefined; 66 var writer = io.getStdout(&buf); 67 68 switch (args.action) { 69 .recent_dirs => { 70 const managed = try db.recentDirs(); 71 defer managed.deinit(); 72 for (managed.value) |d| { 73 try writer.print("{s}|{s}\n", .{ d.timestamp orelse "-", d.path }); 74 } 75 }, 76 .recent_files => { 77 const managed = try db.recentFiles(); 78 defer managed.deinit(); 79 for (managed.value) |f| { 80 try writer.print("{s}|{s}|{s}|{s}\n", .{ f.timestamp orelse "-", f.file_type, f.action, f.path }); 81 } 82 }, 83 .favorites => { 84 try fzf.favorites(allocator, db, config); 85 }, 86 .search => { 87 if (args.query) |query| { 88 const managed = try db.searchHistory(query); 89 defer managed.deinit(); 90 const results = managed.value; 91 92 for (results.directories) |d| { 93 try writer.print("D|{s}\n", .{d.path}); 94 } 95 for (results.files) |f| { 96 try writer.print("F|{s}|{s}|{s}\n", .{ f.file_type, f.action, f.path }); 97 } 98 } 99 }, 100 .goto_dir => { 101 try fzf.recentDir(allocator, db, config); 102 }, 103 .goto_file => { 104 try fzf.recentFile(allocator, db, config); 105 }, 106 .look_file => { 107 try fzf.lookFile(allocator, db, config, args.depth); 108 }, 109 .look_dir => { 110 try fzf.lookDir(allocator, db, config, args.depth); 111 }, 112 .grep => { 113 try fzf.grep(allocator, db, config); 114 }, 115 .cleanup => { 116 try db.cleanup(); 117 }, 118 .log_dir => { 119 if (args.log_path) |path| { 120 try db.logDir(path); 121 } 122 }, 123 .log_file => { 124 if (args.log_path) |path| { 125 try db.logFile(path, args.file_type orelse "other", args.file_action orelse "open"); 126 } 127 }, 128 .help => { 129 try cli.printUsage(); 130 }, 131 } 132 try writer.end(); 133 }