aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.h
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-15 13:13:34 +0200
committeruser <user@clank>2026-08-15 13:13:34 +0200
commitd9dee7f725b68332982f34ab6c52da0552b821d3 (patch)
tree950f8293a6d6b6fd5a39acee5625c64813ab0160 /src/app.h
parentsl0ppty: let the cheatsheet breathe (diff)
downloadslosh-d9dee7f725b68332982f34ab6c52da0552b821d3.tar.gz
slosh-d9dee7f725b68332982f34ab6c52da0552b821d3.tar.xz
slosh-d9dee7f725b68332982f34ab6c52da0552b821d3.zip
sl0ppty: write the session back out as a layout, and a loop that uses it
Dogfooding this while building it has one sharp edge: a running session keeps the binary it started with. `reload` re-reads the config, it cannot re-read the code, so every build you want to try means losing your screen. The only thing worth carrying across a restart is the shape, and sl0ppty already knows how to read one -- it just could not write one. `dump-layout` is the inverse of `--layout`: tabs with their names and purposes, how the panes are split, in what proportion, in which directory, running what, which tab was active and which pane had focus. Two details make it worth trusting. The directory is where the shell *is*, read from /proc, not where the pane was started -- after any amount of `cd` those differ and only one of them is useful. And a pane running the session's default shell is dumped with no `command`, so it comes back as a shell rather than as a shell wrapped in a shell, one layer deeper every restart. contrib/sl0ppty-dev is the loop: attach, and when the session ends because you asked for a restart, come straight back with the layout. It is two halves because it has to be -- `restart` runs inside the session, and the moment the session ends so does the shell it was typed in, so it leaves the layout and a note and the loop outside picks them up. What does not come back is what was running *inside* a program. A shell returns as a shell, in the right directory, with an empty history. That is the limit of restoring a layout rather than a session, and the script says so rather than implying otherwise. Three bugs found by the round-trip test, all the same kind -- a dump that loads without complaint and rebuilds something subtly different: - `split=` belongs on the node that *has* the children, not on the children. Written the other way it parses fine and gives the wrong tree. - a split's weight was never restored, because the edit meant to read it silently matched nothing and was never applied. - `active=true` landed on the wrong tab: the index is recorded while the new tabs sit after the old ones, and `replace` then moves them to the front. Which is why the test asserts that a dump of a reload is byte-identical to the first dump. Anything the dumper loses shows up there at once, where reading it and nodding would not.
Diffstat (limited to 'src/app.h')
-rw-r--r--src/app.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/app.h b/src/app.h
index f220eb6..6150147 100644
--- a/src/app.h
+++ b/src/app.h
@@ -126,6 +126,14 @@ bool app_shade_add(app_t *a, uint32_t pane_id, const char *kind, color_t color,
void app_shade_clear(app_t *a, uint32_t pane_id);
size_t app_shade_count(app_t *a, uint32_t pane_id);
+/* The session written back out as a layout file: tabs, splits, proportions,
+ * directories and commands. The inverse of app_apply_layout_text(), and what
+ * makes "quit, rebuild, come back to the same screen" possible. Caller frees.
+ *
+ * The shape is restorable; what is running inside a program is not, and this
+ * does not pretend otherwise. */
+char *app_dump_layout(app_t *a);
+
/* State as JSON, for the control API and the harness. Caller frees. */
char *app_panes_json(app_t *a);
char *app_tabs_json(app_t *a);