<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pardes.git/test/snapshots/lspdebug.golden, branch main</title>
<subtitle>Pardes</subtitle>
<id>https://git.0x4200.cafe/pardes.git/atom?h=main</id>
<link rel='self' href='https://git.0x4200.cafe/pardes.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/'/>
<updated>2026-10-01T03:12:17Z</updated>
<entry>
<title>Release Pardes 0.6</title>
<updated>2026-10-01T03:12:17Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-30T01:59:43Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=6d148bb9c433814835935ead30020e43781b7f03'/>
<id>urn:sha1:6d148bb9c433814835935ead30020e43781b7f03</id>
<content type='text'>
Merge: audit top-five cuts + tag sweeps + Config/DumpConfig (on the audit bug fixes C9, C2).

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Config opens the startup file, DumpConfig the settings report, and the workspace tag reads Dump Themes Config Debug Exit</title>
<updated>2026-10-01T03:12:17Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-30T01:27:38Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=d4960472375ea68f709c56a677d8a37571419ff7'/>
<id>urn:sha1:d4960472375ea68f709c56a677d8a37571419ff7</id>
<content type='text'>
Config (SPC f c) opens init, found as the settings report finds it
(opts.startup_config_path: $XDG_CONFIG_HOME/pardes/init or
~/.config/pardes/init, and the macOS and Windows paths config.md gives). A
pane that already holds it is gone to instead; a file on disk is looked at;
with none, an empty pane is named for it, and Save makes its directory and
any above it first (File.make_dirs, fs.makeDirs) before writing. Without a
configuration directory it says so and opens nothing.

The report Config used to open, the startup path and every live setting, is
DumpConfig, in a +DumpConfig pane. No alias keeps the old meaning.

The workspace tag's default words put Themes where NextColor was, NextColor
staying a builtin, and Config beside it. A tag the user edited is kept as it
was: a dump stores only an edited one (topbar_custom), and a restore puts
back only that.

theme.snap types NextColor onto the workspace tag to click it, and tagnav's
walk back to Dump takes five long-word steps. The rest of the re-recorded
goldens differ in the workspace words and their widths only.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Zig files go to zls as a child process through the protocol client, as every other language does: the in-process ZLS backend goes</title>
<updated>2026-10-01T03:12:17Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-30T01:31:27Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=7e8e2655567cab1c28597f44d0aec79e46b0deb8'/>
<id>urn:sha1:7e8e2655567cab1c28597f44d0aec79e46b0deb8</id>
<content type='text'>
lsp_zls.zig (1,522 lines), the zls dependency, build.zig's zls wiring and the import graph it baked into the options only for it, and main.zig's reference go. lsp_client's table gains a zls row (PARDES_LSP_ZIG overrides it); Hover, Rename, Diagnostics, WsSymbols, Lspinfo and gd answer through it (checked with lspprobe and the snapshots against zls 0.16.1-dev). What changes for a user: zls must be on PATH; a completion's rows are zls's candidates at the cursor, where the linked analyser gave each one's declaration; document symbols carry no signature. The Zig snapshots (lsp, lspcomplete, lspcompletemoved, lspdebug, lsprelpath) run the real zls now: lspdebug reads the client's explain and report, lsprelpath spells gr's rows where it spelled a completion's, and their goldens are recorded again (stable over three runs). Lspinfo still opens with its backend line. The ReleaseFast tty binary is 105.35 MB to 96.28 MB, the Debug one 296.5 MB to 245.9 MB. docs/lsp.md, web.md, design.typ and the README say so.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Exit quits and Kill stops commands, as in acme</title>
<updated>2026-10-01T03:12:14Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-28T14:22:53Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=1c3842f136b9f98fae784559ec12d66d629c5909'/>
<id>urn:sha1:1c3842f136b9f98fae784559ec12d66d629c5909</id>
<content type='text'>
Kill quit the editor, which in acme is Exit; acme's Kill stops the
commands it started. Exit now quits as acme's does (exec.c, rowclean):
it refuses once, naming each pane with unsaved text, and quits when
asked again with nothing edited since (a small scratch is not asked
about). Kill, bare or with names, stops the commands pardes typed into a
terminal (an exec, a middle click, a pty/run) while their shell's marks
say they run, by SIGTERM to the terminal's foreground job, never to the
shell (acme posts the kill note, which terminates). Both are session
builtins; the topbar's Kill becomes Exit, same width, and every golden's
topbar row changed by exactly that word (checked line by line); the
builtins script scrolls one more row for the index's new line.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Notices become tagline bands at the top of the body</title>
<updated>2026-10-01T03:12:14Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-22T05:21:03Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=43b9d696f9e25ad7589527b91a74666e71ff0472'/>
<id>urn:sha1:43b9d696f9e25ad7589527b91a74666e71ff0472</id>
<content type='text'>
A message, a leader chord and a prompt used to share one row of body text at
the bottom of a pane, wearing the tagline font and nothing else about a
tagline. Now each one is a TagLayer of its own, emitted through the same
renderHeaderLayer the pane and column tags go through, so it gets the tagline
height, the small-font metrics, the band offset and the border for free --
none of which a body-grid row can have by changing its font role. The text is
right aligned. The prompt stays on the canonical grid because it owns a
cursor, and a cursor has to sit on a real cell.

