[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). 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"] [dependencies] crossterm = "0.28" thiserror = "2" unicode-width = "0.2" # 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 = { version = "1", features = ["derive"] } rmp-serde = "1" # 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 = { version = "1", features = ["use-std"] } # 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 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 (no syscalls # beyond `kill(2)` for v0.1). nix = { version = "0.29", default-features = false, features = ["signal", "user", "fs", "term", "socket"] } # 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"