diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 07:23:58 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | a63185292e80beac3848f4f6395c61d941f5144f (patch) | |
| tree | e097eb6675db1af9a098e647a5b9f33c161c7ba4 /src | |
| parent | 97780909cbe0f4c62dfb9b012bff3fe7e7ec32f9 (diff) | |
| download | pardes-a63185292e80beac3848f4f6395c61d941f5144f.tar.gz pardes-a63185292e80beac3848f4f6395c61d941f5144f.zip | |
A look that goes to another pane leaves the looking pane's dot alone
Every look that found something cleared the looker's selection first, so
`@p5:2` or `f.txt:2` written to a pane's look collapsed its dot to
q1-1. Only a look that stays in the pane starts from a clean selection
now; one that goes elsewhere takes away just the click's highlight, and a
miss changes nothing, as acme's look does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/look.zig | 15 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 24 |
2 files changed, 35 insertions, 4 deletions
diff --git a/src/look.zig b/src/look.zig index 92e711fa..2f712fae 100644 --- a/src/look.zig +++ b/src/look.zig @@ -1381,9 +1381,16 @@ pub fn lookAt(p: *Pardes, id: usize, operand: []const u8) void { // already clamped, so the one written is asked). if (found == .pane and found.pane.id < MAX_PANES) if (p.panes[found.pane.id]) |shown| if (shown.file) |*f| if (pl.at.line > panes.File.nlines(p.gpa, f)) return missedLine(p, id, trimmed, pl.at.line); - // A miss changes nothing, the selection included; anything else starts - // from a clean one. - if (found != .none) clearNavigationSelection(p, pane); + // A miss changes nothing, the selection included; a look that stays in + // this pane starts from a clean one. One that goes to another pane + // leaves this one's dot alone, as acme's does: only the click's own + // highlight goes. + if (found == .pane and found.pane.id == id) + clearNavigationSelection(p, pane) + else if (found != .none) { + for (0..pane.sel.len) |slot| pane.clearPointerSelection(slot); + pane.sel = @splat(.{}); + } switch (found) { .none => { // A raw terminal's clicks are its program's; a look written over @@ -1717,6 +1724,6 @@ test "Look ignores missing and out of bounds pane addresses" { lookAt(p, 0, operand); try std.testing.expectEqual(@as(usize, 0), p.active); try std.testing.expectEqual(@as(i32, 0), pane.body.cur_row); - try std.testing.expect(!pane.body.vsel.active); + try std.testing.expect(pane.body.vsel.active); // a miss changes nothing, the selection included } } diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 709f017f..b8f73c6f 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -2024,6 +2024,30 @@ test "@p<serial>:<address> takes any sam address; a miss and an unknown serial a try testing.expectEqualStrings("", rd(p, root, 0, 64).bytes); } +test "a look that goes to another pane leaves the looking pane's dot alone" { + const p = try withFile(testing.allocator, "alpha bravo\ncharlie\n"); + defer p.deinit(); + const source = serialOf(p); + const other = try th.newPane(p); + _ = wr(p, Node.of(other, .body), "one\ntwo\nthree\n"); + var tmp = testing.tmpDir(.{}); + defer tmp.cleanup(); + try tmp.dir.writeFile(testing.io, .{ .sub_path = "f.txt", .data = "f one\nf two\n" }); + var dir_buf: [4096]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(testing.io, &dir_buf)]; + var line: [4200]u8 = undefined; + for ([_][]const u8{ "@p{d}:2", "@p{d}:/three/", "{s}/f.txt:2" }) |form| { + @import("pane.zig").setDot(p.panes[p.paneBySerial(source).?].?, .{ .q0 = 6, .q1 = 11 }); + const text = if (form[0] == '@') + (if (std.mem.eql(u8, form, "@p{d}:2")) try std.fmt.bufPrint(&line, "@p{d}:2\n", .{other}) else try std.fmt.bufPrint(&line, "@p{d}:/three/\n", .{other})) + else + try std.fmt.bufPrint(&line, "{s}/f.txt:2\n", .{dir}); + try testing.expectEqual(Status.ok, wr(p, Node.of(source, .look), text).reply.status); + try testing.expect(p.active != p.paneBySerial(source).?); + try testing.expectEqualStrings(" 6 11 ", rd(p, Node.of(source, .dot), 0, 64).bytes); + } +} + test "@p<terminal>:<address> takes any address over the terminal's lines, selecting the match" { const p = try th.withTerm(testing.allocator); defer p.deinit(); |