The body starts BELOW the bands rather than under them, the way tree-sitter
context rows already worked. Pane.body_offset is how many rows they took and
Pardes.bodyTop(pane, rect) is the one place that answers "where does the body
begin" -- replacing fifteen copies of `if (tag_bottom) r.y else r.y + BOX_H`
spread across the paint, hit-test, scroll, PDF and image paths, which is what
let the bands and the text under them come adrift. Every notice is painted on
the grid as well, because the grid is what a terminal client draws and a band
it cannot see is a message it never gets; the GUI skips grid cells a tag layer
covers, so nothing is drawn twice.

Three bugs the bands exposed, fixed here:
  - a prompt band flush with the right edge put its caret one column past the
    pane, which the detached wire refuses -- so every frame was dropped for as
    long as the prompt was open. The band now reserves that column.
  - a click on a band mapped to Sel row 0, which is the TAG row: clicking
    chrome expanded a word out of the tagline and ran it as a builtin.
  - a watched file reloading under the editor changed the core without going
    through update, so needs_frame was never set and the reload was never
    drawn. Pardes.invalidate() is the name for that, and the file and theme
    reloads call it.

A session can now drive its own 9P namespace instead of being refused one:
ownMountSuffix answers what a path names inside this editors own tree and
resolve, readLimit and write serve it from memory rather than making the
syscall that never returns. The match is anchored to whole components under
the registrys 9p/pardes/&lt;name&gt;, because a bare /pardes/&lt;name&gt; anywhere in a
string would claim ~/src/pardes/&lt;name&gt;/README -- and, before write learned the
same trick, write the trees bytes over the real file. readFileLimit and
writeFile refuse instead, having no core to answer from.

A toggle setting SETS when given `on` or `off` and only flips when it is bare,
so the report LocationsConfig prints can be fed back as configuration and mean
what it says.

Snapshots: 97/98, from 0/98. The goldens were several commits stale and 17
scripts had stopped running; `config &lt;line&gt;` is a new script command that
appends to the per-script startup config, so a script that clicks body
coordinates pins `Verbose off` instead of counting the rows an announcement
moves. nested-optout is left failing on purpose: two levels of nesting prepend
vaxis F3 codepoints to typed lines, which is a real bug and is written down in
docs/divergences.md with a repro.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>trunk: resume before the Reload experiment</title>
<updated>2026-09-15T20:24:42Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-11T15:38:56Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=682e237df7e8b22f820d14a4adee58e6e2f84268'/>
<id>urn:sha1:682e237df7e8b22f820d14a4adee58e6e2f84268</id>
<content type='text'>
Empty marker on the last pre-Reload change. Keep the Reload experiment on reload (3801914), its first change on reload-start (200a1fc), and the unfinished performance investigation on reload-perf-wip.
</content>
</entry>
<entry>
<title>Refactor panes and filesystem; replace FUSE with 9P</title>
<updated>2026-09-07T16:59:12Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-06T21:11:36Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=60367d8fe23f6af98ec28e3cf6c2094dfe332df0'/>
<id>urn:sha1:60367d8fe23f6af98ec28e3cf6c2094dfe332df0</id>
<content type='text'>
Consolidate pane, layout, memory and host code. Serve 9P by default over Unix sockets, with runtime mounts and optional TCP/QUIC transports. Remove FUSE and obsolete proof-of-concept examples.

