summaryrefslogtreecommitdiff
path: root/src/edit.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/edit.zig')
-rw-r--r--src/edit.zig30
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;