| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
runtime
syntax.zig points the tree-sitter runtime at a Zig allocator, but the
grammars' external scanners did not follow it. A grammar's
tree_sitter/alloc.h maps ts_malloc to the runtime's current allocator only
when TREE_SITTER_REUSE_ALLOCATOR is defined, and plain malloc otherwise, so
every scanner's state and its arrays came from libc. Five scanners (bash,
markdown, markdown_inline, python, typst) also call malloc, calloc, realloc
and free by name.
build.zig now compiles every grammar with TREE_SITTER_REUSE_ALLOCATOR and
forces in src/tree_sitter_heap.h, which includes stdlib.h and then defines
the four names as calls through ts_current_malloc and friends. A header
forced in from the build rather than a patch to the grammars keeps zig-pkg
pristine. No grammar archive refers to libc's allocator any more; only the
runtime does, for its defaults. A scanner frees only what it allocated
itself, and the syntax tests that create and destroy a parser for every
grammar under a leak-checking allocator pass.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
C's malloc, calloc, realloc and free over a Zig allocator were written three
times: syntax.zig's for tree-sitter, pdf.zig's for MuPDF, and gui.zig's for
FreeType and HarfBuzz. They are now one, src/c_heap.zig's Heap. Each hook
names the allocator variable its heap reads; gui.zig exports its heap under
the ui_malloc names font.c and HarfBuzz call. It is a module of its own
because pdf.zig is the MuPDF module, and a file cannot belong to that module
and the core's at once.
A block starts with a 16-byte header holding its size and the allocator that
made it, so it goes back where it came from even after the heap is repointed,
as the fonts' copy did. The fonts' copy carried the 16-byte Allocator itself
in a 32-byte header; here the header holds the allocator's index in a table of
every allocator a heap has used (entries are published once and never change,
and a heap remembers where its current one was last found). The difference is
measurable: with the 32-byte header, pardes-pdf-bench's filtered page render
at 96 dpi took 1.1% longer than before this change, slower in 15 of 16 pinned
rounds in two separate runs, and highlighting all of src/pardes.zig (305k
tree-sitter blocks) up to 0.6% longer, against an A/A pair within 0.7%. With
the 16-byte header both are back within the A/A pair's noise.
Two other things change. For tree-sitter and MuPDF, a block made before the
allocator was repointed now goes back to the one that made it rather than
through the current one. For the fonts, realloc(block, 0) now frees and
returns null, as glibc's does and as the other two copies already did;
neither FreeType nor HarfBuzz asks for it. The heap's test replaces the
tests of the old copies.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
| |
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
|
| |
|
|
| |
walk wrapped rows
|
| |
|
|
| |
optional methods
|
| |
|
|
| |
additions, unit tests
|
| |
|
|
| |
+ snapshot refresh
|
| | |
|
| | |
|
| |
|
|
| |
web snapshot tooling
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The tty shell rendered (core.render + full vaxis repaint + tree-sitter
re-highlight of the visible window) after EVERY event, so a wheel flick over a
highlighted file was 150 re-parses and 150 terminal repaints; the gui shell
drains the SDL queue before drawing and never had the issue. Now the tty loop
applies every queued input event, then renders once (batch cap 64; pty output
keeps a frame per chunk so progress paints and transient-state waits behave
exactly as before). Measured with tracy on a 2400-line .zig scroll script:
150 highlightFileRange calls at 1.85ms mean -> 4; render pipeline total
730ms -> 64ms; 364 frames -> 39. Snap suite 18/18.
Tracy: -Dtracy=<path-to-tracy-checkout> compiles TracyClient.cpp into the
binary and turns src/tracy.zig zones live (default off, all no-ops). Sampling,
callstacks, system tracing and the crash handler are disabled: tracy's symbol
worker SIGSEGVs on this binary's debug info and its crash handler then parks
every thread before the first frame. Capture: tracy-capture -o t.tracy; export:
tracy-csvexport t.tracy.
|
|
|
test/ (snapshot parity harness + 18 frozen goldens). One sans-IO core, vaxis tty + SDL3 GPU native + wasm web shells, 18/18 parity with the purged prototype, 7.6k lines vs 12.1k. Fix: gui shell pre-sized the core at init so the greet-releasing resize never fired (blank panes until first interaction); live sessions now init at defaults and get the real grid as a resize event (the shell contract, documented on Options).
|