commit fd4a4949b2929c0644e85af5c0e1dbef8eb89a38 from: mtmn date: Tue Jul 7 16:22:37 2026 UTC fix prek and docs, dead code, allow tilde in favorites commit - 5a25ead23cee7f32c14e2dd549c3c32b1ba36d79 commit + fd4a4949b2929c0644e85af5c0e1dbef8eb89a38 blob - aa888200fc0a32f3de023c46cdda470ae438c0d2 blob + 37ae75008306305032d1674861c875bc7c8644fd --- README.md +++ README.md @@ -12,7 +12,7 @@ A command-line tool for interactive shell navigation a ## Dependencies -- Zig 0.15.2 +- Zig 0.16.0 - ripgrep - fzf - bat blob - a1d954513c27f0796620405d2f73e651d74b6b49 blob + a4b9994dc0d8b8f2550eb2485707c42db3286f04 --- config.json +++ config.json @@ -12,7 +12,7 @@ "--color=marker:#e06fad,fg+:#f0dfe5,prompt:#7a9fd4,hl+:#f0a070", "--color=border:#3d2a42" ], - "fav_dirs": ["/home/miro/src"], + "favorites": ["~/src"], "openers": [ { "extensions": ["mp4", "mkv", "avi", "webm"], blob - ea9b6abb41ba3e87be1033b62fc9aae49b20579e blob + 9fd8e389b9e46e5cdb0a44cb47433891e583ca40 --- prek.toml +++ prek.toml @@ -4,38 +4,11 @@ rev = "v6.0.0" hooks = [ { id = "trailing-whitespace" }, { id = "end-of-file-fixer" }, - { id = "double-quote-string-fixer" } ] [[repos]] -repo = "https://github.com/biomejs/pre-commit" -rev = "v2.4.14" -hooks = [ - { id = "biome-format" } -] - -[[repos]] repo = "https://github.com/gitleaks/gitleaks" rev = "v8.30.1" hooks = [ { id = "gitleaks" } ] - -[[repos]] -repo = "https://github.com/astro/deadnix" -rev = "v1.3.1" -hooks = [ - { id = "deadnix" } -] - -[[repos]] -repo = "local" -hooks = [ - { - id = "alejandra", - name = "alejandra", - language = "system", - entry = "alejandra", - files = '\.nix$' - }, -] blob - 4c1239df39138e842c816ee72b7a464de534b9a3 blob + 4d2ce948ed673c91f5b3f0a8b15d30ecfe05723b --- src/cfg.zig +++ src/cfg.zig @@ -47,18 +47,29 @@ pub fn applyFolderOverride(base: Config, cwd: []const } pub fn loadConfig(allocator: std.mem.Allocator) ?std.json.Parsed(Config) { - const home = io.getenv("HOME") orelse return null; - const path = std.fs.path.join(allocator, &.{ home, ".config", "magdalena", "config.json" }) catch return null; + const home = io.getenv("HOME") orelse { + io.warn("HOME not set, skipping config load\n", .{}); + return null; + }; + const path = std.fs.path.join(allocator, &.{ home, ".config", "magdalena", "config.json" }) catch { + io.warn("failed to allocate config path\n", .{}); + return null; + }; defer allocator.free(path); - const content = std.Io.Dir.cwd().readFileAlloc(io.rt(), path, allocator, .unlimited) catch return null; + const content = std.Io.Dir.cwd().readFileAlloc(io.rt(), path, allocator, .unlimited) catch |err| { + if (err != error.FileNotFound) { + io.warn("failed to read config {s}: {}\n", .{ path, err }); + } + return null; + }; defer allocator.free(content); return std.json.parseFromSlice(Config, allocator, content, .{ .ignore_unknown_fields = true, .allocate = .alloc_always, }) catch |err| { - std.log.err("failed to parse config: {any}", .{err}); + io.warn("failed to parse config {s}: {}\n", .{ path, err }); return null; }; } blob - ac9739c7a9d68808433abc92662fde17ff3a2d45 blob + e7e32675b7303c9a6a5deb82d0def49d533d80bb --- src/cli.zig +++ src/cli.zig @@ -41,7 +41,6 @@ pub const CommandLineArgs = struct { exe: []const u8, tail: []const [:0]const u8, - list: []const [:0]const u8, pub fn parse(parent: std.mem.Allocator, source: std.process.Args) !CommandLineArgs { const arena = try parent.create(std.heap.ArenaAllocator); @@ -62,7 +61,7 @@ pub const CommandLineArgs = struct { var lookup: std.StringHashMapUnmanaged([]const u8) = .{}; if (items.len == 0) { - return .{ .exe = "", .tail = &.{}, .list = &.{}, ._arena = arena, ._lookup = lookup }; + return .{ .exe = "", .tail = &.{}, ._arena = arena, ._lookup = lookup }; } const exe = items[0]; @@ -96,7 +95,6 @@ pub const CommandLineArgs = struct { return .{ .exe = exe, .tail = items[tail_start..], - .list = items, ._arena = arena, ._lookup = lookup, }; blob - 5cbedb8b32b318127fec7b9a26ca37794ea5e8cd blob + 23f01221c0f9da9f7fa8b47c9deb04548dc0d47f --- src/db.zig +++ src/db.zig @@ -153,8 +153,11 @@ pub const Db = struct { } fn resolvePath(self: *Db, path: []const u8) ![]const u8 { - return std.Io.Dir.cwd().realPathFileAlloc(io.rt(), path, self.allocator) catch { - return try std.fs.path.resolve(self.allocator, &[_][]const u8{path}); + return std.Io.Dir.cwd().realPathFileAlloc(io.rt(), path, self.allocator) catch |err| { + if (err == error.FileNotFound) { + io.warn("path not found for logging: {s}\n", .{path}); + } + return try std.fs.path.resolve(self.allocator, &.{ ".", path }); }; } @@ -223,6 +226,7 @@ pub const Db = struct { var total_entries: usize = 0; var missing_entries: usize = 0; + var inaccessible_entries: usize = 0; var it = std.mem.splitBackwardsScalar(u8, content, '\n'); while (it.next()) |line| { const trimmed = std.mem.trim(u8, line, " \r\t"); @@ -248,15 +252,17 @@ pub const Db = struct { missing_entries += 1; continue; } - return err; + io.warn("skipping inaccessible entry {s}: {}\n", .{ p, err }); + inaccessible_entries += 1; + continue; }; try seen.put(p, {}); try lines.append(self.allocator, trimmed); } - const duplicates = total_entries - lines.items.len - missing_entries; - io.warn(" Entries: {d} total, {d} unique, {d} missing, {d} duplicates removed\n", .{ total_entries, lines.items.len, missing_entries, duplicates }); + const duplicates = total_entries - lines.items.len - missing_entries - inaccessible_entries; + io.warn(" Entries: {d} total, {d} unique, {d} missing, {d} inaccessible, {d} duplicates removed\n", .{ total_entries, lines.items.len, missing_entries, inaccessible_entries, duplicates }); const write_file = try std.Io.Dir.cwd().createFile(io.rt(), path, .{ .truncate = true }); defer write_file.close(io.rt()); blob - e07175224c5d0aa9c9fcd4fc19818ebcebaf561c blob + 9654e0bb66dcf0077b16444c595ea288a019d167 --- src/fzf.zig +++ src/fzf.zig @@ -216,11 +216,15 @@ fn expandPath(allocator: std.mem.Allocator, path: []co var res = std.ArrayListUnmanaged(u8).empty; errdefer res.deinit(allocator); + const home = io.getenv("HOME") orelse return error.HomeNotFound; + var i: usize = 0; while (i < path.len) { - if (std.mem.startsWith(u8, path[i..], "$HOME")) { - const home = io.getenv("HOME") orelse "/home/user"; + if (path[i] == '~' and (i == 0 or path[i - 1] == std.fs.path.sep)) { try res.appendSlice(allocator, home); + i += 1; + } else if (std.mem.startsWith(u8, path[i..], "$HOME")) { + try res.appendSlice(allocator, home); i += 5; } else { try res.append(allocator, path[i]); blob - c0bf997c71213570fffb7bde2052c56fab5fbbca blob + 1939677accd3af9aeb9cd4ca98dedd28e2406993 --- src/memcached.zig +++ src/memcached.zig @@ -57,6 +57,8 @@ pub const Memcached = struct { const chunk_size = 900 * 1024; const chunk_prefix = "\x00chunked:"; + // Large values are split into chunk keys `{key}:{i}`. Overwriting a chunked + // key with a smaller value leaves old chunks as orphans. pub fn set(self: *Memcached, key: []const u8, value: []const u8, exptime: u32) !void { if (value.len <= chunk_size) { try self.sendSet(key, value, exptime);