Fix highlighting and terminal-history performance, expand differential and stress-test infrastructure, sort navigation results while preserving the next occurrence, add syntax-colored Braille minimaps, remove SPC-k, and document 9P interaction as a repository skill.
</content>
</entry>
<entry>
<title>lsp: a protocol client for every other language, narrated on the message row</title>
<updated>2026-09-01T14:24:12Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-01T12:23:53Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=ae9325a5cb128d0d952afb8f9feaaca68e5e37a2'/>
<id>urn:sha1:ae9325a5cb128d0d952afb8f9feaaca68e5e37a2</id>
<content type='text'>
The seam grows a second backend: src/lsp/lsp_client.zig speaks JSON-RPC to
child language servers — rust-analyzer, clangd, gopls, tsserver, pyright are
rows in a spec table — while the in-process ZLS analyser keeps .zig. One
reader thread per server owns the socket, routes responses to a mailbox
under the conn mutex (monotonic condvar), answers server-to-client requests,
feeds the diagnostics store, and narrates $/progress and state changes
through a status sink both native shells post to the transient message row:
"rust-analyzer: cargo check 88% 955/1083" lands where a save narrates, with
the same clock. Chatty progress is throttled and deduplicated; settled
states always land, which is also what makes the goldens deterministic.

Nothing wedges and nothing healthy dies: waits are deadline-bounded, a
timeout cancels and returns no rows, three consecutive timeouts restart the
server ONLY while it is idle (an indexing server is narrating its own
excuse), spawn and handshake failures back off 10s to 2min, a crash shortly
after ready counts as a failure, and only a missing binary disables a spec.
PARDES_LSP_{RS,C,GO,TS,PY} override binaries; empty disables; the snapshot
harness pins RS to test/lspmock.zig and empties the rest.

Mutating answers really mutate now: the @put record beside rename @edit
carries per-range text, so = applies the formatter (both backends) and a
same-file WorkspaceEdit rename applies atomically, one undo step, narrated
("renamed 2 range(s)"); a multi-file rename previews as rows instead of
half-applying. Malformed responses fail closed: coordinates validated not
clamped, one bad TextEdit poisons the whole edit set, poison frames kill
the connection instead of buffering forever, decoded control bytes reject a
uri, hierarchy items too deep to reserialize are skipped.

Four kinds helix does not have, on SPC l: c/C incoming/outgoing calls (rows
are call sites), t/T super/subtypes. Pull diagnostics (3.17) preferred when
advertised. Help gains a language-keys footer for the motions no builtin
row could carry; lsp.rel and look.grep now share one path-shortening rule.

zig build lspprobe drives the seam from the CLI (comma-separated kinds share
one server); measured against a 1083-crate workspace warm: gd 26ms, gr 213
rows 165ms, incoming calls 212 sites 197ms, document symbols 670 rows 347ms.
docs/lsp.md tells the whole story; lsp-evaluation.md gets an addendum.
</content>
</entry>
<entry>
<title>tests: a capture is a delta and a click names its word, so a tagline edit stops rewriting the suite</title>
<updated>2026-08-25T15:28:58Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-08-25T14:05:21Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=e5f9e172330bc4500995ddd5954ed94f94e07af6'/>
<id>urn:sha1:e5f9e172330bc4500995ddd5954ed94f94e07af6</id>
<content type='text'>
</content>
</entry>
<entry>
<title>builtins + config: Save reaches every pane holding text of its own, and takes a path argument</title>
<updated>2026-08-25T12:42:07Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-08-25T02:00:52Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=28c70cabb6ceb7e5fecfd74f6984f5a995269f01'/>
<id>urn:sha1:28c70cabb6ceb7e5fecfd74f6984f5a995269f01</id>
<content type='text'>
</content>
</entry>
</feed>
