summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-02 01:03:55 -0300
committerGabriel Schneider <[email protected]>2026-10-02 01:33:55 -0300
commitd65ec3394ff619118d9208718477469c673a5598 (patch)
treed66c6bd145258fc2b369714abc618aa6766dfb5e
parent2537126c643db75419ff846f1041e40d154c9426 (diff)
downloadpardes-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.zig41
-rw-r--r--test/panes.zig7
-rw-r--r--test/snapshots/tagalign.snap5
-rw-r--r--test/snapshots/tagpath.snap3
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