| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
| |
Four rows deep at 60 a row instead of three at 45: the edge row is nearly
gone (#0e0e0e from white) and the melt reads as "there is more this way"
rather than as a rendering artefact. The quarter-viewport cap, the
(above > 0) gate and everything else about the derivation stand; a config
that writes its own scrolled chain is untouched, as ever.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The out-of-the-box look, rethought as one piece:
- the compiled-in palette calms down: muted blue #7aa2f7 on the same
neutral darks, with the colours that mean something kept semantic --
amber bell, red-orange dead. sl0p stays one include away as the house
style, and contrib/themes/default.kdl is the starting point written
down (theme-tour shows it).
- derived state defaults now actually follow the theme: the scrolled
wash is rebuilt from scroll_bg after the theme block (it used to bake
the compiled accent), and declaring a state -- in any file of an
include chain -- still wins. The dump writes derived states as
comments so C-a e cannot pin what is meant to keep following.
- a bell you can see: the frame blinks three times in theme's bell
colour then breathes until answered, and a soft diagonal shimmer --
the bell colour halved towards default_fg, width breathing on a sine
-- crosses the body for the same 900ms. bell_indicator false silences
all of it; states { bell { } } replaces it like any state. since
carries the clock dependency, so an idle session pays nothing.
- scrollback says where it continues: while scrolled, the viewport's
top and bottom rows melt towards an edge with content past it and
turn solid at the buffer's end. New expression variables above/below
(lines hidden past each edge, own dependency bit, cached per scroll
position), carried in shade_ctx_t -- SLOSH_SHADER_ABI 3 -> 4.
- expressions survive the dump: a program keeps its source and cb_chain
writes it back, so amount="(y % 2) * 40" no longer dumps as a number.
- headers move to include/, -Iinclude everywhere; the plugin Makefile's
SLOSH var becomes SLOSH_DIR because slosh exports SLOSH=1 into every
pane it runs, and building from inside a session read that as a path.
- comment drift culled where features outran the prose, and the
derivation boilerplate folded into derived_pass()/ctx_scroll().
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
sl0p + pty was error-prone to type and the zero made it worse; slosh
(slop + sh) is one syllable, impossible to typo, and slosh.foo is ours.
Mechanical rename everywhere it appears: binary, env vars (SLOSH,
SLOSH_SESSION, SLOSH_BIN, SLOSH_CONFIG), socket dir (/tmp/slosh-<uid>,
$XDG_RUNTIME_DIR/slosh), config path (~/.config/slosh), header guards,
src/sl0ppty.h -> src/slosh.h, contrib/sl0ppty-dev -> contrib/slosh-dev,
the driving-slosh skill, docs and tests. The sl0ppi fork references and
the sl0p theme stay: one is history, the other is the brand.
The rename surfaced a latent bug in test_osc5577: the hello-reply
answer always appeared on screen twice (ECHOCTL echo plus cat -v), but
a seven-character implementation name happened to wrap the second copy
across the 60-column boundary, so counting substrings in wrapped text
found one and passed for the wrong reason. A five-character name moved
the wrap and exposed it. The loop guard itself is correct -- with echo
off before the request there is exactly one reply -- so the test now
counts on de-wrapped text and tolerates the pane's own echo.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Keeping every dead pane was too much. Split off a shell, do something in it,
type `exit` -- and you are left with a corpse to dismiss, which is fussiness
rather than information. You know what happened. You did it.
So the policy has a line now, and the line is the *command*, not who made the
pane. A pane told to run `npm run dev` is part of the session's shape: when it
dies you want the error it left and the button that runs it again. A pane that
is a shell is finished when you say so.
Not provenance, because a shell is a shell whether a layout file made it or
C-a \ did -- and that also means a session restored from dump-layout behaves
like the one it was dumped from, since the dump writes `command=` only for
panes that had one. The distinguishing mark turned out to need no new state:
pane_label() already holds the command a layout gave it and is empty for a
plain shell, so this is a policy over something already recorded.
`keep_dead` is now `commands` (default), `all` or `none`, and still reads
`true`/`false` as `all`/`none` -- that was the shipped spelling and a config
saying it should keep working rather than quietly changing behaviour.
Most of the diff is tests. The dead-pane suite had been written against the
session's own pane, which is a shell under the new rule, so it was testing the
half of the policy that now says "reap it". They run commanded panes from
layouts instead, and the pair of cases -- a shell you split off goes, a
commanded pane stays -- sits together in one place so the rule is legible in
the test file too.
One of those layouts wanted an escape sequence, which has to be written `\\033`
so KDL's unescaping hands `\033` to the shell. Written singly the shell prints
`033[38;2;...` and the test reads as "the colour stopped working".
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`dim_unfocused 60`, on by default, 0 to turn it off.
The dimming itself was already possible -- `states { unfocused { dim } }` --
and deliberately not the default. The argument then was that ambient contrast
is a taste, and shipping a taste as a default is how a tool earns a
reputation for fighting you. That argument was mostly about the escape hatch:
"turn it off" meant knowing the states block exists and what a shader chain
is. A single number does not have that problem, so the objection goes away
and the default can be the one most people want.
The knob and the table are one mechanism -- the knob fills the unfocused
chain in when the config has not -- so writing the chain by hand still wins,
including writing an empty one. `states { unfocused { } }` means nothing at
all, and is not quietly refilled, which needed the parser to distinguish
"said nothing" from "said none".
60 by choice: white text lands on #c3c3c3, which reads as "not this one"
without reading as "not available", because half the time you are reading the
other pane. Picked by looking at 40, 55, 70, 90 and 120 rather than by taste
alone.
The tests that had to change are the interesting part. Six in test_shaders.py
asserted "back to green after the drag", which is no longer what normal looks
like -- and rewriting them to compare against a snapshot taken before the
drag failed too, because a drag *moves focus*: press a title and that pane is
yours, so the two panes legitimately swap appearances across one. They assert
the rule now (the pane you are in keeps its colour, the others are pushed
back), which is both what we mean and immune to the next change of defaults.
test_states.py's "an unfocused pane is left alone" is inverted, with the
reason written where the assertion used to be, because a test that flips
should say why it flipped.
|
|
|
The shader machinery has been able to do this since it existed, and shipped
an opinion about exactly one state. Now it ships three, and the line between
those and the rest is the point:
a pane that is *not live* gets a default -- dead, suspended, scrolled. In
all three the cells are showing something other than a running program's
present: output from something that has exited, a pane that never started,
or the past. None of that is discoverable by looking unless something says
so, which is the whole argument for the feature.
a pane that is merely *not the one you are in* does not -- unfocused, and
one being dragged. That is ambient contrast, which is a taste, and a taste
shipped as a default is how a tool gets a reputation for fighting you. It
is one line of config away for anyone who disagrees, and there is now a
test asserting we have not quietly changed our minds.
So: suspended is greyed and dimmed (inert, still legible -- its contents are
the command it is waiting to run), and scrollback takes a 9% wash of the
scrollback indicator's own colour, so a theme moves the indicator and the
wash together. Checked against phosphor, amber and paper: each gets its own
hue rather than a hardcoded one.
The other half is the gap this leaves. A collapsed header never reaches the
shader pass -- a header is chrome and shaders colour contents (D13) -- so
collapsing a tab used to hide precisely the facts the colour exists to show.
The header now carries them in words, in the same order the status line ranks
them: `exited: status 3`, `not started`, `▲ 12`.
tests/test_states.py asserts the line in both directions, including that an
unfocused pane is left exactly as it was, and that a flattened tab still says
which of its panes never started.
|