[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" [package] name = "pmacs" version = "1.0.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 = "0.2" # 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" # 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" # T M4.4 process supervisor: signal sending without `unsafe`. Keep # the feature surface tight to keep build time low. `poll` feeds the # compile-mode group readers (cancellable poll-based reads, Q#CM3). nix = { version = "0.29", default-features = false, features = ["signal", "user", "fs", "term", "socket", "poll"] } # T M4.4 PTY mode: portable abstraction over openpty / fork+exec # with controlling-tty wiring. The crate uses internal `unsafe` # but exposes a fully safe API; pmacs's own `unsafe_code = "forbid"` # rule still holds. portable-pty = "0.9" # T M4.5 LSP wire format: JSON-RPC 2.0 bodies inside Content-Length # framing. Used only on LSP and similar protocols that require JSON # specifically; in-process workers continue to use MessagePack # (spec §5.2). `preserve_order` is off --- LSP doesn't require it # and the default `BTreeMap` keeps allocation low. serde_json = "1" # T M7.1 package manifest format (spec §sec:packages-future): TOML at # the package's root (`pmacs.toml`). Read at install time, not at every # load. toml = "0.8" # T M7.1 semantic versioning for `version` and `pmacs_required` fields. # `serde` feature gives us localized parse errors during deserialization # (rejected at parse time, not at install time). semver = { version = "1", features = ["serde"] } # T M7.6 lockfile content-hashing. SHA-256 over `git archive --format=tar` # bytes detects upstream tampering even when the host serves a SHA-1 # collision. Pure-Rust implementation; no system dep. sha2 = "0.10" # T M10.2 sequence CRDT for the v1.0 multi-frontend promotion. Selected # in M10.1 (Decision section under spec §sec:m10-crdt-choice) on the # basis of: per-op throughput dominance under realistic mixed-workload # (190× faster than yrs at 30s window), ~100× more compact wire # representation, stable v1.x API, and explicit spec mention. The pin # is exact (`=1.12.0`) per the M10.1 commitment language: library # updates are deliberate work (re-run M10.1 benchmarks, run convergence # proptest, run acceptance suite), not Cargo background activity. # Optional + feature-gated: zero footprint in v0.1 builds. loro = { version = "=1.12.0", optional = true } [dev-dependencies] proptest = "1" tempfile = "3" # T M10.2 Day 7 perf bench (tests/m10_2_perf.rs) — seeded RNG plus # log-normal op-size distribution matching the M10.1 methodology. # Dev-only; not in release builds. rand 0.8 + edition 2024 requires # `r#gen` for the (now-reserved) `gen` method name. rand = "0.8" rand_distr = "0.4" [profile.release] opt-level = 3 lto = "thin" codegen-units = 1 debug = "line-tables-only" strip = "debuginfo" [profile.bench] opt-level = 3 lto = "thin" codegen-units = 1 debug = "line-tables-only"