diff options
Diffstat (limited to 'src/look.zig')
| -rw-r--r-- | src/look.zig | 50 |
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(); |
