diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-02 01:03:55 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-02 01:33:55 -0300 |
| commit | d65ec3394ff619118d9208718477469c673a5598 (patch) | |
| tree | d66c6bd145258fc2b369714abc618aa6766dfb5e | |
| parent | 2537126c643db75419ff846f1041e40d154c9426 (diff) | |
| download | pardes-d65ec3394ff619118d9208718477469c673a5598.tar.gz pardes-d65ec3394ff619118d9208718477469c673a5598.zip | |
A name typed into the tag's path survives Esc, pending, as any edit does: the next Enter renames the buffer, a second Esc drops the draft, and a stray key meanwhile changes nothing but says so
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/pardes.zig | 41 | ||||
| -rw-r--r-- | test/panes.zig | 7 | ||||
| -rw-r--r-- | test/snapshots/tagalign.snap | 5 | ||||
| -rw-r--r-- | test/snapshots/tagpath.snap | 3 |
4 files changed, 54 insertions, 2 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index e92f9623..2a74e441 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -3192,6 +3192,33 @@ fn pardes_ctlfs_ctlText(p: *Pardes, pane: *Pane) []const u8 { return th.rd(p, ctlfs.Node.of(pane.serial, .ctl), 0, 4096).bytes; } +test "a name typed into the tag's path survives Esc, pending, and the next Enter renames; a second Esc drops it" { + const gpa = std.testing.allocator; + const p = try Pardes.init(gpa, .{ .tty_only = true }); + defer p.deinit(); + const pane = try p.setTestFile("x\n"); + for ([_]bool{ true, false }) |enter| { + tagline.enterTag(p, pane); + pane.tag.mode = .insert; + pane.tag.cur_row = 0; + pane.tag.cur_col = 1; + p.update(.{ .key = .{ .cp = 'z', .text = "z" } }); + try std.testing.expect(pane.prompt == .name); + p.update(.{ .key = .{ .cp = Key.escape } }); + try std.testing.expect(pane.prompt == .name); + // A stray key changes nothing while it waits. + p.update(.{ .key = .{ .cp = 'q', .text = "q" } }); + if (enter) { + p.update(.{ .key = .{ .cp = Key.enter } }); + try std.testing.expectEqualStrings("/ztest.txt", pane.file.?.path); + } else { + p.update(.{ .key = .{ .cp = Key.escape } }); + try std.testing.expect(pane.prompt != .name); + try std.testing.expectEqualStrings("/ztest.txt", pane.file.?.path); + } + } +} + test "tabbed file aligns syntax cursor and mouse at the nearest insertion gap" { const gpa = std.testing.allocator; const p = try Pardes.init(gpa, .{ .cols = 60, .rows = 12 }); @@ -6355,16 +6382,28 @@ pub const Pardes = struct { } if (header == null and pane.prompt == .name) { // Enter or the execute key commits the draft and the keyboard - // goes back to the body; Esc drops it. + // goes back to the body. Esc while typing keeps the draft, + // pending, as Esc keeps any edit: Enter then renames, and a + // second Esc drops it. Pending, no other key changes it. if (hit(key, config.look_key) or hit(key, config.exec_key)) { if (tagline.commitTagName(p, pane)) pane.focus = .body; return; } + const pending = pane.input.mode != .insert; + if (hit(key, config.escape) and !pending) { + pane.input.mode = .normal; + if (p.paneIdOf(pane)) |id| p.setMessage(id, "name drafted: Enter renames the buffer, Esc drops the draft"); + return; + } if (hit(key, config.escape)) { pane.closePrompt(); pane.focus = .body; return; } + if (pending) { + if (p.paneIdOf(pane)) |id| p.setMessage(id, "name drafted: Enter renames the buffer, Esc drops the draft"); + return; + } edit.handleInsert(p, &pane.input, key); return; } diff --git a/test/panes.zig b/test/panes.zig index 8f1c510a..41061bea 100644 --- a/test/panes.zig +++ b/test/panes.zig @@ -367,6 +367,8 @@ const TagNavigationTests = struct { p.update(.{ .key = .{ .cp = 'x', .text = "x" } }); try std.testing.expect(pane.prompt == .name); try std.testing.expectEqualStrings("x/test.txt", pane.input.own.?); + // Esc keeps the draft pending; a second drops it. + key(p, Key.escape); key(p, Key.escape); try std.testing.expect(pane.prompt == .none); try std.testing.expectEqualStrings("/test.txt", pane.file.?.path); @@ -1621,7 +1623,9 @@ test "pane filename drafts commit and cancel without changing body or command ta try std.testing.expectEqualStrings("/new name.zig", pane.input.own.?); try std.testing.expectEqualStrings(tail, pardes.tagline.curTail(pane)); try std.testing.expectEqualStrings("original body\n", pane.file.?.content); + // Esc keeps the draft pending; a second drops it. p.update(.{ .key = .{ .cp = if (commit) Key.enter else Key.escape } }); + if (!commit) p.update(.{ .key = .{ .cp = Key.escape } }); try std.testing.expect(pane.focus == .body); try std.testing.expect(pane.prompt == .none); try std.testing.expectEqualStrings(if (commit) "/new name.zig" else original, pane.file.?.path); @@ -1649,6 +1653,9 @@ test "pane filename grapheme edits and invalid empty commits preserve the buffer try std.testing.expect(pane.prompt == .name); try std.testing.expectEqualStrings("/test.txt", pane.file.?.path); try std.testing.expectEqualStrings("untouched\n", pane.file.?.content); + // Esc keeps the draft pending; a second drops it. + p.update(.{ .key = .{ .cp = Key.escape } }); + try std.testing.expect(pane.prompt == .name); p.update(.{ .key = .{ .cp = Key.escape } }); try std.testing.expect(pane.prompt == .none); } diff --git a/test/snapshots/tagalign.snap b/test/snapshots/tagalign.snap index 3bb3922e..7237167a 100644 --- a/test/snapshots/tagalign.snap +++ b/test/snapshots/tagalign.snap @@ -22,12 +22,15 @@ press left 12 3 release left 12 3 stable 400 5000 snap clicked -# The click was on the path, so it drafted a name; Esc drops the draft. `:` +# The click was on the path, so it drafted a name; Esc keeps it pending and +# a second Esc drops the draft. `:` # then `A` puts the caret after the tag's end, which reveals the complete # command suffix; a scrolled Del still executes. resize 31 70 key esc settle 100 +key esc +settle 100 key : key A stable 400 5000 diff --git a/test/snapshots/tagpath.snap b/test/snapshots/tagpath.snap index f02769d9..841d4fed 100644 --- a/test/snapshots/tagpath.snap +++ b/test/snapshots/tagpath.snap @@ -41,6 +41,9 @@ key i text /renamed stable 400 5000 snap name-draft +# Esc keeps the draft pending; a second drops it +key esc +settle 100 key esc stable 400 5000 snap name-cancelled |
