magdalena

interactive shell navigation and history
Log | Files | Refs | README | LICENSE

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 }