| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two things wrong with the first one, and both are about it being a modal
rather than a pane that happens to float.
The close button was invisible. It was drawn in the pane button colour on the
finder background, and in the default theme those are the same value --
#45454a on #45454a -- so it only appeared when the pointer landed on it and
the hover colour took over. That is the hazard of borrowing names from
another surface: each one is right, and together they are nothing. A modal is
its own surface now, with its own names (modal_bg, modal_fg, modal_border,
modal_title, modal_button, modal_button_hover), a dark panel a shade lighter
than the dimmed screen, a border in the accent, and a button chosen to be
visible *without* the pointer on it. All six themes set them.
And nothing behind it moved, so it read as another pane rather than as
something in front. There is a scrim now, `modal_scrim` (0..255, 120 by
default), and the pleasing part is that it is not a new mechanism: it is the
shader pass aimed at the screen instead of at a pane. Same dim, same
materialisation of default colours, no special case. It goes down after
everything else is painted and before the modal, so the modal is the only
thing at full brightness -- which is the whole idea, and is asserted rather
than assumed.
The shape is now reusable: modal_frame() draws the box, title, close button
and hit, and returns the rect inside it; draw_scrim() is one line above it.
The next modal is a function call and looks the same as this one.
The finder is deliberately left alone. It is a picker rather than a modal --
it navigates, where a modal here dismisses on any key -- so unifying them
would be making two things one because they are both rectangles.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A pane whose program exited was reaped before the next paint. The pane went,
and with it everything the program had printed -- including, always, the one
line that would have explained why it stopped. Close the last one and the
session went too, so a mistyped command in a fresh session closed the
terminal you were typing in.
Now the pane stays. It keeps its contents, writes one line into its own
backlog saying how it ended -- `[process exited: status 3]`, `signal 9` --
says the same thing in its frame and in the status line, and offers the two
verbs that still mean anything:
╰ exited: status 3 ──────────────────────────────[re-run]─[close]─╯
`[re-run]` runs the same argv in the same cwd in the *same pane*: same id,
same node in the tree, same terminal. Nothing that referred to that pane has
to be told anything, and the run that ended stays above the new one in the
scrollback, which is what makes comparing two runs possible at all. C-a r
and {"cmd":"rerun"} do the same thing; a live pane is refused rather than
restarted, because "run it again" is not a request to kill something.
Those buttons are the OSC 5577 row, not a second mechanism. A dead pane's
own buttons are inert -- a click would write a report into a closed pty --
so the row is given over rather than added to. `close` is listed last, so it
is drawn rightmost and is the one that survives a narrow frame: being unable
to dismiss a dead pane is a trap, being unable to re-run one is an
inconvenience.
`dead` is a shader state now, which D13 said it could never be: it named a
frame that could not be drawn, and now there is one. Dead panes drain to
grey by default, so a wall of them reads at a glance. A collapsed header
says "exited" in words as well, because the shader pass does not reach one
and a flattened tab draws nothing else of a pane.
Two things about this are load-bearing rather than incidental:
- the pty fd is closed the moment EOF is seen. A pane that outlives its
program stays in the poll set, and an fd at EOF is readable forever: the
session would spin a core behind a pane that looks idle.
- the exit status is collected with a bounded wait, never a blocking one.
EOF means the program already closed its fds, so it is on its way out and
a few hundred microseconds wins that race. A blocking waitpid would hang
the whole session on one program that closes its terminal and keeps
running; losing the race costs the words "status 0" and nothing else.
`keep_dead false` restores the old behaviour for a one-shot layout that
wants it. `panes` reports alive/exit_code/exit_signal, so a script can find
the pane whose command failed and rerun it.
|
|
|
Six themes, each setting every colour the config knows about. A theme that has
fallen behind silently keeps the compiled-in default for whatever it forgot,
which looks like a bug in the theme rather than a missing line in it, so a test
compares each file against the names config.c actually parses.
contrib/theme-tour applies one to a running session, or cycles the lot. It does
that by writing over the file the session was started with and letting the
config watcher notice, which makes the showcase a demonstration of the watcher
as well.
HANDOVER.md is for the next context. It deliberately does not restate DESIGN.md
or the README; it is the part that was only learnable by getting it wrong —
which state is derived and which is intent and what happens when you confuse
them, the dwell repaint list, that glyph width and glyph weight are different
problems, that settle() in the harness is a sleep in disguise, and that a test
pinned to a coordinate it does not care about will eventually look like a
regression it is not.
|