diff options
Diffstat (limited to 'src/edit.zig')
| -rw-r--r-- | src/edit.zig | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/edit.zig b/src/edit.zig index e21352e1..b2d71ed2 100644 --- a/src/edit.zig +++ b/src/edit.zig @@ -112,8 +112,12 @@ pub fn applyPaste(p: *Pardes, bytes: []const u8) void { /// into, after the cursor's cell in normal mode, as a body's paste is. fn pasteInto(p: *Pardes, t: *Text, bytes: []const u8) void { if (bytes.len == 0) return; - if (t.mode == .insert) return insertKey(p, t, .{ .cp = bytes[0], .text = bytes }); - pasteText(p, t, bytes, false, 1); + const typed: pardes.Key = .{ .cp = bytes[0], .text = bytes }; + if (t.what == .tag and t.mode == .insert) if (t.pane()) |pane| if (tagline.typedIntoName(p, pane, typed)) return; + const kept = .{ t.cur_row, t.cur_col, t.vsel, t.msel, t.sels, t.nsel }; + t.refused = false; + if (t.mode == .insert) insertKey(p, t, typed) else pasteText(p, t, bytes, false, 1); + if (t.refused) t.cur_row, t.cur_col, t.vsel, t.msel, t.sels, t.nsel = kept; } pub fn clipYank(p: *Pardes, pane: *Pane, main_only: bool) void { @@ -358,7 +362,8 @@ pub fn pinPaneCursor(p: *Pardes, t: *Text) void { pub fn flatSurface(p: *Pardes, t: *Text) ![]const u8 { switch (t.what) { .body => {}, - .tag => return if (t.pane()) |pane| tagline.curTail(pane) else "", + // the tag as it is shown: the keyboard reaches its prefix too + .tag => return if (t.pane()) |pane| try tagline.tagText(p, p.scratch.allocator(), pane) else "", .input => return t.own orelse "", .column, .workspace => return t.own orelse tagline.headerDefault(p, t.what), } @@ -384,6 +389,10 @@ pub fn paneWrapWidth(p: *const Pardes, t: *Text) usize { fn editText(p: *Pardes, t: *Text, lo: i32, hi: i32, col: i32) ?panes.EditText { // A tag or header nobody has changed shows its default; the first edit // makes that default its own text. + if (t.what == .tag) { + const pane = t.pane() orelse return null; + return .{ .text = tagline.tagText(p, p.scratch.allocator(), pane) catch return null, .row0 = 0 }; + } if (t.what != .body and t.what != .input and t.own == null) t.own = p.gpa.dupe(u8, flatSurface(p, t) catch return null) catch return null; if (t.what != .body) return .{ .text = t.own orelse &.{}, .row0 = 0 }; @@ -403,6 +412,21 @@ fn editTextEol(p: *Pardes, t: *Text, b: Bounds) ?panes.EditText { /// install a rewritten editable text (frees the old one) 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); + const pane = t.pane() orelse return; + const prefix = tagline.pathPrefix(p.scratch.allocator(), pane) catch return; + if (!std.mem.startsWith(u8, new, prefix)) { + t.refused = true; + return; + } + const tail = p.gpa.dupe(u8, new[prefix.len..]) catch return; + if (t.own) |old| p.gpa.free(old); + t.own = tail; + return; + } if (t.what != .body) { if (t.own) |old| p.gpa.free(old); t.own = new; |
