commit - 5a25ead23cee7f32c14e2dd549c3c32b1ba36d79
commit + fd4a4949b2929c0644e85af5c0e1dbef8eb89a38
blob - aa888200fc0a32f3de023c46cdda470ae438c0d2
blob + 37ae75008306305032d1674861c875bc7c8644fd
--- README.md
+++ README.md
## Dependencies
-- Zig 0.15.2
+- Zig 0.16.0
- ripgrep
- fzf
- bat
blob - a1d954513c27f0796620405d2f73e651d74b6b49
blob + a4b9994dc0d8b8f2550eb2485707c42db3286f04
--- config.json
+++ config.json
"--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
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
}
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
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);
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];
return .{
.exe = exe,
.tail = items[tail_start..],
- .list = items,
._arena = arena,
._lookup = lookup,
};
blob - 5cbedb8b32b318127fec7b9a26ca37794ea5e8cd
blob + 23f01221c0f9da9f7fa8b47c9deb04548dc0d47f
--- src/db.zig
+++ src/db.zig
}
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 });
};
}
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");
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
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
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);