<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slosh.git/contrib, branch master</title>
<subtitle>an opinionated terminal multiplexer in C with programmable pane chrome</subtitle>
<id>https://git.sl0p.foo/slosh.git/atom/contrib?h=master</id>
<link rel='self' href='https://git.sl0p.foo/slosh.git/atom/contrib?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/'/>
<updated>2026-10-28T10:19:05Z</updated>
<entry>
<title>brew: pin the build to zig@0.16</title>
<updated>2026-10-28T10:19:05Z</updated>
<author>
<name>Peter Geissler</name>
<email>peter@haxx.in</email>
</author>
<published>2026-10-28T10:17:53Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=58cddb132e75103ad03ce1ce69a7ba7e0ae6e210'/>
<id>urn:sha1:58cddb132e75103ad03ce1ce69a7ba7e0ae6e210</id>
<content type='text'>
homebrew-core moved "zig" to 0.17.0, and the vendored libghostty-vt
rejects any mismatched major/minor, so every brew install broke with
"Your Zig version v0.17.0 does not meet the required build version of
v0.16.0". Installing zig@0.16 by hand did not help: it is keg-only, so
it is never on PATH, and the formula took the "zig" opt path regardless.

Also stop hardcoding the version in the test block; it had gone stale at
0.1.0 and failed against the 0.1.8 binary.
</content>
</entry>
<entry>
<title>release: v0.1.8 paperwork -- formula and PKGBUILD pinned</title>
<updated>2026-09-22T14:21:23Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-22T14:21:23Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=dfdd8199da35f94ae6e81251b1489cb33d6c1504'/>
<id>urn:sha1:dfdd8199da35f94ae6e81251b1489cb33d6c1504</id>
<content type='text'>
</content>
</entry>
<entry>
<title>theme: a name and a directory, not sixty colours in your config</title>
<updated>2026-09-22T10:42:15Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-22T10:42:15Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=faa3fb6ee575a900abc574b0f9ed5ff291761837'/>
<id>urn:sha1:faa3fb6ee575a900abc574b0f9ed5ff291761837</id>
<content type='text'>
Wearing a theme meant pasting its `theme { }` block into config.kdl, or
including a path to a file you had copied there yourself. Both make the
palette a literal in your config, and a literal is the one thing you cannot
change cheaply: not from a script, not from a running session, not by a list
of what is available, and never again from upstream -- the colours you pasted
are the colours that theme had the day you pasted them.

So a theme is a file in a directory now, and a config names it:

    theme_name "phosphor"
    theme { frame_focus "#00ff88" }   // ...but that one colour is mine

theme_name is applied after the includes and before everything the file says
itself, which is the rule includes already follow and for the same reason: the
loader reads a document by asking it for names rather than walking it in order,
so "here" is not a position it could honour, and "what you asked for is the
base, what you wrote is yours" is the rule worth having.

Two directories, yours first: `themes/` beside the root config -- beside the
file that was loaded, so a config somewhere else (SLOSH_CONFIG, or one handed
to --check) takes its themes with it -- and then &lt;prefix&gt;/share/slosh/themes,
compiled in from PREFIX. install(1) has been putting themes there all along
and nothing could read them; now a shipped theme is nameable without being
copied, and a file of yours with the same name shadows it, which is how a
root-owned theme gets edited.

A name, not a path. The directory is what makes a theme switchable, listable
and shadowable, and a path silently does none of those, so `theme_name
"../x.kdl"` is refused with a line pointing at `include`, which still works
and is still the answer for a file somewhere a directory of names cannot
reach. A theme that is not there is one complaint and no more (D9): the rest
of the config applies, because losing your keybindings over a mistyped colour
scheme would be the wrong trade. A theme file is read by the same loader, so
it is watched like any other: saving one reloads the session wearing it, and
the derivations (tab_status_fg, tab_idle_bg) run over the theme's own colours
exactly as before.

