<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slosh.git/tests/test_zoom.py, branch master</title>
<subtitle>an opinionated terminal multiplexer in C with programmable pane chrome</subtitle>
<id>https://git.sl0p.foo/slosh.git/atom/tests/test_zoom.py?h=master</id>
<link rel='self' href='https://git.sl0p.foo/slosh.git/atom/tests/test_zoom.py?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/'/>
<updated>2026-08-22T16:59:41Z</updated>
<entry>
<title>slosh: a pane arriving in a zoomed tab ends the zoom</title>
<updated>2026-08-22T16:59:41Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-22T16:59:41Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=4d2cd060089a4c48c24b93253f49bfd5bf22d53b'/>
<id>urn:sha1:4d2cd060089a4c48c24b93253f49bfd5bf22d53b</id>
<content type='text'>
A split, the config editor or a new float while zoomed used to land the
new pane behind the pane filling the tab -- which looks exactly like the
verb having failed. Whoever asked for a new pane asked to see it, so the
zoom yields, in place_beside where every such arrival funnels through;
the move-pane unzoom was this rule as a special case and folds in.
Minimising the zoomed pane ends the zoom too, or the layout would solo a
pane the strip now holds.
</content>
</entry>
<entry>
<title>sl0ppty: ruff format the Python</title>
<updated>2026-08-17T12:36:59Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-17T12:36:59Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=c0022776d0912042819e4ea330cf7491a8196b45'/>
<id>urn:sha1:c0022776d0912042819e4ea330cf7491a8196b45</id>
<content type='text'>
The bumpy one, again. Every `.py` outside `vendor/` plus the three `contrib/`
scripts that are Python with no extension: 60 files, 6,714 lines rewritten, no
behaviour changed. Nothing here is worth reading -- the next commit adds it to
`.git-blame-ignore-revs` so `git blame` walks past it.

It is a bigger reformat than the C was, 60% of the lines against 17%, and for a
reason worth writing down rather than tuning away: ruff and black break a call that
does not fit onto one argument per line, where this code aligned the continuation
under the opening paren. The test suite is thousands of `check("some prose", cond,
detail)` calls, so nearly every one of them changed shape and the suite grew 3,308
lines. Line length was the one lever that moved it -- 120 columns would have been a
40% reformat and no growth at all -- and it was left at 88, because picking an
unusual width to dodge a one-time diff is paying forever to avoid paying once.

Import sorting came with it. Two files had `import os, pty, uuid, select, struct,
sys, termios, time, fcntl, signal` on one line and now have ten.

Verified after, not before, because a formatter that alters behaviour would be
worse than none:

- `make retest`, 1801 checks green -- and this reformats the suite that does the
  checking, including `harness.py`, which every one of those files imports.
- `make test-live`, the tty tests the fast suite skips. They matter here more than
  usual: `live_input.py` and `live_m0.py` are two of the files whose comma-imports
  were split, and nothing in the fast suite would have noticed if that broke them.
- All 60 files still compile, `make fmt` twice in a row changes nothing the second
  time, and `ruff check --select I` has nothing left to say.
</content>
</entry>
<entry>
<title>sl0ppty: one family of marks for the frame's buttons</title>
<updated>2026-08-15T21:35:58Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-15T21:35:58Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=dabeb8eb2da8e87c52ad068173bf52204f3b76d6'/>
<id>urn:sha1:dabeb8eb2da8e87c52ad068173bf52204f3b76d6</id>
<content type='text'>
    ⊟ ⊞ ⊠        away, bigger, gone
    ⊟ ⊡ ⊠        ...and while it is already filling the tab

`_ # x` said what they did only if you already knew, and `*` for a zoomed
pane was the weakest of the four: nothing about an asterisk says "put it
back". So there are four marks now instead of three and a half, with the
unzoom state getting one of its own.

ASCII was there for a reason, and the reason survives: the cells are
even, but a glyph that does not fill its own cell hands the slack to the
gap beside it, and how much it hands over depends on the font -- which is
why box-drawing and block characters were tried here and looked unevenly
spaced. Four copies of *the same box* answer that better than four
unrelated glyphs did: whatever a font does with the box, it does four
times, and only the interior changes. Minus for away, plus for bigger,
dot for back to normal, times for gone.

Single width, checked in a real frame rather than assumed -- the row
still closes on its corner and each button is still measured rather than
booked, so the hits land where the glyphs are. Not emoji, which many
terminals draw two columns wide while chrome here is booked as one.

