diff options
| -rw-r--r-- | src/look.zig | 13 | ||||
| -rw-r--r-- | src/ninep/events.zig | 8 |
2 files changed, 16 insertions, 5 deletions
diff --git a/src/look.zig b/src/look.zig index 3d02802a..030aa432 100644 --- a/src/look.zig +++ b/src/look.zig @@ -2428,7 +2428,7 @@ test "a click, a 9P whole-line look and an empty event write-back take one expan // An empty record written back to event, at the same byte. const body = pane.file.?.content; const line_start = modal.lineStartOffset(body, at.row); - const written = pardes.ctlfs.events.expandAt(p, pane, body, line_start + at.col, true); + const written = pardes.ctlfs.events.expandAt(p, pane, body, line_start + at.col, true, true); try std.testing.expectEqualStrings(at.want, written); // A 9P look of the whole line. if (at.whole_line) { @@ -2518,7 +2518,7 @@ test "every entry point to Look takes one expansion: a diff line and a file:12:5 }, .event_write_back => { const body = pane.file.?.content; - const text = pardes.ctlfs.events.expandAt(p, pane, body, modal.lineStartOffset(body, case.row) + case.col, true); + const text = pardes.ctlfs.events.expandAt(p, pane, body, modal.lineStartOffset(body, case.row) + case.col, true, true); lookAt(p, 0, p.scratch.allocator().dupe(u8, text) catch unreachable); }, } @@ -2563,6 +2563,15 @@ test "a tag word looked at by a click and by Enter is one record to an event rea pane.body.cur_col = 0; try std.testing.expectEqualStrings("+line", exec.operandAt(p, pane, cursorWordSel(p, pane), false, false).text.?); try std.testing.expectEqualStrings("src/x.zig:1", exec.operandAt(p, pane, cursorWordSel(p, pane), false, true).text.?); + // An exec written back to event (`MX0 0`) takes the word too, on a + // header, a hunk header and a marker column; a look, the address. + const body = pane.file.?.content; + const events = pardes.ctlfs.events; + try std.testing.expectEqualStrings("diff", events.expandAt(p, pane, body, 0, true, false)); + try std.testing.expectEqualStrings("@@", events.expandAt(p, pane, body, modal.lineStartOffset(body, 3), true, false)); + try std.testing.expectEqualStrings("+line", events.expandAt(p, pane, body, modal.lineStartOffset(body, 5), true, false)); + try std.testing.expectEqualStrings("src/x.zig", events.expandAt(p, pane, body, 0, true, true)); + try std.testing.expectEqualStrings("src/x.zig:1", events.expandAt(p, pane, body, modal.lineStartOffset(body, 5), true, true)); // An event reader on the pane. const event = pardes.ctlfs.Node.of(pane.serial, .event); diff --git a/src/ninep/events.zig b/src/ninep/events.zig index 5b2a763e..3910ac05 100644 --- a/src/ninep/events.zig +++ b/src/ninep/events.zig @@ -728,11 +728,13 @@ fn scanNumber(data: []const u8, i: *usize, overflow: *bool) ?u32 { /// An empty range written back: what a click at `at` takes, as the mouse's /// does (exec.pointerOperand). In a diff pane's body that is look.diffClick's /// answer, the line's address or its code's words. -pub fn expandAt(p: *Pardes, pane: *Pane, whole: []const u8, at: usize, in_body: bool) []const u8 { +/// `for_look`: only a look in a body takes a diff line's address +/// (exec.operandAt); an exec takes the word there, as anywhere. +pub fn expandAt(p: *Pardes, pane: *Pane, whole: []const u8, at: usize, in_body: bool, for_look: bool) []const u8 { const start = if (std.mem.lastIndexOfScalar(u8, whole[0..at], '\n')) |nl| nl + 1 else 0; const end = std.mem.indexOfScalarPos(u8, whole, at, '\n') orelse whole.len; var word_from: usize = 0; - if (in_body) diff: { + if (in_body and for_look) diff: { const row = std.mem.count(u8, whole[0..start], "\n"); // Only when the served line is the one the diff reads there. const lines = look.diffLines(p, pane) orelse break :diff; @@ -794,7 +796,7 @@ pub fn writeEvent(p: *Pardes, asked: Req, id: usize) Reply { // An empty range with no text is a click at that point: expanded as // the click would be, to the word or file name under it (acme's // expand, look.c). - const said = if (r.q0 == r.q1) r.text orelse expandAt(p, pane, whole, lo, !r.action.onTag()) else whole[lo..hi]; + const said = if (r.q0 == r.q1) r.text orelse expandAt(p, pane, whole, lo, !r.action.onTag(), r.action == .body_look or r.action == .tag_look) else whole[lo..hi]; const text = p.scratch.allocator().dupe(u8, said) catch continue; switch (r.action) { // A body's click written back is done as the click would have |
