diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 00:01:57 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 23f430573efe4f6ef55b0180aa0d742ff4eca1d9 (patch) | |
| tree | da2157ba73d6abff4b1674541433294fb6c2daa9 /src/normal.zig | |
| parent | 9584b0682b45f17aaa42157540947904d867777a (diff) | |
| download | pardes-23f430573efe4f6ef55b0180aa0d742ff4eca1d9.tar.gz pardes-23f430573efe4f6ef55b0180aa0d742ff4eca1d9.zip | |
Make a pane's tag a Text edited with the body's own keys
The tag was a fixed buffer with its own one-line editor, a cursor measured
across the path, and a hijack of the body's mode while it was typed into.
It is now the pane's second Text: its own characters after the computed
prefix (path, dirty marker, PDF page), which is never stored in it, so a
rename or a dirty marker never moves its cursor. Normal and insert mode are
the body's, undo included; `:` moves the keyboard between body and tag, the
tag remembers its cursor and starts on Save, and executing a word from it
hands the keyboard back. The mouse still sees the prefix: a sweep selects
across it and a click on the path drafts a new name.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/normal.zig')
| -rw-r--r-- | src/normal.zig | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/src/normal.zig b/src/normal.zig index a77f27a7..e4fa075d 100644 --- a/src/normal.zig +++ b/src/normal.zig @@ -257,7 +257,7 @@ pub fn replaySels(p: *Pardes, t: *Text, what: Replay) void { if (p.multi_stop) { p.multi_stop = false; const pn = p.panes[id] orelse return; - if (pn.serial == serial) pn.body.nsel = 0; + if (pn.serial == serial) t.nsel = 0; return; } const text = edit.flatSurface(p, t) catch return; @@ -285,7 +285,7 @@ pub fn handleNormal(p: *Pardes, t: *Text, key: Key) void { fn executeNormalAction(p: *Pardes, t: *Text, semantic: modal.Normal.Action) void { const pane = t.pane(); - const raw_selection = pane.rawPointerText(pane.sel[sel_slot]) != null; + const raw_selection = t.what == .body and pane.rawPointerText(pane.sel[sel_slot]) != null; const before = .{ t.cur_row, t.cur_col, t.vsel, t.msel, t.select, t.nsel, t.mode }; defer if (raw_selection and !std.meta.eql(before, .{ t.cur_row, t.cur_col, t.vsel, t.msel, t.select, t.nsel, t.mode })) { pane.clearPointerSelection(sel_slot); @@ -334,7 +334,7 @@ fn executeNormalAction(p: *Pardes, t: *Text, semantic: modal.Normal.Action) void .view_center => return t.gotoWindow(text, range, .center, go.count), .view_bottom => return t.gotoWindow(text, range, .bottom, go.count), }, - .view => |view| switch (view) { + .view => |view| if (t.what == .body) switch (view) { .top => { pane.scrollBy(t.cur_row - pane.scroll()); pane.ensureCursorVisible(); @@ -545,10 +545,11 @@ fn executeNormalAction(p: *Pardes, t: *Text, semantic: modal.Normal.Action) void p.leader_on = true; p.leader_n = 0; }, - .command_line => { - p.enterTagEdit(pane, -1); - if (pane.tag_edit) t.mode = .normal; - }, + // `:` is the one key a tag and a body do not share: it moves the + // keyboard between them. + .command_line => if (t.what == .tag) { + pane.focus = .body; + } else p.enterTag(pane), .pipe_selection => |how| return p.startPrompt(pane, .{ .pipe = how }), .search => return p.startPrompt(pane, .{ .search = config.search_marker }), .search_step => |direction| return look.lookWalk( @@ -590,10 +591,7 @@ pub fn handlePdfNormal(p: *Pardes, pane: *Pane, key: Key) void { p.leader_on = true; p.leader_n = 0; }, - .command_line => { - p.enterTagEdit(pane, -1); - if (pane.tag_edit) pane.body.mode = .normal; - }, + .command_line => p.enterTag(pane), .search => p.startPrompt(pane, .{ .search = config.search_marker }), .search_forward => look.lookWalk(p, 1), .search_backward => look.lookWalk(p, -1), |
