summaryrefslogtreecommitdiff
path: root/src/look.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 19:11:53 -0300
committerGabriel Schneider <[email protected]>2026-10-01 19:57:27 -0300
commit5f41a03fdcf0eaa3c1917e0f94243878c481cf8b (patch)
treec3025e2ca80a295962fa941bb4423df9a1525509 /src/look.zig
parent6ee4c3caa6faf42b9825dca39e9130ac83f425a8 (diff)
downloadpardes-5f41a03fdcf0eaa3c1917e0f94243878c481cf8b.tar.gz
pardes-5f41a03fdcf0eaa3c1917e0f94243878c481cf8b.zip
Incl dir ... adds directories a look at a name found nowhere else is tried in, as acme's includename, <stdio.h> too; bare Incl lists them and Incl - empties them; the session's, seeded with /usr/include and /usr/local/include, kept in a dump; Indent's refusal says Enter keeps the indent always
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/look.zig')
-rw-r--r--src/look.zig50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/look.zig b/src/look.zig
index a2aa5be0..3d02802a 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -1141,6 +1141,13 @@ fn resolveLookTarget(p: *Pardes, id: usize, txt: []const u8, realbuf: *[4096]u8)
// `.`, `..`, `./x` are this pane's directory's, not another's.
if (found != .none or pl.path.len == 0 or pl.path[0] == '/' or filesystem.dotRelative(pl.path)) break;
}
+ // Found nowhere else, a relative name is tried in Incl's directories,
+ // as acme's includename tries its (look.c:500).
+ if (found == .none and pl.path.len > 0 and pl.path[0] != '/' and !filesystem.dotRelative(pl.path))
+ for (p.incl.items) |dir| {
+ found = resolve(p, txt, dir, realbuf);
+ if (found != .none) break;
+ };
return found;
}
@@ -1734,7 +1741,9 @@ pub fn lookAt(p: *Pardes, id: usize, operand_raw: []const u8) void {
const txt = p.scratch.allocator().dupe(u8, looked) catch return;
// A trailing `:` (`a.txt:2:3:`, as a compiler's message ends) is no
// part of the place, as a click's expansion leaves it off.
- const trimmed = std.mem.trimEnd(u8, std.mem.trim(u8, txt, " \t\r\n"), ":");
+ const bare = std.mem.trimEnd(u8, std.mem.trim(u8, txt, " \t\r\n"), ":");
+ // `<stdio.h>` written whole: the name inside, as a click on it takes.
+ const trimmed = if (bare.len > 2 and bare[0] == '<' and bare[bare.len - 1] == '>') bare[1 .. bare.len - 1] else bare;
// acme's `file:addr` and `:addr` (look.c:450-543): an address after
// the colon, evaluated in that file from its dot (openfile, look.c:675).
// `file:3:0`, and `file:0:0` too: columns count from 1, as addr's do,
@@ -2586,6 +2595,45 @@ test "a tag word looked at by a click and by Enter is one record to an event rea
try std.testing.expect(p.panes[0] != null);
}
+test "Incl's directories find a name found nowhere else, <name> too; bare Incl lists them, Incl - empties them, and a dump keeps them" {
+ if (!platform_has_fs) return;
+ var tmp = std.testing.tmpDir(.{});
+ defer tmp.cleanup();
+ try tmp.dir.createDirPath(std.testing.io, "inc");
+ try tmp.dir.createDirPath(std.testing.io, "src");
+ try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "inc/pardes_incl_probe.h", .data = "#define X 1\n" });
+ var dir_buf: [4096]u8 = undefined;
+ const root = dir_buf[0..try tmp.dir.realPath(std.testing.io, &dir_buf)];
+ const p = try Pardes.init(std.testing.allocator, .{ .cols = 100, .rows = 30 });
+ defer p.deinit();
+ // C's two by default.
+ try std.testing.expectEqualStrings("/usr/include", p.incl.items[0]);
+ const pane = try p.setTestFile("#include <pardes_incl_probe.h>\n");
+ p.gpa.free(pane.file.?.path);
+ pane.file.?.path = try std.fs.path.join(p.gpa, &.{ root, "src", "main.c" });
+ var line: [4200]u8 = undefined;
+ try std.testing.expect(p.executeBuiltinLine(0, try std.fmt.bufPrint(&line, "Incl {s}/inc", .{root})));
+ for ([_][]const u8{ "pardes_incl_probe.h", "<pardes_incl_probe.h>" }) |word| {
+ p.active = 0;
+ p.look_missed = false;
+ lookAt(p, 0, word);
+ try std.testing.expect(!p.look_missed);
+ try std.testing.expect(std.mem.endsWith(u8, p.panes[p.active].?.file.?.path, "/inc/pardes_incl_probe.h"));
+ }
+ // Bare, it lists them.
+ try std.testing.expect(p.executeBuiltinLine(0, "Incl"));
+ try std.testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "/inc") != null);
+ // A dump keeps them.
+ try pardes.dump.dumpState(p);
+ const restored = try pardes.dump.restore(p, p.dump_out.?, "/tmp/pardes.dump.zon");
+ defer restored.deinit();
+ try std.testing.expectEqual(p.incl.items.len, restored.incl.items.len);
+ try std.testing.expect(std.mem.endsWith(u8, restored.incl.items[restored.incl.items.len - 1], "/inc"));
+ // Emptied, the name is found nowhere.
+ try std.testing.expect(p.executeBuiltinLine(0, "Incl -"));
+ try std.testing.expectEqual(@as(usize, 0), p.incl.items.len);
+}
+
test "Look outside a diff pane expands and looks as ever" {
const p = try Pardes.init(std.testing.allocator, .{ .cols = 100, .rows = 30 });
defer p.deinit();