diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 11:46:38 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | cef529dc8cd080198f79d2b26bffbe9c7cf3e8bd (patch) | |
| tree | b6f98f447572d9e9c94c27981b737e897268d1a0 /src/ninep/ctl.zig | |
| parent | 261eb7ac3f090c8ce47ad47c0f58f824a9b162a6 (diff) | |
| download | pardes-cef529dc8cd080198f79d2b26bffbe9c7cf3e8bd.tar.gz pardes-cef529dc8cd080198f79d2b26bffbe9c7cf3e8bd.zip | |
Theme takes a name in any case, and a miss names its nearest themes
Names were case-sensitive, and a miss listed only the first letter's themes that fitted 40 bytes, 4 of the many d ones. It now lists every theme sharing the first letter when they fit the 128 bytes an Rerror carries, else the nearest by a plain likeness score (shared prefix, the name inside, its letters in order).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index ea0a0bc6..68b62186 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -408,13 +408,15 @@ fn checkBuiltin(p: *Pardes, req: Req, line: []const u8, scope: builtins.Scope) ? if (arg.len == 0 and builtins.registry.requiresArg(b)) return refuse(p, req, "wrong #args in control message", line); const setting = config.Runtime.find(word) orelse return null; const takes = switch (setting.action) { - .theme => for (pardes.themes) |t| { - if (std.mem.eql(u8, t.name, arg)) break true; - } else { - // `refuse` quotes the line after it, in what is left of 128. - var near: [40]u8 = undefined; - var why: [104]u8 = undefined; - return refuse(p, req, std.fmt.bufPrint(&why, "bad value in control message; like it: {s}; Themes lists all", .{pardes.colors.themesNear(&near, arg)}) catch "bad value in control message", line); + .theme => if (pardes.colors.themeIndex(arg) != null) true else { + // `refuse` quotes the line after it, all in the 128 bytes an + // Rerror carries: the names get what is left. + const head = "bad value in control message; like it: "; + const tail = "; Themes lists all"; + var near: [128]u8 = undefined; + const room = @import("cloud9").fs.errmax -| (head.len + tail.len + line.len + 3); + var why: [256]u8 = undefined; + return refuse(p, req, std.fmt.bufPrint(&why, head ++ "{s}" ++ tail, .{pardes.colors.themesNear(near[0..@min(room, near.len)], arg)}) catch "bad value in control message", line); }, .font => config.Runtime.FontSpec.parse(arg) != null, else => probe: { @@ -1614,12 +1616,34 @@ test "Joincol with no column to the right and Theme with no such theme say so" { const themed = wr(p, root_ctl, "Theme drak\n"); try testing.expectEqual(E.INVAL, themed.errno()); try testing.expectStringStartsWith(themed.reply.ename, "bad value in control message; like it: "); - try testing.expect(std.mem.indexOf(u8, themed.reply.ename, " dark") != null or std.mem.indexOf(u8, themed.reply.ename, ": dark") != null); + try testing.expect(std.mem.indexOf(u8, themed.reply.ename, ": dr") != null); try testing.expect(std.mem.endsWith(u8, themed.reply.ename, "\"Theme drak\"")); // A click on the word says it on the message row. _ = wr(p, Node.of(serialOf(p), .exec), "Theme drak\n"); const pane = p.panes[p.active].?; try testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "no theme \"drak\"") != null); + // Within the 128 bytes an Rerror carries, the quoted line kept. + try testing.expect(themed.reply.ename.len <= 128); + // A name in any case is the theme. + try testing.expectEqual(Status.ok, wr(p, root_ctl, "Theme DRACULA\n").reply.status); + try testing.expectEqualStrings("dracula", pardes.themes[p.settings.theme].name); + // A misspelling far from any first letter's list still finds its like. + var near: [170]u8 = undefined; + try testing.expect(std.mem.indexOf(u8, pardes.colors.themesNear(&near, "9dracula"), "dracula") != null); + // Every theme sharing the first letter, when they fit. + var tested = false; + for ("abcdefghijklmnopqrstuvwxyz") |letter| { + var count: usize = 0; + var len: usize = 0; + for (pardes.themes) |t| if (t.name[0] == letter) { + count += 1; + len += t.name.len + 1; + }; + if (count < 2 or len > near.len) continue; + try testing.expectEqual(count, std.mem.count(u8, pardes.colors.themesNear(&near, &.{letter}), " ") + 1); + tested = true; + } + try testing.expect(tested); } test "a look after Newcol fills the empty column the keyboard is on" { |
