| Commit message (Collapse) | Author | Age |
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
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.
|
| | |
|
| |\ |
|
| | | |
|
| | |
| |
| |
| |
| |
| | |
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.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
+Grep, +Search and every language answer render rows like
src/look.zig:718:12-16 fn grepText(path: []const u8, text: []const u8...
— a location, a space, and a piece of some file. The location names the file,
the file names the grammar, and the rest of the row is a fragment of that
language, so a grep over Zig reads as Zig and one Markdown row in the same
buffer does not pretend otherwise. The location itself is left uncoloured: it
is not code, and painting it as code is how a path starts looking like a
keyword.
`look.parsePathLine` decides what counts as a location — the same primitive
n/N already walks these buffers with, so the two agree by construction about
which rows are locations. NOT `lookableLineSpan`, which is n/N's whole
heuristic: it calls `resolve`, and a `realpath` per row per scroll is not
something a render path can afford. A bare filename is refused too; only
`path:line` counts, or a prose line whose first word ended in `.md` would
colour the rest of a sentence.
THE BUFFER IS COLOURED WHOLE, ONCE, WHEN IT IS FILLED. An adversarial pass
measured the obvious per-window implementation and it was untenable: the rows
are independent, so a window pass buys no fidelity, only amortisation, and
pays a burst on every scroll that outran the covered range. Grammars compile
their highlights query on first use — zig 26.9ms, cpp 18.9ms, rust 14.3ms —
so a polyglot grep showing six languages stalled a frame by 66ms, moving a
cost the syntax module had deliberately put on "opening a file" onto a scroll.
It also raised tree-sitter's allocation rate 3.5x (8,785 per refresh against
2,454) into a 16 MiB bump arena that only reclaims LIFO, so ~16 scroll
re-highlights exhausted it — and that arena is shared with real file panes, so
a results pane could evict editing. A grep is capped at 512 rows; colouring it
once makes the covered-range check true forever after and scrolling free.
The rest of that pass, in the same spirit: injections off for a single row
(both build a SECOND parser, per fenced block and per inline node, which is
absurd for one truncated row that almost never contains a fence), one query
cursor for the buffer instead of one per row, a one-entry extension memo so
non-matching rows stop paying a 29-spec scan, and NO highlights at all when
nothing painted — an all-zero run is not the same as none, and it defeated
`recolorSyntax`'s fast path, making every +Help and +Config walk its graphemes
every frame to paint nothing.
One correctness bug from the same pass: a failed `setLanguage` has already
nulled the parser's language, so leaving `held` on the previous grammar made
every later row of it skip the call and silently lose colour.
Documents keep `.source`: a New scratch and a real file are output-shaped but
have one language and an edit per keystroke, and `saves` is the line between
the two.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016Q4RATpafkwahrovHQLKRf
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
A message row is cleared by the next keystroke, so anything reported while you
were looking at another pane was gone before you could read it — a save that
failed, a watcher's reload, a builtin's complaint. `setMessage` now records
into a fixed ring first: no allocation and no failure path, because it sits
underneath `reportError`, which is reached from sites that are reporting an
allocation failure. `Messages` (`SPC h m`) reads it back oldest-first.
Three things an adversarial pass found, each of which defeated the feature:
PROGRESS IS NOT A MESSAGE. A language server emits `Indexing 47%` several
times a second, and every tick is a distinct string BY CONSTRUCTION, so no
de-duplication can collapse it: at the client's one-per-150ms throttle it
takes about nineteen seconds to push every real message out of the ring. A log
that one indexing run empties is not a log. That path is `setStatus` now —
the row, and nothing else.
THE CLOCK MADE EVERY HOST MESSAGE UNIQUE. `message.stamp` prefixes `HH:MM:SS`,
so `saved /x.zig` at 14:32:07 and at :09 compared unequal and the ring filled
with rows that look identical and each say (x1) — exactly the case the
de-duplication exists for. It compares `message.body` now, the row without its
clock, and the newest wording wins so the row carries the last time it
happened rather than the first. It also keys on the PANE (one pane's failure
must not be recorded as another's) and compares the truncated form, so two
identical messages over 256 bytes stop being two rows.
AND THE CAPACITY BELONGS IN limits.zig. 128 entries is 32.75 KiB that is
allocated whether or not anybody reads it — 8.5% of the ESP32-P4's whole
384 KiB heap, about the size of its effect ring. The board takes sixteen.
The builtins/leader goldens move because the listing gains a row, and
builtins.snap middle-clicks a SCREEN COORDINATE that Tutor moved out of; both
updated selectively and verified against a fresh run.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016Q4RATpafkwahrovHQLKRf
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
`|` was the only one of helix's five. The other four differ in exactly two
things — whether the selection is stdin, and where the output lands — so they
are one action carrying a `PipeBehavior` rather than four code paths:
| stdin is the selection, output REPLACES it (had this)
A-| stdin is the selection, output discarded shell_pipe_to
! no stdin, output inserted BEFORE each selection shell_insert_output
A-! no stdin, output appended AFTER each selection shell_append_output
Each arms the same visible tag-tail prompt with its own marker (`|`, `|-`, `!`,
`!+`) so the prompt says which one you are in — they take the same command line
and do very different things to the buffer.
Two helix rules came with them. A behaviour that sends no stdin runs the
command ONCE and every cursor gets that one answer (helix's `shell_output`
cache): ten cursors and `date` give ten identical stamps rather than ten forks
racing to produce one. And a command that put a trailing newline on a selection
which did not have one has it taken back off — that is what keeps a one-line
`| tr a-z A-Z` from becoming two lines. The existing multi-range test moved
with that rule and now pins it deliberately.
In all three writing behaviours the OUTPUT is what ends up selected, keeping
the original range's direction, so an operator can follow straight on from what
the command just produced.
`$` (`shell_keep_pipe` — drop the selections whose command exited nonzero) is
still missing: it needs a per-selection verdict and the runner's answer is
atomic. Noted in docs/helix-keys.md beside the `$` divergence already there.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016Q4RATpafkwahrovHQLKRf
|