Two tests were pinning the old glyphs by hand (`line.rindex("x")` for the
cheatsheet's close button, `"*" in line` for the zoom state). They read
them out of `sl0ppty --dump-config` now, which is generated from the
code: picking a nicer mark later cannot leave a test asserting a glyph
nothing draws.
</content>
</entry>
<entry>
<title>sl0ppty: plain ASCII for the frame's buttons</title>
<updated>2026-08-14T18:28:30Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-14T18:28:30Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=5cdbca2c8a896fd0e25cfc03aa44ba0143d2d31b'/>
<id>urn:sha1:5cdbca2c8a896fd0e25cfc03aa44ba0143d2d31b</id>
<content type='text'>
_ for minimise, # for zoom, * for the way back, x for close.

Box-drawing and block characters were each tried and each looked unevenly
spaced, which is the answer: the cells are even every time, and what differs is
how much of its own cell a glyph fills. That is a property of the font, not
something to be fixed from here, and single-width ASCII of a similar weight is
the way to stop asking the question.

The measurement stays, so a mark is still yours to change and may be more than
one character. The config note now says what the three attempts established
rather than what I expected each time.
</content>
</entry>
<entry>
<title>sl0ppty: the squares are back for zoom</title>
<updated>2026-08-14T18:23:04Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-14T18:23:04Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=b9a2ab5e39e9292a98c37bf5abebef18e4c09b9e'/>
<id>urn:sha1:b9a2ab5e39e9292a98c37bf5abebef18e4c09b9e</id>
<content type='text'>
□ and ▣ read as a pane and a filled pane, which is what zoom does to one; [] and
][ were only ever a hedge against a spacing problem that turned out to be
elsewhere. Minimise and close stay as the underscore and the x, so the row is
_ □ x.

The measured button width stays, which is what makes the choice free: a mark of
any width can go in there now, including the two-character ones, so the config
note is about how a glyph *looks* beside its neighbours rather than about what
will fit.
</content>
</entry>
<entry>
<title>sl0ppty: minimised panes get one row between them, and ASCII marks</title>
<updated>2026-08-14T18:18:23Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-14T18:18:23Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=373931bf85fa92bc326f2ab68edf14a5bc15b260'/>
<id>urn:sha1:373931bf85fa92bc326f2ab68edf14a5bc15b260</id>
<content type='text'>
The strip was a row per minimised pane, which let putting things away cost more
room than leaving them out. It is one row now, shaped like the tab strip and
for the same reason: a list of names you click to go somewhere. Three panes put
away leave the survivor exactly as tall as one did, and there is a test that
says so, because that is the whole change.

The panes on it are no longer laid out at all — the bar draws them, so they
have no rect. The row the bar occupies is worked out by the layout and stored,
rather than by the drawing working it out again from the same inputs; two
copies of that sum is how a click lands somewhere the eye did not.

The frame's marks are plain ASCII now. Spacing has been reported twice and the
cells were even both times: what is uneven is the glyphs. A light character
floating in a mostly empty cell hands that space to the gap beside it, and the
fix of picking heavier glyphs only holds for fonts I can see. ASCII has neither
that problem nor the double-width one, and "[]" and "][" say maximise and
restore about as clearly as anything.

That needed the button width measured rather than assumed. It was hardcoded to
three cells, which was fine while every mark was one character and silently
wrong the moment one was two: the mark would have been drawn over its
neighbour, and the neighbour's hit would have covered a cell it did not draw.

Also fixes a case that could not happen with a row each: when there is no room
for the bar at all, the tab flattens rather than leaving minimised panes with
no rect and nobody drawing them.
</content>
</entry>
<entry>
<title>sl0ppty: zoom a pane, and give the frame buttons for it</title>
<updated>2026-08-14T17:39:32Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-08-14T17:39:32Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=277869e7621b057554f6c02c478c4786392e0aa4'/>
<id>urn:sha1:277869e7621b057554f6c02c478c4786392e0aa4</id>
<content type='text'>
A pane can now fill its tab and go back again, by C-a z or by a button in the
frame's top-right corner. The others keep running; they are just not drawn.

Zoom is intent rather than derived state, so it is stored like focus is: on the
tab, one per tab, because zooming a pane in one tab has nothing to say about
another. Everything else about it falls out of that. It survives the layout
being recomputed because it is an input to the layout rather than a product of
it. It cannot outlive the pane it names, because the id is checked against the
tree every pass and dropped if the pane has gone. And it needed no new
arrangement: "show this one and nothing else" is what layout_solo already did
for a tab too small to divide, and zoom is the same shape asked for on purpose
rather than as a last resort.

The frame gets buttons back, having had its split button removed once already
on the grounds that one glyph cannot mean four directions. Zoom and close are
two verbs a single glyph *can* mean, which is the difference; splitting is
still done by clicking an edge, where the edge encodes the direction. They cost
six columns of every frame, which is a real tax and why pane_buttons turns them
off — the keybindings are untouched by that, because the setting is about the
affordance and not the verb.

A test in the split-UX suite had been asserting that the frame spends nothing
on buttons. It now asserts the weaker thing with them on and the original,
stronger thing with them off, which says what actually changed rather than
lowering a number until it passed.

One test of mine was wrong in an instructive way: it counted visible panes
across every tab, and panes in a tab that is not on screen were never laid out,
so they carry whatever rect and hidden flag they had last time. The comment on
those fields says exactly that. It counts the current tab now.
</content>
</entry>
</feed>
