summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Terminal.zig2
-rw-r--r--src/edit.zig13
-rw-r--r--src/pardes.zig3
3 files changed, 15 insertions, 3 deletions
diff --git a/src/Terminal.zig b/src/Terminal.zig
index e3378007..4f94533d 100644
--- a/src/Terminal.zig
+++ b/src/Terminal.zig
@@ -1382,7 +1382,7 @@ pub fn editText(p: *Pardes, pane: *Pane, lo: i32, hi: i32, col: i32) ?EditText {
/// Consume a rewritten overlay, freeing the terminal edit text it replaces.
pub fn setEditText(p: *Pardes, pane: *Pane, new: []u8) void {
- const overlay = if (pane.ovl) |*value| value else return p.gpa.free(new);
+ const overlay = if (pane.ovl) |*value| value else return pardes.edit.retireEditText(p, new);
for (0..pane.sel.len) |button| {
pane.clearPointerSelection(button);
pane.sel[button].state = .none;
diff --git a/src/edit.zig b/src/edit.zig
index 8f6f09c6..3e12f169 100644
--- a/src/edit.zig
+++ b/src/edit.zig
@@ -463,7 +463,9 @@ pub fn setEditText(p: *Pardes, t: *Text, new: []u8) void {
if (t.what == .tag) {
// A tag is edited as it is shown, but only what follows its
// prefix is its own: an edit that changed the prefix is refused.
- defer p.gpa.free(new);
+ // The shown text stays alive until the next such edit, since every
+ // caller reads the new text back, as a body's is kept.
+ defer retireEditText(p, new);
const pane = t.pane() orelse return;
const prefix = tagline.pathPrefix(p.scratch.allocator(), pane) catch return;
if (!std.mem.startsWith(u8, new, prefix)) {
@@ -480,11 +482,18 @@ pub fn setEditText(p: *Pardes, t: *Text, new: []u8) void {
t.own = new;
return;
}
- const pane = t.pane() orelse return p.gpa.free(new);
+ const pane = t.pane() orelse return retireEditText(p, new);
if (pane.file) |*f| return panes.File.setContent(p, f, new);
panes.Terminal.setEditText(p, pane, new);
}
+/// Take a text an edit made that nothing keeps, holding it until the next
+/// one: the edit's caller still reads it to place the cursor.
+pub fn retireEditText(p: *Pardes, new: []u8) void {
+ if (p.retired_edit) |old| p.gpa.free(old);
+ p.retired_edit = new;
+}
+
pub const InsertAt = enum { at, append, line_start, line_end, open_below, open_above };
/// Files insert only inside existing rows and at grapheme boundaries.
diff --git a/src/pardes.zig b/src/pardes.zig
index e4645d70..c9d93979 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -4096,6 +4096,8 @@ pub const Pardes = struct {
in_len: usize = 0,
registers: Registers = .{},
+ /// an edited text nothing kept (a tag's shown text): see edit.retireEditText
+ retired_edit: ?[]u8 = null,
clip_pending: ?edit.ClipRequest = null,
/// the last serialized dump (gpa-owned), read by the write_dump effect
dump_out: ?[]u8 = null,
@@ -4267,6 +4269,7 @@ pub const Pardes = struct {
for (&p.col_tags) |*t| t.deinit(gpa);
p.global_tag.deinit(gpa);
p.registers.deinit(gpa);
+ if (p.retired_edit) |r| gpa.free(r);
if (p.dump_out) |d| gpa.free(d);
p.fallback.deinit();
if (p.last_dump) |d| gpa.free(d);