summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtins.zig6
-rw-r--r--src/pardes.zig35
2 files changed, 24 insertions, 17 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index 934b3996..ee542e77 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -194,9 +194,9 @@ pub const Wrap = struct {
/// Taglines at the BOTTOM of every pane instead of the top. Global like Wrap
/// and for the same reason — a layout where some panes label themselves above
/// and others below is unreadable, so it is one switch for the whole screen.
-/// The transient message row moves the other way to keep out of its way (see
-/// render), which puts the two strips of chrome at the ends they always were,
-/// just swapped.
+/// The transient message row gives that row up and takes the one above it (see
+/// render), so it is the pane's last BODY row either way and a prompt stays
+/// beside the tag it is typed into.
pub const Tagbottom = struct {
pub fn run(c: Ctx) void {
c.p.tag_bottom = !c.p.tag_bottom;
diff --git a/src/pardes.zig b/src/pardes.zig
index 592dd059..ef606f23 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -12084,17 +12084,17 @@ pub const Pardes = struct {
try p.renderPane(arena, pane, p.rects[id], id == p.active);
}
- // ---- the transient message row: the end away from the tag ----
+ // ---- the transient message row: the pane's last body row ----
//
// An OVERLAY, not geometry: no rect moves, no pane shrinks, and a pane
// with neither a message nor an armed prompt is not touched at all.
// Drawn after every pane's body so it lands OVER whatever that row was
- // showing, and painted in the tag bar's own colours — it is the
- // tagline's twin at the other end of the pane, and reading as chrome is
- // what keeps it from being mistaken for content. Out here rather than
- // at the end of renderPane because renderPane returns early for a
- // native PDF page and for an image, and a `/` on a PDF is a real search
- // whose prompt has to be visible like any other.
+ // showing, and painted across the whole row — it is the tagline's twin,
+ // and reading as one strip rather than a stamp on a body line is what
+ // keeps it from being mistaken for content. Out here rather than at the
+ // end of renderPane because renderPane returns early for a native PDF
+ // page and for an image, and a `/` on a PDF is a real search whose
+ // prompt has to be visible like any other.
//
// Exactly two things can occupy the row and an ARMED PROMPT beats a
// MESSAGE, because they are not the same kind of thing: a message is a
@@ -12104,15 +12104,19 @@ pub const Pardes = struct {
//
// ponytail: the row is draw-only. A click on it lands wherever the body
// under it says (tag clicks map to tag_col on the TAG row), so a prompt
- // that moved down here cannot be clicked into or swept the way one on
- // the tagline could — the keyboard still edits it in full. Upgrade path
+ // that moved off the tagline cannot be clicked into or swept the way it
+ // could up there — the keyboard still edits it in full. Upgrade path
// is a hit test here that maps a press on this row to tag_col + the
// marker offset, i.e. the tag row's own mapping with a constant added.
for (&p.panes, 0..) |*slot, id| {
const pane = slot.* orelse continue;
const r = p.rects[id];
// no body row (a one-row pane, or one squeezed out entirely): the
- // tag row is not ours to overwrite, so the message just waits
+ // tag row is not ours to overwrite, so the message just waits. One
+ // guard for both placements, because the row picked below is the
+ // last BODY row either way — "the pane has a body row" is the whole
+ // condition, and it is what keeps r.h - 1 - BOX_H from underflowing
+ // or landing above the pane.
if (r.w <= config.GUTTER or r.h <= BOX_H) continue;
// the same one input model renderPane cut off the tagline; only one
// of the two can ever be armed (a body key arms one, exitTagEdit
@@ -12128,10 +12132,13 @@ pub const Pardes = struct {
if (text.len == 0 and !leader_here) continue;
const tx = r.x + config.GUTTER;
const tw = r.w - config.GUTTER;
- // ...at the OTHER end from the tagline, whichever end that is:
- // Tagbottom moved the tag onto this row, so the twin moves to the
- // pane's first. They stay a pair with the body between them.
- const row = if (p.tag_bottom) r.y else r.y + r.h - 1;
+ // the pane's last BODY row: its last row outright, or one up from
+ // that when Tagbottom has taken the last for the tagline. The first
+ // cut of Tagbottom sent this row to the pane's FIRST instead — the
+ // far end, symmetric with the tag — which put the prompt you are
+ // typing as far as the pane allows from the tag you are typing
+ // into. Beside the tagline is where it is read, so it stays there.
+ const row = if (p.tag_bottom) r.y + r.h - 1 - BOX_H else r.y + r.h - 1;
// In the EDITOR's colours, not the tag bar's: this row is the one
// place the program talks back to you about the buffer you are in,
// and it reads as part of that buffer rather than as another strip