Switching without editing anything, over the socket a session already has:

    slosh -s main cmd theme                                # amber default* ...
    slosh -s main cmd '{"cmd":"theme","name":"amber"}'      # now
    slosh -s main cmd '{"cmd":"theme","name":"amber","save":true}'

The session holds the name over later reloads, so saving your config for an
unrelated reason does not put the old colours back; `save` writes the
theme_name line into the file, replacing the one already there and leaving
every other line and comment alone -- dumping the whole config back over
itself would reformat a hand-written file and drop its comments, which is not
a fair price for changing a colour scheme. A name is tried on a throwaway
config first, so a typo costs nothing. An empty name gives the answer back to
the file.

--dump-config stops writing colours: it writes the theme's name and the
colours a config overrode by hand, so a dumped config keeps following its
theme instead of freezing it. --dump-theme is the other half and is new: the
resolved palette as a theme file, which is how you start one from the session
in front of you rather than from an empty file. It is also what keeps
contrib/themes/default.kdl honest -- that file is now the annotated reference
(the commented palette moved there out of config.kdl, where it was 119 lines
of colour in the middle of the prose), and a test compares it against the
compiled-in one.

While in there: tests/test_themes.py's "every theme sets every colour" guard
had been grepping for `&amp;c-&gt;`, the spelling before the colour table moved to
offsetof, so it had been finding zero colours and passing for months. Fixed,
with the derived and opt-in colours exempted for the reasons they are derived
and opt-in, and with a check that the guard found a table at all.
</content>
</entry>
<entry>
<title>tabs: idle tabs you can actually read across the room</title>
<updated>2026-09-22T10:17:33Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-22T10:17:33Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=e18976b315baeb8914970bd8e54887cdb05faefc'/>
<id>urn:sha1:e18976b315baeb8914970bd8e54887cdb05faefc</id>
<content type='text'>
Seen next to the accent, the first plate was too polite to do the job it was
added for: a 30% lift off the background under labels in the same #45454a the
idle frames use. From another monitor the strip still read as one dark band
with a blue block in it.

Both ends move. tab_idle leaves the ambient chrome grey and becomes #8a8a95,
because a tab you are not in is a place to go and has to be legible at a
glance, where a dimmed pane border only has to be findable. The plate follows
it to 43%, which is not a taste constant but a contrast ratio: the same step
taken from a dark background upward and a light one downward lands at about
1.9:1 either way, so paper's #bdbebe on near-white and the default's #3b3b40
on black are the same amount of plate.

The six themes in contrib named their idle tab colour as their frame grey, so
each gets the same move in its own family -- 40% of the way from that grey to
the colour the theme writes text in -- and their plates follow by derivation:
amber #a67c26, mono #909090, paper #666a6e, phosphor #4a9c5d, slate #70789c,
sl0p the house #8a8a95. Nobody who named a colour loses it; the derivation
only ever fills in a theme's silence.
</content>
</entry>
<entry>
<title>sidebar: a status colour mixed from the theme, not the chrome's flat grey</title>
<updated>2026-09-10T14:38:09Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-10T14:38:09Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=8df6491b9fe70e8fb000d27d1ada6577f6873515'/>
<id>urn:sha1:8df6491b9fe70e8fb000d27d1ada6577f6873515</id>
<content type='text'>
tab_status_fg defaulted to the ambient grey on the argument that the
slant already carried the distinction. True, and it looked it: the
frame, the inactive labels, the pane count and the statuses were one
colour, and the liveliest thing in the sidebar read as furniture.

It is now 40% of the way from tab_count to tab_hover -- not the grey of
the chrome round it, not the full accent it would shout in. Derived the
same way rather than picked, so it lands in each theme's own family: a
monochrome theme mixes two greys and stays monochrome, phosphor stays
green, amber stays amber, and none of the seven in contrib needs a line
adding to it. That the mix cannot invent a hue is the same argument the
italic rests on, so both signals survive a colourless palette.

