summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 47892108..cd01187b 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -5227,17 +5227,49 @@ pub const Pardes = struct {
/// lands right below `from_id`, be that a shell, a file or another list,
/// and `from_id` alone pays the rows (several lists just stack there).
/// A real doc joins the docs: any doc already open is the split parent (the
- /// source if it IS one, else the first found) and the newcomer lands right
- /// below it, so all docs share one column. The FIRST doc of the session
- /// instead gets a column of its own on the left (acme: files left, shells
- /// right) — nothing is displaced, the other columns just narrow. A full
- /// column bar, or a result list whose source died, stacks into the leftmost.
+ /// source if it IS one, else the one most recently worked in) and the
+ /// newcomer lands right below it, so docs share a column. The FIRST doc of
+ /// the session instead gets a column of its own on the left (acme: files
+ /// left, shells right) — nothing is displaced, the other columns just
+ /// narrow. A full column bar, or a result list whose source died, stacks
+ /// into the leftmost.
pub fn placeDoc(p: *Pardes, from_id: usize, free: usize, nt: *Pane) void {
const doc = if (nt.file) |f| output_pane.fileTraits(f.output).doc else true; // an image is a doc
var src_id: ?usize = null;
if (p.panes[from_id]) |src| if (if (src.file) |f| output_pane.fileTraits(f.output).doc else src.image != null) {
src_id = from_id;
};
+ // Opened from somewhere that is NOT a doc (a shell, a results list):
+ // the file joins the column it was last being READ in, which is the
+ // newest doc on the jump stack. The stack already IS that record — it
+ // is where the keyboard has been — so nothing new is remembered here;
+ // asking it is the whole change. What this replaces was the first doc
+ // in slot order, i.e. pane-id ALLOCATION order, so which column your
+ // file landed in depended on how the session had handed out ids rather
+ // than on where you were working.
+ //
+ // The answer wanted is the COLUMN, and it stays right once the pane
+ // itself is closed: trackJump compacts dead entries out, so the walk
+ // falls through to the next doc remembered in that same column. The
+ // serial test is the one trackJump uses — slots are reused, so an entry
+ // whose pane has been replaced names a pane that is gone, not the
+ // newcomer sitting in its slot (`free`, this very pane, among them).
+ if (doc and src_id == null) {
+ var n = p.njumps;
+ while (n > 0) : (n -= 1) {
+ const j = p.jumps[n - 1];
+ const pp = p.panes[j.pane] orelse continue;
+ if (pp.serial != j.serial) continue;
+ if (if (pp.file) |f| output_pane.fileTraits(f.output).doc else pp.image != null) {
+ src_id = j.pane;
+ break;
+ }
+ }
+ }
+ // A doc no jump remembers is still a doc: a restored session focuses
+ // one pane, not each, and the stack is finite. The rule that a second
+ // doc never claims a second column outranks knowing where you were, so
+ // the old slot-order scan stays as the fallback.
if (doc and src_id == null) for (p.panes, 0..) |sl, i| {
if (sl) |pp| if (i != free and (if (pp.file) |f| output_pane.fileTraits(f.output).doc else pp.image != null)) {
src_id = i;