[workspace] # Session 1 of the pmacs-gpu arc landed `pmacs-protocol` as a workspace # member (the wire-types crate). Session 2 (this) adds `pmacs-gpu` as # the GPU/GUI frontend binary — wgpu/winit/cosmic-text/glyphon — with # hello-world rendering. Protocol consumption arrives in session 3. # See `docs/pmacs-gpu-design.md`. members = [".", "pmacs-protocol", "pmacs-gpu"] [workspace.dependencies] # Shared between `pmacs` and `pmacs-protocol`. Pinned here so both # crates use byte-identical postcard / serde versions — the wire # format depends on it. serde = { version = "1", features = ["derive"] } postcard = { version = "1", features = ["use-std"] } thiserror = "2" # Shared between `pmacs` (terminal screen) and `pmacs-protocol` # (`TerminalFrame::validate`). Pinned here so the producer and the # validator agree on every glyph's column width. unicode-width = "0.2" [package] name = "pmacs" default-run = "pmacs" version = "1.1.0" edition = "2024" rust-version = "1.95" description = "Parallel Emacs --- a Rust-cored, Lua-scripted editor in the Emacs tradition" license = "MIT OR Apache-2.0" authors = ["Pmacs contributors"] readme = "README.md" repository = "https://git.levineuwirth.org/neuwirth/pmacs" homepage = "https://levineuwirth.org/essays/pmacs" documentation = "https://docs.rs/pmacs" keywords = ["editor", "emacs", "tui"] categories = ["text-editors"] [lib] name = "pmacs" path = "src/lib.rs" [[bin]] name = "pmacs" path = "src/main.rs" [[bin]] name = "pmacs-audit" path = "src/bin/pmacs_audit.rs" [lints.rust] unsafe_code = "forbid" missing_docs = "warn" [lints.clippy] all = { level = "warn", priority = -1 } pedantic = { level = "warn", priority = -1 } cargo = { level = "warn", priority = -1 } # Allows: pedantic lints that fight readable code. module_name_repetitions = "allow" must_use_candidate = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" cast_possible_truncation = "allow" cast_sign_loss = "allow" cast_precision_loss = "allow" similar_names = "allow" multiple_crate_versions = "allow" [features] # Pick exactly ONE Lua flavor at build time. v0.1 default is LuaJIT # (spec §3 Checkpoint 6); lua54 is a buildable fallback for environments # without LuaJIT support (e.g. some CI hosts, big-endian machines). # # `luajit` and `lua54` are MUTUALLY EXCLUSIVE — they select mlua's # mutually-exclusive Lua backends. `--all-features` enables both and CANNOT # build; the `mlua-sys` build script errors ("You can enable only one of # the features: …") before this crate compiles, so pmacs can't preempt it # with a friendlier message — the fix is to build one flavor. See the # feature matrix in README.md; build a non-default flavor with # `--no-default-features --features lua54` (audit F-002). default = ["luajit"] luajit = ["mlua/luajit", "mlua/vendored"] lua54 = ["mlua/lua54", "mlua/vendored"] # T M10.2: gate the CRDT-backed buffer mode behind an opt-in feature # so v0.1 builds carry zero CRDT overhead (no loro dependency, no # field on the Buffer struct layout, no branch on apply_edit). v1.0 # builds enable `crdt`; the rope-projection redirect from M10.1 means # the feature flip is invisible to v0.1 frontends and to workers. crdt = ["dep:loro", "pmacs-protocol/crdt"] [dependencies] crossterm = "0.28" thiserror = { workspace = true } unicode-width = { workspace = true } unicode-segmentation = "1" # Regex engine for in-buffer regex search (Q#RX1). `regex::bytes::Regex` # matches over rope-snapshot bytes and yields byte offsets directly. # Already in the lockfile transitively; promoted to a direct dependency. regex = "1" # Work-stealing deque, MPMC channels, and parking primitives for the # M3 worker pool (spec §6.3). The umbrella crate re-exports # `crossbeam_deque`, `crossbeam_channel`, and `crossbeam_utils`. crossbeam = "0.8" # Wire format for the M3 message bus (spec §5.2). `serde` derives the # trait, `rmp-serde` is the MessagePack codec the spec calls out by # name; in-process and out-of-process workers must look identical to # Lua, which means even the in-process bus encodes through MessagePack. serde = { workspace = true } rmp-serde = "1" # Wire-types crate (session 1 of pmacs-gpu arc). Owns the # `InstanceMessage` / `FrontendEvent` / capability / `SemanticFrame` # family, plus the cell/buffer/rope wire types they reference. The # `pmacs` crate re-exports through `crate::protocol`, `crate::cell`, # `crate::buffer`, and `crate::rope` so existing internal imports keep # working unchanged. pmacs-protocol = { version = "1.0.0", path = "pmacs-protocol" } # Wire format for the M5 frontend ↔ instance protocol (T M5.5b). # Length-prefix framing wraps postcard-encoded payloads. Chosen for # compactness on the cell-stream traffic (60 Hz cell deltas dominate # the wire) and for its no-std future-option (a thin attach client or # embedded REPL bridge can use the same parser). Schema evolution is # handled by an explicit version handshake (`PROTOCOL_VERSION`); see # `src/protocol.rs::Hello`. The worker-protocol encoding (§5.5 spec) # remains MessagePack via `rmp-serde`; different subsystems with # different requirements (compactness vs schema evolution). postcard = { workspace = true } # Signal handling for the M5.5 daemon (T M5.5e). Provides a safe # wrapper for installing handlers that set an AtomicBool flag, which # our accept loop polls between iterations. Used for SIGTERM/SIGINT # (graceful shutdown) and SIGPIPE/SIGHUP (no-op handlers so writes # return EPIPE rather than killing the process). signal-hook = "0.3" # mlua is feature-gated; the `default-features = false` here lets the # top-level features above pick the Lua flavor without conflict. mlua = { version = "0.10", default-features = false } # Tree-sitter incremental-parser core (T M4.1). The bundled grammars # below (T M4.2) sit on top of this crate. tree-sitter = "0.26" # Bundled grammars (T M4.2). Detection is by file extension; loading # is lazy --- the C-side language object isn't materialized until the # first buffer of that language opens. Adding a new grammar requires # only a new dependency line here plus one entry in # `crate::syntax::BUILTIN_LANGUAGES`. tree-sitter-rust = "0.24" tree-sitter-lua = "0.5" # T M_B3 — C / C++. Bundled so opening a `.c`/`.cpp`/header file in # the grid TUI gets lexical highlighting (keywords/strings/operators) # via tree-sitter, with `LspStyleView` layered on top for semantic # refinement (functions/types/macros via clangd's semantic tokens). # `.h` is ambiguous C / C++; the `c` entry below claims it by default, # matching the LSP filetype map in `builtin/runtime/lsp.lua`. tree-sitter-c = "0.24" tree-sitter-cpp = "0.23" # CUDA (`.cu`/`.cuh`). CUDA is C++ with device extensions, but its own # grammar recognizes `__global__`/`__device__` kernels, `<<<...>>>` # launch syntax, and CUDA builtins that the C++ grammar would misparse. # Loading is lazy like the others; `LspStyleView` layers clangd's CUDA # semantic tokens on top (clangd serves `.cu`/`.cuh` off the same # binary as C/C++). The crate exports `LANGUAGE`/`HIGHLIGHTS_QUERY` # (plural, the rust/lua idiom) and rides `tree-sitter-language 0.1`, so # it shares the ABI crate with the other grammars — no second # `tree-sitter` in the graph (its own `tree-sitter` dep is dev-only). tree-sitter-cuda = "0.21" # Shell / bash. Lexical highlighting for `.sh`/`.bash` and the wider # shell family (`.zsh`/`.ksh`/`.ash`/`.bats`) — the LSP half # (bash-language-server + shellcheck/shfmt) was already wired in # `builtin/runtime/lsp.lua`; this fills in the missing grammar. bash # does not inherit another grammar, so `HIGHLIGHT_QUERY` (singular, the # c/cpp/md idiom) is self-contained — no base-query composition like # `cuda`. Exports `LANGUAGE` over `tree-sitter-language 0.1` (shared ABI # crate, no second `tree-sitter` in the graph). Note: because the # grammar's language name (`bash`) matches the `pmacs.lsp.config.bash` # key, every extension claimed here also auto-attaches # bash-language-server (shellcheck refuses zsh, so `.zsh` diagnostics # may be sparse; highlighting is unaffected). tree-sitter-bash = "0.25" # Filename-identified languages (no useful extension): Dockerfile, Make, # CMake. Highlighting for files detected by BASENAME (`Dockerfile`, # `Makefile`, `CMakeLists.txt`) via the new filename map, plus their # extensions (`.dockerfile`/`.mk`/`.cmake`). All three ride # `tree-sitter-language 0.1` with `tree-sitter` dev-only (no second core # in the graph) and export `LANGUAGE`/`HIGHLIGHTS_QUERY`. # * Dockerfile: `tree-sitter-containerfile` — the maintained, # ABI-current grammar (the older `tree-sitter-dockerfile` is pinned to # `tree-sitter ^0.20` and would fork the graph). Covers Containerfile. # * Make / CMake serve `dockerfile`/`cmake` LSP servers too (see lsp.lua); # Make has no language server. tree-sitter-containerfile = "0.9" tree-sitter-make = "1.1" tree-sitter-cmake = "0.7" # Grammar-gap languages: these already have LSP configs (basedpyright / # gopls / tsserver / taplo / zls) but shipped no tree-sitter grammar, so # they rendered with no lexical color. Fill the gap. All ride # `tree-sitter-language 0.1` (tree-sitter dev-only) and export # `LANGUAGE`/`HIGHLIGHTS_QUERY`. TypeScript is special: one crate ships # TWO grammars (`LANGUAGE_TYPESCRIPT`/`LANGUAGE_TSX`) and its highlights # inherit JavaScript, so the `typescript*` entries compose the JS query # ahead of the TS one (see `crate::syntax::BUILTIN_LANGUAGES`). JavaScript # parses both `.js` and `.jsx`. tree-sitter-python = "0.25" tree-sitter-go = "0.25" tree-sitter-javascript = "0.25" tree-sitter-typescript = "0.23" tree-sitter-toml-ng = "0.7" tree-sitter-zig = "1.1" # JSON + YAML — config formats + the honest gate on the Jupyter path # (JSON). Both are ABI-current (`LANGUAGE: LanguageFn` via # `tree-sitter-language`), NOT a `tree-sitter ^0.20` fork. Registering # yaml also lights up markdown `---` frontmatter through the #122 # injection engine (the block injection query already sets yaml for it). tree-sitter-json = "0.24" tree-sitter-yaml = "0.7" # T M9.7: markdown grammar so prompt result buffers with # `_meta.format = "markdown"` get structured highlighting through the # same M4 path as rust/lua — no special-case painter in Lua. # Pinned to `0.5` (caret-excludes-major for 0.x; see # `tree-sitter-rust = "0.24"` style above). The crate is the official # tree-sitter-org grammar (`tree-sitter-md` on crates.io); the # alternative names `tree-sitter-markdown*` are forks of varying # maintenance status — pick the upstream one. tree-sitter-md = "0.5" # LaTeX / TeX (`.tex`/`.latex`/`.sty`/`.cls`) — the "basic LaTeX mode" # foothold and the tier-1 detection substrate for the inline-math arc (lane # framing `docs/latex-grammar-math-substrate-framing.md`). The canonical crate name # `tree-sitter-latex` is squatted by a broken 0.1.0 repackage that ships no # `scanner.c` for its declared external tokens and therefore CANNOT LINK # (undefined `tree_sitter_latex_external_scanner_*`). `codebook-tree-sitter-latex` # is a linkable republish of the real, maintained `latex-lsp/tree-sitter-latex` # (MIT, texlab's author) modernized to the `LanguageFn` shim: it ships # `scanner.c`, exports `LANGUAGE` over `tree-sitter-language 0.1` (tree-sitter # dev-only, shared ABI crate — no second core in the graph), and its # `grammar.js`/`scanner.c` are byte-identical to upstream (provenance diff # discharged in the framing). It exports NO query constants, so highlighting # uses the in-repo overlay `builtin/queries/latex/highlights.scm` (the first # such overlay; `include_str!`'d in `crate::syntax::BUILTIN_LANGUAGES`). codebook-tree-sitter-latex = "0.6" # Web grammars: HTML + CSS (`.html`/`.htm`/`.xhtml`, `.css`). The official # tree-sitter-org grammars; both export `LANGUAGE` + query constants over # `tree-sitter-language 0.1` (shared ABI crate, `tree-sitter` dev-only), so no # overlay is needed. HTML's `INJECTIONS_QUERY` lights up `