tab_status_bg is still unset: a band is opt-in, and none is what a
translucent terminal wants.
</content>
</entry>
<entry>
<title>sidebar: statuses wear italic instead of an indent, and can wear colour</title>
<updated>2026-09-10T14:32:10Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-10T14:32:10Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=a2d08f4876226446c0052f033e8afea2f2ffbbf1'/>
<id>urn:sha1:a2d08f4876226446c0052f033e8afea2f2ffbbf1</id>
<content type='text'>
Three columns of indent is a fifth of a sixteen-column sidebar, spent
saying 'this belongs to the row above'. The slant says it in none: a
status now starts in the same column its tab's name starts in, and is
set in italic. That also survives the monochrome themes in contrib,
where a colour-only distinction would have had nothing to spend.

tab_status_fg / tab_status_bg are there for themes that do have colour
to spend. The fg follows tab_count when a theme does not name it -- the
same declared/derived split apply_scrolled makes -- so the six themes
in contrib get coherent status rows without a line added to any of
them. The bg is unset by default, because a band is opt-in and 'none'
is what a translucent terminal wants; the row is padded so a band that
*is* set covers the row rather than the words on it.

Two things fell out. The padding loop existed three times and is now
pad_cells. And cb_color wrote #000000 for an unset colour, so
 quietly pinned attach_bg -- 'gray
ink on the terminal's own background', says its comment -- to a black
band. Unset colours are now written commented out, the same trick the
states block uses for what it wants re-derived rather than pinned.
</content>
</entry>
<entry>
<title>build: a vendor bump rebuilds libghostty-vt, everywhere it is consumed</title>
<updated>2026-09-10T09:19:54Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-10T09:19:54Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=16620e7fd9a6780756dc956466c3579e5bb2f384'/>
<id>urn:sha1:16620e7fd9a6780756dc956466c3579e5bb2f384</id>
<content type='text'>
Three stale-build landmines, all found by shipping v0.1.7 -- the first
release where new code (GhosttySearch) actually needed the vendor bump
of 2026-09-01:

- $(VT_LIB) had no prerequisites, so an existing .a *was* the build:
  the macOS builder compiled pane.c against zig-out headers from before
  the bump. The vendor manifest is now the prerequisite; a re-vendor
  rewrites it, so a bump rebuilds the lib and its installed headers.

- web/demo had the same guard and also never passed -Dversion-string:
  upstream's build.zig ran git describe in our repo, and on the tag
  checkout web/publish builds from, a slosh tag is a fatal version
  mismatch. Both fixed; both had hidden behind a stale build/vt.

- The builder's zig-pkg (excluded from the sync, and left half-empty by
  a once-interrupted push) is an input, not a cache: it is now synced
  separately and additively, so a bump's new packages arrive and a
  partial local tree cannot maim the builder's copy.
</content>
</entry>
<entry>
<title>release: v0.1.7 paperwork -- formula and PKGBUILD pinned</title>
<updated>2026-09-10T09:13:44Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-10T09:13:44Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=d9a04772fc4797ff20dccefc6cc4f68c6c040feb'/>
<id>urn:sha1:d9a04772fc4797ff20dccefc6cc4f68c6c040feb</id>
<content type='text'>
</content>
</entry>
<entry>
<title>release: v0.1.6 paperwork -- formula and PKGBUILD pinned</title>
<updated>2026-09-07T14:40:41Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-07T14:40:41Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=e918e4385c5e5cf944af53932f9a60eca03c1ac0'/>
<id>urn:sha1:e918e4385c5e5cf944af53932f9a60eca03c1ac0</id>
<content type='text'>
</content>
</entry>
<entry>
<title>docs: a way back to slosh.foo from every page; README links the site</title>
<updated>2026-09-02T14:57:12Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-02T14:57:12Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/slosh.git/commit/?id=8aea65b9d9c0ed704a7171aa69ee2c615d818486'/>
<id>urn:sha1:8aea65b9d9c0ed704a7171aa69ee2c615d818486</id>
<content type='text'>
The docs header gains a right-aligned slosh.foo link (absolute, so a
locally rendered build/docs points somewhere real too), and the
README says the website exists, which it never did.
</content>
</entry>
</feed>
