summaryrefslogtreecommitdiff
path: root/src/exec.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.zig')
-rw-r--r--src/exec.zig47
1 files changed, 46 insertions, 1 deletions
diff --git a/src/exec.zig b/src/exec.zig
index d114dbf8..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];
@@ -738,6 +782,7 @@ fn runCommand(p: *Pardes, from: usize, line: []const u8) ?usize {
};
p.gpa.free(pane.command.?);
pane.command = owned;
+ p.diff_output.drop(p.gpa, pane.serial);
pane.command_done = false;
pane.command_status = null;
pane.command_pty = true;