diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 23:10:41 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 23:22:39 -0300 |
| commit | e4562384ac910b78254ec7aaaecad8b74717f2ee (patch) | |
| tree | 418ea5ef8f1d3c97d4f7241ee48f5d60bb681a69 | |
| parent | 5618465914b259bea8f5d07e2438814e8607175d (diff) | |
| download | pardes-e4562384ac910b78254ec7aaaecad8b74717f2ee.tar.gz pardes-e4562384ac910b78254ec7aaaecad8b74717f2ee.zip | |
n in a command pane walks its own file:line places first, whichever pane was walked last: make's errors, then on through the other places as before
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/look.zig | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/look.zig b/src/look.zig index 030aa432..41cfdc0c 100644 --- a/src/look.zig +++ b/src/look.zig @@ -792,10 +792,16 @@ fn lookStand(pane: *Pane) LookFrom { fn lookWalkPanes(p: *Pardes, out: *[MAX_PANES]usize) []const usize { var n: usize = 0; + // A command pane walked from (`make`'s errors): its own places first. + if (commandPaneActive(p)) { + out[0] = p.active; + n = 1; + } var i = p.n_look_src; while (i > 0) { i -= 1; const id = p.paneBySerial(p.look_src[i]) orelse continue; + if (n > 0 and out[0] == id) continue; out[n] = id; n += 1; } @@ -890,11 +896,18 @@ fn lookSpanIn(p: *Pardes, pane: *Pane, from: LookFrom, delta: i32, budget: *usiz return null; } +/// A command pane has the keyboard: `n` there walks its own output. +fn commandPaneActive(p: *Pardes) bool { + const pane = p.panes[p.active] orelse return false; + return pane.command != null and pane.file == null and !p.header_focus; +} + pub fn lookWalk(p: *Pardes, delta: i32) void { var buf: [MAX_PANES]usize = undefined; const order = lookWalkPanes(p, &buf); if (order.len == 0) return; - const owner = if (p.look_walk_owner) |serial| p.paneBySerial(serial) else null; + // From a command pane the walk starts there, whoever walked last. + const owner = if (commandPaneActive(p)) p.active else if (p.look_walk_owner) |serial| p.paneBySerial(serial) else null; const active_at = std.mem.indexOfScalar(usize, order, p.active) orelse 0; const at = if (owner) |wanted| std.mem.indexOfScalar(usize, order, wanted) orelse active_at @@ -2643,6 +2656,46 @@ test "Incl's directories find a name found nowhere else, <name> too; bare Incl l try std.testing.expectEqual(@as(usize, 0), p.incl.items.len); } +test "n in a command pane walks its own file:line places, whoever walked last" { + if (!platform_has_fs) return; + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "x.c", .data = "a\nb\nc\n" }); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "y.c", .data = "a\nb\n" }); + var dir_buf: [4096]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(std.testing.io, &dir_buf)]; + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 30 }); + defer p.deinit(); + const doc = try p.setTestFile("x\n"); + p.gpa.free(doc.file.?.path); + doc.file.?.path = try std.fs.path.join(p.gpa, &.{ dir, "main.c" }); + while (p.nextEffect()) |_| {} + const dst = exec.execute(p, 0, "make") orelse return error.NoCommandPane; + while (p.nextEffect()) |_| {} + p.update(.{ .output = .{ .pane = @intCast(dst), .bytes = "x.c:3:1: error: bad\r\ny.c:2:1: warning: odd\r\n" } }); + p.update(.{ .exited = .{ .pane = @intCast(dst), .status = 2 } }); + p.update(.{ .eof = .{ .pane = @intCast(dst) } }); + const cmd = p.panes[dst].?; + // A walk last made elsewhere, and another pane with places in it. + try std.testing.expect(p.executeBuiltinLine(0, "New")); + const scratch = p.panes[p.active].?; + _ = pardes.ctlfs.pane.spliceBody(p, scratch, 0, 0, "x.c:1:1 elsewhere\n") orelse return error.NoScratch; + p.look_walk_owner = scratch.serial; + p.active = dst; + cmd.focus = .body; + cmd.body.mode = .normal; + for ([_]u21{ 'g', 'g' }) |cp| p.update(.{ .key = .{ .cp = cp } }); + p.update(.{ .key = .{ .cp = 'n' } }); + try std.testing.expectEqual(dst, p.active); + const first = cmd.look_at orelse return error.NoSpot; + const lines = try edit.paneCursorLines(p, &cmd.body); + try std.testing.expect(std.mem.startsWith(u8, lines[@intCast(first.row)][@intCast(first.col0)..], "x.c:3:1")); + p.update(.{ .key = .{ .cp = 'n' } }); + try std.testing.expectEqual(dst, p.active); + const second = cmd.look_at orelse return error.NoSpot; + try std.testing.expect(std.mem.startsWith(u8, lines[@intCast(second.row)][@intCast(second.col0)..], "y.c:2:1")); +} + 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(); |
