diff options
Diffstat (limited to 'src/exec.zig')
| -rw-r--r-- | src/exec.zig | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/exec.zig b/src/exec.zig index 5e223f04..5a421f19 100644 --- a/src/exec.zig +++ b/src/exec.zig @@ -169,10 +169,54 @@ pub fn pointerOperand(p: *Pardes, pane: *Pane, clicked: Pane.Sel) PointerOperand result.text = edit.currentSelText(p, pane); return result; } + // In a diff, a file or hunk header, and a hunk line pointed at on its + // `+`/`-`/` ` prefix, are looked at whole: the place the line names + // (look.diffLook). A hunk line's code is words, looked at as ever: + // the code's, the prefix never one of them. + var word_from: usize = 0; + if (clicked.r0 >= pane.tag_rows and clicked.r0 == clicked.r1 and clicked.c0 == clicked.c1 and row >= 0) diff: { + const lines = look.diffLines(p, pane) orelse break :diff; + const at: usize = @intCast(row); + if (at >= lines.len) break :diff; + const line = lines[at]; + const target = @import("diff.zig").targetAt(lines, at, pane.file == null) orelse break :diff; + const on_prefix = col == 0 and line.len > 0 and std.mem.indexOfScalar(u8, "+- ", line[0]) != null; + switch (target.kind) { + .context, .added, .removed => if (!on_prefix) { + word_from = @intFromBool(line.len > 0 and std.mem.indexOfScalar(u8, "+- ", line[0]) != null); + break :diff; + }, + else => {}, + } + result.text = line; + p.diff_look = .{ .serial = pane.serial, .row = at }; + const hi = std.math.cast(i32, line.len) orelse return result; + if (hi == 0) return result; + var expanded = clicked; + if (pane.file != null) { + result.file_word = .{ .row = row, .lo = 0, .hi = hi }; + const first = pane.wrapRow(row, 0); + const last = pane.wrapRow(row, hi - 1); + if (first.row < 0 or last.row < 0) return result; + expanded.r0 = first.row + @as(i32, pane.tag_rows); + expanded.c0 = @as(i32, panes.File.gutterWidth(pane)) + panes.File.displayOffset(pane, row, first.at, 0); + expanded.r1 = last.row + @as(i32, pane.tag_rows); + expanded.c1 = @as(i32, panes.File.gutterWidth(pane)) + panes.File.displayEndOffset(pane, row, last.at, hi - 1); + } else { + const shown = if (raw) raw_line else line; + expanded.c0 = 0; + expanded.c1 = @as(i32, @intCast(panes.File.rawDisplayCol(shown, shown.len))) - 1; + } + result.preview = expanded; + result.expanded = expanded; + return result; + } if (pane.file != null and clicked.r0 >= pane.tag_rows and clicked.r0 == clicked.r1 and clicked.c0 == clicked.c1) { const line = panes.File.sourceLine(pane, row); const source_col: usize = @intCast(@max(0, col)); - const b = look.expandedWord(line, source_col) orelse return result; + if (source_col < word_from or word_from > line.len) return result; + const word = look.expandedWord(line[word_from..], source_col - word_from) orelse return result; + const b: look.ExpandedWord = .{ .lo = word.lo + word_from, .hi = word.hi + word_from }; const lo = std.math.cast(i32, b.lo) orelse return result; const hi = std.math.cast(i32, b.hi) orelse return result; result.text = line[b.lo..b.hi]; |
