Skip to content

v0.104.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 18:10
· 138 commits to master since this release

madc v0.104.0

The madcide split release. Everything since v0.103.0: madc's interactive
mode takes the ed/ex editing core — a colon mode, a command registry modules and
hosts extend, and host-facing language services — and madc gains a Language
Server (--lsp) and a Model Context Protocol server (--mcp) with a project
memory, a code graph and an external-task client. madcide moves to its own
repository and releases on its own as madcide 0.7.0, its first standalone
release, built on and pinned to madc 0.104.0, so madc's packages no longer carry
it. Chthonia 0.1.0 builds on madcide 0.7.0 + madc 0.104.0. Regexes now run on one
PCRE2 engine and a source's standard follows its extension — the user-visible
behaviour changes this release carries.

Features

  • madc's interactive mode gains colon mode and a command registry. An
    interactive entry's first non-blank character is its mode: % and . are the
    REPL's commands (IPython / clang-repl and cling / Node), ? is the query, and
    : is colon mode — ed / ex / vim commands run through madc's own ex core
    (madc::ex_session over a ui:: world). The built-in command table becomes the
    one registry that a loaded module's rows and a host's rows extend, resolved by
    the same name lookup, listed by %help and offered by completion in both REPL
    modes.

    madc -i                      # a C/C++/madc prompt, now with : colon mode
    
  • The REPL buffer. Colon mode at the REPL (madc -i) edits the REPL buffer,
    a scratch buffer [REPL] (vim's buftype=nofile) that holds every entry the
    session kept and every file %load kept, each appended to its end as one undo
    group; a refused entry stays out. At a bare madc -i colon mode starts on it;
    madc -i FILE is line mode, starting on FILE, with :b REPL reaching the REPL
    buffer, and :ls, :b N / :b NAME, :bn, :bp and :e switch between
    them. The scratch buffer never counts as unsaved for :q, :w FILE writes a
    copy (it keeps its name), :sav is refused, and %run / %check / %build
    with no FILE refuse it.

  • %run rebuilds the REPL buffer. %run with no FILE and the REPL buffer
    current rebuilds it the way an IDE rebuilds an edited file (Jupyter's Restart
    and Run All): a fresh session (%reset), then the buffer's text read back as
    typed lines, each entry shown as usual and nothing appended to the buffer
    again. Only the REPL buffer rebuilds; %run on any other current buffer runs
    it as before.

  • %psource and ??NAME. madc -i answers %psource NAME, %pinfo2 NAME
    and ??NAME (IPython's inspector). %psource NAME prints the source of each
    definition of NAME the session holds — from the entry that typed it
    (REPL[N]) or the file that defined it (the host's buffer of it, else the
    disk), a function's whole body and an object's whole declaration — and is
    refused with "no source found for 'NAME'" when it holds none; %pinfo2 NAME /
    ??NAME is %pinfo's fields with a Source: section after them. The three
    are detail levels of the one pinfo command. Colon mode's printed buffer lines
    (:p, :nu) and the shown source are coloured in the theme where colour
    reaches the terminal, line numbers plain.

  • New REPL commands. madc -i answers %std and %reset (a fresh session
    under a named or the same standard), %history (this session's or the saved
    entries), %check [FILE] (diagnostics without running, gcc -fsyntax-only's
    shape), %build and %run on the current buffer, %args (the program
    arguments a buffer %run passes), and %project (open, add, del, check, build,
    run and close the session's project). The project manifest gains a C++ writer
    beside its reader.

  • Coloured prompts and diagnostics. madc -i now colours each entry in the
    theme's colours as it is typed, the code in what a command shows (%type,
    %pinfo, ?name) and the source line it echoes under a diagnostic — and madc's
    diagnostics carry SGR colour only where they reach a terminal that shows it,
    matching gcc's -fdiagnostics-color=auto. New options follow gcc's spelling
    (-fdiagnostics-color[=auto|always|never], -fno-diagnostics-color), and
    NO_COLOR / TERM=dumb turn colour off. A madc.ini theme = PATH key reads a
    .theme file in place of the built-in theme.

  • madc --lsp — a Language Server. madc --lsp [FILE] runs a Language
    Server Protocol server on standard input and output (Content-Length framed, LSP
    3.17), answering diagnostics, document symbols, definition, references, hover
    and semantic tokens for each document the client opens, from its live text.
    workspace/executeCommand runs the REPL's % commands as madc.NAME in a
    crash-isolated backend session, reporting the program's output, and
    window/showDocument opens a file in the client's editor.

  • madc --mcp — a Model Context Protocol server with a project memory.
    madc --mcp FILE (or --mcp --project X) runs a Model Context Protocol server
    on stdin/stdout (JSON-RPC 2.0, one message per line), serving a tiered tool
    registry over the served documents: 16 code-graph reads (graph.symbols,
    definition, references, callers, impact, ...) and three edits
    (graph.insert / replace / delete, validated by the compiler before
    anything changes), a project memory — one event stream, memory-only until bound
    to a <base>.events file beside the manifest — with proposal, nexus and test
    tools, the served file's version history from the madcgit module, and a client
    whose nexus.sources / nexus.sync pull an external MCP system's tasks. One
    process at a time owns a project, held by the OS on an advertisement file.

  • One regex engine (PCRE2). madc::regex_match / regex_search /
    regex_replace and the regex-aware perl::grep / perl::split now share one
    PCRE2 engine — the engine behind PHP's preg_* — so a pattern means the same
    thing on every platform (Linux links libpcre2-8, the macOS and Windows
    packages carry a pinned static PCRE2 10.42). Lookbehind, lazy quantifiers,
    named groups and inline flags that std::regex lacked now work; an invalid
    pattern is refused on stderr with PCRE2's reason and offset, instead of a silent
    substring or literal-delimiter fallback, and perl::split on an empty pattern
    splits into code points.

  • A source's standard follows its extension. A source compiled without
    --std now takes the standard its extension names, as plain gcc and g++ do:
    a .c / .h file compiles as gnu17, a .cpp / .cc / .cxx file as
    gnu++17, and a .mad file as the madc dialect — where previously every source
    compiled in the madc dialect. The precedence is --std > the extension >
    madc.ini std > madc, with one owner deciding it for the CLI, a --project TU
    and the editor's document parse. madc.ini gains a repeatable modules key, as
    php.ini loads extensions.

Fixes, internals and process

  • madcide moves to its own repository. madcide — the IDE and the editor core
    it builds on — now lives in its own repository and ships its own packages, each
    carrying the madc release it runs on. The moved paths (tools/madcide/,
    tools/texteditor/, tools/vscode-madcide/, the madcide tests and window
    tests, the check-madcide-* and pty gates), their packaging stanzas, the
    Homebrew formula's madcide build, the man page and the lane ledger's APPLICATION
    split leave madc; no src/ or include/ file changed, as madcide only consumed
    the engine. Coverage that only madcide exercised keeps an engine twin
    (tests/gui/ui_web_menu for the native menu bar; the theme profiles under
    tests/unit/themes/).

  • One set of language services. madc::lang (include/madc_lang.h) answers a
    document's diagnostics, outline, enclosing, definition, references, hover and
    spans in one place over one parse handle, with one coordinate (a 1-based line, a
    0-based byte column) and one re-parse-on-version-change door, so the LSP, the
    MCP tools and an editor read the same answers; a madc::doc_* dialect face
    gives them as rows. A plain parse handle now inherits its opener's include
    search list, so the IDE and LSP find a header the command-line compile finds.

  • A document component in the data substrate. A text carries a monotonic
    version, and a document adds path, kind, read-only, a derived modified,
    anchors that follow edits (one shared shift rule, madc::hub::shift_position),
    a checkpoint and a parse-handle slot. Every mutation publishes one byte-precise
    edit notification whose change kind is an enum code, and a mutation from inside
    a delivery, or on a read-only document, is refused.

  • Forest and pack correctness and reproducibility. The pack emits unit
    payloads in canonical unit order rather than heap-address order, so two freezes
    of one corpus agree and the release pack is reproducible; the one pack profile
    is labelled for the C++ modes it shares with madc (gnu++17, c++17), so those
    compiles bind it instead of falling through to source text; a skipped
    directive-only #ifndef arm replays at bind; each translation unit materializes
    its own frozen nodes, fixing REPL reuse across entries; a restored class keeps
    its constructor's explicit; and a dependent noexcept operand no longer folds
    at class-pattern capture.

  • Codegen. A copy-elided method-call initializer (T v = obj.m();) now lowers
    through the one method-call owner with the declared object as the result slot,
    so the receiver is adjusted to the method owner's subobject and virtual dispatch
    reaches the dynamic type.

  • A ui:: world face survives its world closing. madc::ex_session and
    madc::tool_host re-ask for their world at every use and forget it on
    destruction, so a face no longer reads a world ui::world_close has freed.

  • Windows and darwin parity. Windows madc and madc -i run the session in a
    crash-isolated backend as POSIX already did, naming a crash's exception code; a
    Windows madc -i shares a piped stdin with its backend byte-exactly; and the ex
    core's write message, madc --lsp's executeCommand output and the vised
    editor carry their Windows expected outputs.

  • Process and tooling. One reader for a test's run fixtures
    (scripts/test_fixtures.sh); run_tests.sh refuses a run that executed no
    test; every static gate sees files a commit has not yet committed; a parallel
    build sizes its job count by host memory, not cores; and php::trim / ltrim /
    rtrim / chop take PHP's $characters and PHP's default set.

Validation

Every platform lane's full suite is run on the shipped packed -O2 madc-release
at the release content (67766e242, 2026-10-11) — the seam battery (seam5), the
native macOS lanes, genuine Windows and the Homebrew lane all on that one
content.

lane result
Linux (packed -O2, headerless) 1966 passed / 0 failed / 43 skipped, plus the on-disk header subset 34/0
Linux native artifacts JIT 2000/0/9 skipped, EXE 1811/0, OBJ 1811/0
Windows (packed PE under Wine, headerless) 1927/0/82 skipped, plus the on-disk subset 1/0
Windows (full suite, owner Windows 11) 1926/0/83 skipped
macOS arm64 (native, libc++) 1968/0/41 skipped, mac battery 12/0
macOS Intel (native, libc++) 1970/0/39 skipped, mac battery 12/0
aarch64 long-double lane green
macOS build lane green (darwin forest pack 837 units, consumer parse leg OK)
Homebrew (Linux bottle) bottle + pour + brew test + keg-masked runpath gate, suite 2000/0/9 skipped
parse-cost profiling gate 0 red of 6 (tolerance 0.5%)
static gates 0 red of 95; make gates (unit tests + repository gates) green

Commit-tier conformance lanes at the same content: c-testsuite 220/0, c-torture
1617 passed (7 failing, all at baseline), c2mir-tests 368/0 (4 skipped), gui
15/0 JIT/EXE/OBJ, index-c 50/50, commonmark 664 of 670 (6 at baseline).

See CHANGELOG.md for full details.