// ZSHRS — C-TO-RUST PORT COVERAGE REPORT

src/zsh/Src/*.c → src/ported/*.rs · 91 C files (32 core + 24 ZLE + 33 modules + 2 Builtins) · 147,233 C lines · 651,206 Rust lines (all .rs incl. tests + build.rs; git ls-files '*.rs' | xargs wc -l) · 613 .rs files · 14,638 #[test] hooks (git ls-files '*.rs' | xargs rg '^\s*#\[test\]') · PORT.md ruleset · tests/port_purity.rs enforces strict-port purity

>_EXECUTIVE SUMMARY

Large-scale C-to-Rust port of upstream zsh: strict-port code under src/ported/ plus non-port extensions. The core file table below is regenerated from the same indexer as port_report.html (regex C top-level defs + Rust fn names + port-doc mining). Those counts are a mechanical index, not proof that every path is behavior-complete.

Codebase split (NEW): the runtime crate now physically isolates ported code from non-port code so drift is mechanically detectable. src/ported/ (107 files) is the strict-port directory — every .rs mirrors a real src/zsh/Src/<x>.c file, every top-level fn carries a /// Port of <cname>() from Src/<file>.c:NNNN doc-comment, and the file set is FROZEN (no new files; PORT.md §"ABSOLUTE FREEZE"). src/extensions/ (40 files) is the non-port directory — features zsh C does not have (AOT, daemon coordination, plugin/script/autoload caches, fish-style autosuggest/abbrev/highlight, persistent worker pools, ZWC byte-code helpers). src/recorder/ (1 file) is feature-gated; deleted by rustc in the default build. Both invariants are enforced by tests/port_purity.rs — a regression of either rule fails CI.

Scope note: this report covers the C-to-Rust port (i.e. src/ported/ only) — what was translated from upstream zsh. It does not cover the new Rust infrastructure layered on top (zshrs-daemon singleton, zshrs-recorder AOP intercept, IPC + HTTP + OpenAPI surface, canonical-state rkyv shards, the z* builtin family, session-persistent supervised jobs with bidirectional ptmx attach, the parser surface in src/ported/parse.rs). That work has no C ancestor and is reported separately in daemon-report.html. See “BEYOND THE C PORT” section below for the cross-link.

14,638
#[test] Hooks
91
C Files Ported
5,471
pub fn (rg)
613
Rust Source Files
107 / 40 / 1
ported / extensions / recorder
147,233
C Lines Covered
0
C-only symbols (index)

Overall Line Coverage

651,206 Rust / 147,233 C — raw line ratio (not semantic completeness)

Rust line count covers the entire 3-crate workspace (zshrs runtime, compsys, zshrs-daemon) plus fish/, tests/, bins/, and root build.rs. C-line ratio is ~258% Rust : C by raw lines, but most files are more concise than their C source — the inflation comes from the non-port surface (extensions, daemon, fish, compsys) that has no C ancestor. exec.rs alone is 353% of exec.c because it includes 180+ builtins (23 coreutils anti-fork) that C splits across builtin.c.


#FILE-BY-FILE COVERAGE

Per-file columns: C Fns = symbols whose primary C definition is that file (unique name, heuristic indexer). Same-name Rust fn = a Rust definition with the identical identifier. Other rows = the remainder (doc-only pointers, different Rust names, or not yet indexed). Port-index % = ported / total from gen_port_report.py (ported = any Rust hit or port-doc mention). Rust targets: src/ported/<stem>.rs except exec.csrc/exec.rs.

C SourceRust TargetC LinesRust LinesRatioC FnsSame-name Rust fnOther rowsPort-index % 
lex.cported/lex.rs2,2945,201226.7%25250
100.0%
parse.cported/parse.rs4,0669,442232.2%75750
94.7%
⚠️
subst.csrc/ported/subst.rs4,92213,161267.4%24240
100.0%
math.csrc/ported/math.rs1,6775,174308.5%20200
100.0%
exec.csrc/exec.rs (re-exported as crate::ported::exec)6,50300.0%74740
97.3%
⚠️
params.csrc/ported/params.rs6,51113,253203.5%1801800
99.4%
⚠️
pattern.csrc/ported/pattern.rs4,3757,280166.4%40400
85.0%
⚠️
glob.csrc/ported/glob.rs3,9737,011176.5%52520
94.2%
⚠️
jobs.csrc/ported/jobs.rs3,2935,254159.6%57570
96.5%
⚠️
hist.csrc/ported/hist.rs3,9656,703169.1%76760
97.4%
⚠️
utils.csrc/ported/utils.rs7,79112,815164.5%1721720
90.1%
⚠️
prompt.csrc/ported/prompt.rs2,5623,965154.8%32320
75.0%
⚠️
init.csrc/ported/init.rs1,9651,87995.6%23230
87.0%
⚠️
signals.csrc/ported/signals.rs1,3392,487185.7%27270
96.3%
⚠️
TOTAL (core)55,23693,625169.5%8778770
94.4%
ℹ️

&RENAMING PATTERNS

C uses free functions with global state. Rust uses struct methods, enum variants, and pattern matching. Every “renamed” C function maps to a Rust equivalent under an idiomatic name. This section explains the mapping patterns.

params.c → ParamTable

60+ GSU callback pointers (randomgetfn, uidsetfn, ifsgetfn, homegetfn, termsetfn, etc.) become match arms in ParamTable::get_special_value() and handle_special_set(). Internal helpers (getparamnode, assigngetset, scanparamvals, paramvalarr, getvaluearr) become get_param(), set_scalar(), scan_match(). Env functions (zputenv, addenv, mkenvstr, delenv, copyenvstr) use std::env::set_var/remove_var. Nameref (resolve_nameref_rec, setscope, upscope) becomes resolve_nameref_name(). Uniq array (simple_arrayuniq, newuniqtable, arrayuniq) becomes uniq_array().

parse.c → ShellParser + AST

C’s recursive-descent functions (par_for, par_case, par_if, par_while, par_repeat, par_subsh, par_funcdef, par_time, par_dinbrack, par_simple, par_redir, par_wordlist, par_cond*) become parse_for(), parse_case(), parse_if(), etc. Bytecode system (ecadd, ecdel, ecstrcode, bld_eprog, ecgetstr, ecgetlist, ecgetredirs, init_eprog) replaced by typed AST: ShellCommand enum with Simple, Pipeline, Compound, FunctionDef. ZWC dump/load (dump_find_func, bin_zcompile, load_dump_header, write_dump, build_dump, try_dump_file) moves to zwc.rs.

exec.c → ShellExecutor

execlistexecute_list(), execplineexecute_pipeline(), execsimpleexecute_simple(), execodeexecute_command(). Function: execshfunc/runshfunccall_function(), execautofnautoload_function(). Pipes: spawnpipes/getpipe inline in pipeline execution. Fd: fixfds/closemn/closemnodes inline. Plus 180+ builtins (including 23 coreutils anti-fork) not in C’s exec.c.

glob.c → Qualifier enum

15 qualifier test functions (qualdev, qualnlink, qualuid, qualgid, qualisdev, qualisblk, qualischr, qualisdir, qualisfifo, qualislnk, qualisreg, qualissock, qualflags, qualmodeflags, qualnonemptydir) become enum variants + GlobMatch::from_path(). Match internals (igetmatch, matchpat, parsecomplist, parsepat, insert_glob_match) in getmatch(), pattern_match(), GlobEngine::glob().

init.c → init_main()

zsh_maininit_main(). Subsystem inits (init_signals, init_misc, init_bltinmods, init_shout, setupshin) fold into ShellExecutor::new() and init_main(). Stubs (noop_function, noop_function_int, zleentry, fallback_compctlread) not needed. parseopts_insert/printhelp/getmypath/tccap_get_name handled inline.

lex.c → Lexer struct

lexinit/initlextabsLexer::new(). lex_context_save/restoresave_state()/restore_state(). checkalias/exalias inline in next_token(). skipcommlex_comment(). Raw buffer ops (zshlex_raw_add/back/mark/back_to_mark) unnecessary — Rust String handles buffer ops natively.

math.c → MathEvaluator

lexconstant part of number parser. callmathfunccall_math_func(). setmathvarset_variable(). getmathparamget_variable(). mathevallevaluate(). checkunary/notzero/getcvar inline in eval loop.

jobs.c builtins

bin_fgbuiltin_fg(), bin_killbuiltin_kill(), bin_suspendbuiltin_suspend() in exec.rs. C puts builtins in the same file as infrastructure; Rust separates executor from job internals.

subst.c

wcpadwidth/subst_parse_str inline in SubstState methods. All 22 other functions matched by name.


$KEY FEATURES PORTED

params.c — Full Parameter System

All 80+ special params with dynamic get/set:

  • $?, $$, $!, $#, $*, $@, $0, $_, $-
  • RANDOM (LCG PRNG, seedable), SECONDS (int + float modes)
  • ERRNO, UID/EUID/GID/EGID (with setuid on assign)
  • COLUMNS/LINES (ioctl), SHLVL, FUNCNEST, OPTIND/OPTARG
  • IFS, HOME, TERM, WORDCHARS, HISTCHARS
  • PS1-PS4, RPS1/2, RPROMPT/2, SPROMPT, POSTEDIT
  • PATH/path, CDPATH/cdpath, FPATH/fpath tied pairs
  • pipestatus, argv, HISTSIZE/SAVEHIST
  • Namerefs with loop detection, scope push/pop with save/restore
  • typeset -p re-executable output, += augmented assignment

pattern.c — Complete Pattern Engine

Bytecode-compiled pattern matcher:

  • Wildcards: *, ?, [...], [!...], [^...]
  • Extended glob: # (0+), ## (1+), ^ (negation), ~ (exclusion)
  • KSH globs: ?(pat), *(pat), +(pat), !(pat), @(pat)
  • Numeric ranges: <n-m>, <n->, <-m>
  • Backreferences with () capture groups (9 max)
  • Case-insensitive: (#i), lowercase-match-upper: (#l)
  • POSIX classes: [:alpha:], [:digit:], [:space:], etc.
  • Glob flags: (#b) backrefs, (#m) match refs, (#s)/(#e) anchors
  • Pattern scope management for completion system

exec.c — 180+ Builtins

Every zsh builtin + 23 coreutils anti-fork:

  • Variables: typeset/local/declare/export/readonly/integer/float
  • I/O: print/printf/echo/read/getln/pushln
  • History: fc/history/r
  • Control: eval/source/exec/command/builtin/noglob
  • Jobs: bg/fg/jobs/kill/wait/disown/suspend
  • Dir: cd/pushd/popd/dirs/pwd
  • Options: set/setopt/unsetopt/emulate
  • Traps: trap/kill
  • Completion: compgen/complete/compdef/compadd/compset
  • ZLE: bindkey/zle/vared
  • Modules: zmodload/autoload/functions
  • Files: mkdir/rmdir/rm/cp/mv/ln/chmod/chown
  • Coreutils (anti-fork): cat/head/tail/wc/sort/find/uniq/cut/tr/seq/rev/tee/sleep/date/mktemp/hostname/uname/whoami/id/basename/dirname/touch/realpath
  • Misc: getopts/zparseopts/zstyle/sched/zformat/coproc

glob.c — Full Globbing

Complete file globbing engine:

  • Recursive scanning with **/ support
  • Brace expansion: {a,b,c}, {1..10}, {a..z}
  • 20+ glob qualifiers: (.) regular, (/) dir, (@) symlink, (=) socket, (p) fifo, (%b) block, (%c) char
  • Permission qualifiers: (r)/(w)/(x), (R)/(W)/(X), (s) setuid
  • Ownership: (u:name:), (U) owned by EUID
  • Size/time/links: (L+n), (m-n), (l+n)
  • Sorting: (on) name, (oL) size, (om) mtime
  • Match/replace: ${var/pat/repl}, ${var//pat/repl}
  • Tokenization: tokenize(), shtokenize(), zshtokenize()

hist.c — Full History

Complete history expansion and management:

  • Event designators: !!, !n, !-n, !string, !?string?
  • Word designators: !:0, !:^, !:$, !:*, !:n-m
  • Quick substitution: ^old^new
  • Modifiers: :h head, :t tail, :r root, :e ext, :l/:u case, :s/o/n/ subst, :& repeat, :q/:Q quote, :x words, :a abs path
  • File I/O with locking, extended format timestamps
  • Deduplication, blank reduction, word splitting
  • History stack for nested parsing contexts
  • Search: prefix (hcomsearch) and substring (hconsearch)

jobs.c — Full Job Control

Complete job lifecycle management:

  • Job table with add/remove/reap/expand/shrink
  • Process tracking: update_process, update_job, update_bg_job
  • Wait: waitforpid, waitjob, waitjobs, waitonejob
  • Control: fg_job, bg_job, disown_job, killjob
  • Process groups: acquire_pgrp, release_pgrp
  • Pipestats tracking with PIPEFAIL support
  • Background status: addbgstatus/getbgstatus
  • Superjob/subjob hierarchy
  • Time reporting: format_time with %E/%U/%S/%P/%J
  • Signal name/number conversion: all 31 standard signals

utils.c — utility surface

Complete utility library:

  • Error/warning: zerr, zerrnam, zwarn, zerrmsg
  • Quoting: quotestring (7 modes), quotedzputs, dquotedztrdup
  • String ops: sepsplit, spacesplit, sepjoin, zjoin, colonsplit
  • Path ops: expand_tilde, findpwd, lchdir, xsymlink, slashsplit
  • Named dirs: finddir, adduserdir, getnameddir, substnamedir
  • Terminal: get_term_width/height, adjustwinsize, gettyinfo/settyinfo
  • Fd: movefd, redup, zclose, read_loop/write_loop
  • Escape parsing: getkeystring (\n \t \xNN \uNNNN \UNNNNNNNN \0NNN \cX)
  • Spelling correction: spdist, spckword, spname, mindist
  • Time: ztrftime, monotonic_time_ns, zsleep

prompt.c + signals.c + init.c

Complete prompt, signal, and init systems:

  • All % escapes: dir (%~/%//%c), user (%n/%m/%M), status (%?/%#), time (%D/%T/%*), history (%h), jobs (%j), psvar (%v)
  • Formatting: %B/%U/%S bold/underline/standout, %F{color}/%K{color}
  • Conditionals: %(?.true.false), truncation, right prompt
  • True color detection, named colors, highlight parsing
  • 28 signal handlers: block/unblock, queue, trap scope management
  • Startup sequence: zshenv, zprofile, zshrc, zlogin, zlogout
  • Emulation modes: zsh, sh, ksh, csh

@PER-SYMBOL PORT INDEX

Hand-maintained per-function tables previously claimed a fixed “859” row total and drifted (wrong Rust paths, inflated coverage). Those rows are removed. The port_report.html file produced by python3 scripts/gen_port_report.py lists every C symbol the indexer extracts from src/zsh/Src/**/*.c (heuristic: top-level ident( with a following {) together with Rust placement and port-doc pointers — regenerate after upstream or port changes.

The core file table above (between PORT_REPORT:CORETABLE markers) is rewritten by the same script from live tree counts; it is not manually curated.


!TEST RESULTS

Pass/fail counts are intentionally not pinned in this HTML snapshot (they drift with feature flags and cargo version). The static surface is the #[test] hook total in the engineering overview below. For a local matrix run cargo test with the same features you ship; when triaging ordering-sensitive cases, --test-threads=1 remains the tie-breaker.


~ARCHITECTURE: WHY RUST IS DIFFERENT

C wordcode vs Rust AST port

C zsh lowers shell to wordcode (ecadd, ecstrcode, bld_eprog) executed from Src/exec.c. The zshrs parser port surfaces a typed AST instead (ShellCommand::Pipeline(Vec<ShellCommand>, bool), etc.), so many wordcode helpers disappear behind enum variants and structured lowering.

Methods Instead of Function Pointers

C’s parameter system uses GSU (get/set/unset) function pointer structs — 60+ callback functions like randomgetfn, uidsetfn, ifsgetfn. Rust dispatches by parameter name in two central match expressions: get_special_value() and handle_special_set(). Same functionality, ~130 fewer function definitions.

Native UTF-8 vs Meta Encoding

C’s zsh uses a custom “meta” encoding for strings containing special characters (20+ functions: metafy, unmetafy, metalen, unmeta, metacharinc, mb_metacharlenconv, etc.). Rust’s String is natively UTF-8. Most meta functions become identity operations or char iteration.

RAII vs Manual Memory

C requires explicit freearray(), freeparamnode(), freeeprog(), freerepldata(), freestr(), deleteparamtable(). Rust’s ownership system handles all of these automatically via Drop. These functions are provided as no-ops for API completeness.


%ENGINEERING OVERVIEW

Workspace-wide cargo workspace metrics (three packages: zshrs, compsys, zshrs-daemon). Counts below are from wc / rg on 2026-05-23; per-subsystem module tables follow unchanged.

651,206
Total Rust Lines
613
.rs Files
14,638
#[test] Hooks
5,471
pub fn (tracked .rs)
580
pub struct
126
pub enum
4,064
Git Commits

ΔMAY 2026 — RECENT PORT WORK

Three themes closed out across May 2026: (1) every // Deferred / // FAKE / // stub marker in builtin.rs turned into a real C-faithful body, (2) the try_with_executor dispatch path — a Rust-only abstraction that bypassed paramtab — was eliminated entirely from src/ported/ (40 → 0 call sites; only two historical comments remain in subst.rs), and (3) all 30 module files (clone/cap/example/datetime/socket/tcp/stat/zftp/zprof/zselect/watch/zpty/termcap/terminfo/attr/system/zutil/ksh93/db_gdbm/pcre/param_private/mathfunc/langinfo/hlgroup/mapfile/parameter/nearcolor/random/regex/files) were migrated from per-module featuresarray/handlefeatures/getfeatureenables/setfeatureenables stub copies to the canonical crate::ported::module::* impls — 4 stubs × 30 modules = 120 duplicate fake fns deleted, replaced with slice-based module::Features { bn_list, cd_list, mf_list, pd_list } arrays populated with the real BUILTIN/CONDDEF/MATHFUNC/PARAMDEF entries.

Other major de-faking in May: fake structs in hashtable.rs deleted (CmdName / Alias / Reswd / DirCache / SuffixAliasTable / ReswdToken / ShFunc impl block — all replaced with canonical lowercase C-named structs from zsh_h.rs), jobs.rs deleted (JobEntry / BgStatus / PipeStats / CommandTimer / JobPointers fake aggregates; JobState/JobInfo/JobTable moved out to exec_jobs.rs), input.rs deleted (StringInput convenience wrapper, InputBuffer aggregate, INP_* drift constants), glob.rs deleted (GlobOptions / GlobSort / SortOrder / SortSpec / TimeUnit / SizeUnit / RangeOp / impl GlobMatch), cond.rs deleted (CondType / CondResult / CondEval fake enums), module.rs deleted (Wrapper struct + addwrapper/deletewrapper), options.rs deleted (ShellOption enum, with opt_state_get("name") globally swapped to isset(OPT_CONST)).

AreaWhat landedC sourceRust location
builtin.rsloadautofn — real $fpath walk + file read + PM_UNDEFINED clear (was return-0 stub)exec.c:5050ported/builtin.rs:883
builtin.rsbin_functions -c autoload-trampoline now invokes loadautofnbuiltin.c:3414ported/builtin.rs:1593
builtin.rsscanmatchshfunc wired (replaces stale “funcs.rs” comment that referenced a non-existent file)builtin.c:3682ported/hashtable.rs
builtin.rsbin_functions -M / +M / -m+M — full add/list/remove/match paths into the new MATHFUNCS globalbuiltin.c:3478–3611ported/module.rs:31
builtin.rsbin_return POSIX-trap promotion to TRAP_STATE_FORCE_RETURNbuiltin.c:5845–5854exec.rs::TRAP_STATE/TRAP_RETURN
builtin.rsbin_enable toggles for Builtin / Shfunc / Reswd via real disable/enable; new BUILTINS_DISABLED setbuiltin.c:541–547ported/builtin.rs
builtin.rsinit_builtins — real reswdtab.disable("repeat") when not EMULATE_ZSHbuiltin.c:212ported/builtin.rs:361
signals.rsSIGPIPE / SIGHUP / SIGINT / SIGWINCH / SIGALRM real bodies (zexit, errflag, stopmsg, adjustwinsize, TMOUT)signals.c:429–498ported/signals.rs:670
signals.rsPOSIXTRAPS option lookup for SIGEXIT sticky-tag bypasssignals.c:746ported/signals.rs
jobs.rskill %jobspec dispatch: real getjob + killjb + SIGCONT-after-stop loopjobs.c:2989–3010ported/jobs.rs:2635
params.rsgetsparam/getiparam/getnparam rewritten to C-faithful single-arg paramtab read (was a drift wrapper around HashMap)params.c:3076ported/params.rs:1726
params.rsnumeric-prefix detection (blanks / minus / 0x / base#) for PM_RIGHT_Z paddingparams.c:2446–2466ported/params.rs:975
params.rsfetchvalue real bracket-subscript dispatch into getindex + KSHARRAYS implicit [0]params.c:2289–2296ported/params.rs
params.rsnew DELUNSET atomic file-global; deleteparamtable save/restore; freeparamnode unsetfn dispatchparams.c:610 / 5986ported/params.rs
module.rsnew HOOKTAB global (mirror of Hookdef hooktab) + addhookfunc/deletehookfunc wrappersmodule.c:843ported/module.rs
module.rsnew MATHFUNCS global — user math fn chain for functions -Mmodule.c:1258ported/module.rs:31
zle/zle_main.rsnew WATCH_FDS global — bin_zle -F registration storezle_main.c:204ported/zle/zle_main.rs
zle/zle_refresh.rsnew TCOUT_FUNC_NAME global — bin_zle -T tc redisplay transformzle_refresh.c:246ported/zle/zle_refresh.rs
zle/zle_vi.rsVIRANGEFLAG / WORDFLAG / VILINERANGE / VICHGFLAG / VIINREPEAT / VIINSBEGIN atomic file-globals (replaces ViState aggregate)zle_vi.c:36–78ported/zle/zle_vi.rs
prompt.rssync_from_executorsync_from_globals: reads paramtab / LASTVAL / curhist / JOBTAB / scriptname directlyprompt.c:56ported/prompt.rs
utils.rsprintprompt4 reads isset(XTRACE) + getsparam("PS4") + opt_state save/restoreutils.c:1720–1730ported/utils.rs:5025
utils.rscallhookfunc walks shfunctab + paramtab <name>_functions arrayutils.c:1494–1514ported/utils.rs

try_with_executor migration: complete. 0 call sites remain in src/ported/ (down from 40). The two surviving mentions are documentation comments in subst.rs:169 and subst.rs:496 referencing the historical removal — no live dispatch path through the fake-executor abstraction.


*MODULE BREAKDOWN BY SUBSYSTEM

SubsystemModulesLines%Coverage BarDescription
Core Enginelexer, parser, exec, subst_port, subst29,93323.4%
Lexer, parser (AST), executor (pipelines, redirects, 145 builtins), substitution
ZLE Line Editorzle/* (28 files)35,67027.9%
Keymaps, widgets, vi mode, completion, refresh, history navigation, text objects, complete/complist/compctl/compmatch/compcore
Loadable Modulesdatetime, files, stat, system, tcp, pcre, curses, zftp, parameter, ksh93, zutil, ...26,41820.7%
35 module ports: networking, files, PCRE, curses, profiling, pseudo-tty, parameter introspection, math functions, db_gdbm, etc.
Utilitiesutils, compat, sort, tokens, input, linklist, mem, ...6,2047.3%
String ops, quoting (7 modes), escape parsing, path resolution, spelling correction
Parametersparams, param_private, parameter4,5965.4%
80+ special params, namerefs, scoping, tied pairs, typeset, GSU dispatch
Pattern / Globpattern, glob4,0824.8%
Compiled pattern engine, glob qualifiers, brace expansion, match/replace
Jobs / Signalsjobs, signals2,7843.3%
Process lifecycle, pipestats, trap scopes, signal queuing, fg/bg/disown
Mathmath, mathfunc2,4702.9%
Arithmetic evaluator, 40+ math functions (sin, cos, rand, int, float, abs, ...)
Prompt / Textprompt, text2,5323.0%
% escape expansion, colors, truncation, right prompt, AST deparsing
Historyhist, history2,2882.7%
Expansion (!!/!$/^old^new), modifiers (:h:t:r:e:s), file I/O, word splitting
Options / Initoptions, init, context1,6882.0%
200+ shell options, startup files, emulation modes (sh/ksh/csh/zsh)
Otherzwc, hashtable, completion, subscript, ...3,4894.1%
Compiled scripts (ZWC), hash tables, completion framework, subscript parsing
TOTAL208,696100%

+35 LOADABLE MODULE PORTS

Each C module from src/zsh/Src/Modules/ has a corresponding strict-port Rust implementation in src/ported/modules/. Module file set is included in the file freeze on src/ported/; every module now routes its features_ / enables_ / cleanup_ hooks through the canonical module::featuresarray / handlefeatures / setfeatureenables impls instead of per-module Rust-only stub copies.

zsh/attr

zgetattr, zsetattr, zdelattr, zlistattr — extended attributes (xattr)

zsh/cap

cap, getcap, setcap — POSIX capabilities (Linux)

zsh/clone

clone builtin — fork shell to new tty

zsh/curses

zcurses — ncurses windows, colors, attributes, input

zsh/datetime

strftime builtin, $EPOCHSECONDS/$EPOCHREALTIME/$epochtime

zsh/db/gdbm

ztie, zuntie, zgdbmpath — GDBM tied associative arrays

zsh/example

Demonstration module — builtins / conddefs / mathfuncs / paramdefs

zsh/files

chgrp, chmod, chown, ln, mkdir, mv, rm, rmdir, sync + zf_ aliases (18 entries)

zsh/hlgroup

$.zle.esc, $.zle.sgr — highlighting group helper

zsh/ksh93

nameref + .sh.* param family (edchar, edmode, file, lineno, match, name, subscript, subshell, version)

zsh/langinfo

$langinfonl_langinfo(3) queries (CODESET, D_FMT, etc.)

zsh/mapfile

$mapfile assoc array — memory-mapped file access

zsh/mathfunc

48 math functions (sin/cos/log/sqrt/atan/copysign/hypot/ilogb/nextafter/scalb/...)

zsh/nearcolor

Hook into get_color_attr for nearest-truecolor remap

zsh/newuser

First-login wizard hook (~/.zshrc seeding)

zsh/param/private

private builtin — local-only param scope override

zsh/parameter

33 magic assoc params: $parameters, $functions, $aliases, $commands, $options, $history, $modules, etc.

zsh/pcre

pcre_compile, pcre_match, pcre_study, =~ condition — Perl-compatible regex

zsh/random

$SRANDOM, zrand_float, zrand_int/dev/urandom backed

zsh/random/real

Real-valued random number generation (extras for math expressions)

zsh/regex

POSIX regex-match condition — [[ x =~ pat ]]

zsh/net/socket

zsocket builtin — Unix domain sockets

zsh/stat

zstat, stat builtins — stat fields, formatting, array output

zsh/system

syserror, sysread, syswrite, sysopen, sysseek, zsystem flock, systell math fn, $errnos/$sysparams

zsh/net/tcp

ztcp builtin — TCP client/server connections

zsh/termcap

echotc + $termcap assoc — termcap capability database

zsh/terminfo

echoti + $terminfo assoc — terminfo capability database

zsh/watch

log builtin, $WATCH/$watch arrays — login/logout watching, utmp parsing

zsh/zftp

zftp builtin — full FTP client (open / get / put / ls / cd / mkdir / ...)

zsh/zprof

zprof builtin — function profiler (gprof-style call/arc graph)

zsh/zpty

zpty builtin — pseudo-terminal process management

zsh/zselect

zselect builtin — poll/select on file descriptors

zsh/zutil

zformat, zparseopts, zregexparse, zstyle — completion-system utilities


^ZLE LINE EDITOR — 28 FILES, 35,670 LINES

The Zsh Line Editor (ZLE) is a complete terminal-based input system with vi and emacs keybinding modes, programmable widgets, and inline completion. Ported from src/zsh/Src/Zle/*.c. Files mirror the C source 1:1 with the canonical zsh prefix (zle_* / comp* / termquery / deltochar).

FileLinesResponsibility
compctl.rs3,170Legacy compctl system (pre-compsys, kept for back-compat)
compcore.rs3,082Completion core: shared matcher state, group ordering
zle_misc.rs2,602Miscellaneous widgets: transpose, case change, undo, named-cmd lookup
compmatch.rs2,179Match patterns, anchor matching, case-insensitive matchers
zle_main.rs2,128ZLE main loop, key reading, widget dispatch, initialization, WATCH_FDS
zle_keymap.rs1,973Keymap management, key binding, bindkey builtin
computil.rs1,831Completion utility functions used by _arguments etc.
zle_hist.rs1,717History widgets: up/down, search, accept-line
zle_vi.rs1,640Vi mode: motions, operators, text objects, registers; VIRANGEFLAG / WORDFLAG / VILINERANGE / VICHGFLAG / VIINREPEAT / VIINSBEGIN atomics
zle_utils.rs1,575ZLE utility functions, character classification, prompt expansion
zle_refresh.rs1,390Screen refresh, cursor positioning, line wrapping, TCOUT_FUNC_NAME
zle_thingy.rs1,349Thingy (widget reference) management, zle -A / zle -N
zle_move.rs1,291Cursor movement: word, line, char, matching bracket
zle_params.rs1,253ZLE special parameters: $BUFFER, $CURSOR, $LBUFFER, $RBUFFER, $REGION_ACTIVE, etc.
zle_tricky.rs1,155Completion: prefix matching, menu selection, listing
complete.rs1,018Completion engine: compadd, compset, _arguments dispatch
compresult.rs982Match result presentation, prefix/suffix sharing
zle_h.rs897Header port — keymap / widget / keystruct types
zle_word.rs854Word detection, WORDCHARS handling, shell-word vs vi-word
complist.rs800Menu selection (Tab cycling, arrow nav, mouse)
comp_h.rs740Header port — Cmatcher / Cmgroup / Cmlist types
termquery.rs627Terminal capability queries (tigetstr / tparm)
zleparameter.rs339$widgets, $keymaps, $builtins intro params for zle/parameter module
textobjects.rs329Vi text objects: iw, aw, i", a(, i{, etc.
compctl_h.rs323Header port for compctl
zle_bindings.rs252Default emacs/vi keymap tables
deltochar.rs119Delete-to-char widget (Vi f/t/F/T family)
mod.rs55Module declarations and re-exports
TOTAL ZLE35,670

;145 SHELL BUILTINS

Every zsh builtin is implemented as a builtin_* method on ShellExecutor in exec.rs. This includes all POSIX builtins, all zsh extensions, all loadable module builtins, and file operation builtins.

Variable Declaration (12)

typeset local declare export readonly integer float set unset shift private readarray

I/O (10)

echo print printf read getln pushln sysread syswrite sysopen sysseek

Flow Control (8)

eval source exec command builtin noglob break continue

Job Control (9)

bg fg jobs kill wait disown suspend coproc trap

Directory (6)

cd pushd popd dirs pwd rehash

History (3)

fc history r

Options & Emulation (5)

setopt unsetopt emulate shopt enable

Alias & Function (7)

alias unalias functions autoload unfunction disable hash

Completion (13)

compgen complete compdef compadd compset comptags comptry compopt compinit compctl compcall comparguments compquote

ZLE (4)

bindkey zle vared add-zsh-hook

File Operations (12)

mkdir rmdir rm cp mv ln chmod chown sync zstat zattr zfiles

Lookup (8)

type whence where which unhash caller help let

Modules & Compiled (4)

zmodload zcompile getopts zparseopts

Networking (3)

ztcp zsocket zftp

Terminal & Prompt (5)

echotc echoti ttyctl promptinit prompt

System & Limits (8)

ulimit limit unlimit umask times syserror sysseek exit

Misc (28)

sched zformat zstyle ztie zuntie zgdbmpath strftime zsleep zsystem zselect zpty zprof zregexparse clone log cap zcurses pcre_compile pcre_match pcre_study cdreplay return logout true false test [ :


&DEPENDENCY ARCHITECTURE

                         ┌──────────────────────────────────────┐
                         │            exec.rs (22,994)          │
                         │     ShellExecutor + 145 builtins     │
                         └──────────┬───────────────────────────┘
                                    │
               ┌────────────────────┼─────────────────────┐
               │                    │                     │
        ┌──────▼──────┐     ┌──────▼──────┐      ┌───────▼──────┐
        │  parser.rs   │     │  lexer.rs   │      │ subst_port.rs│
        │  (4,099)     │     │  (2,551)    │      │  (5,021)     │
        │  AST builder │     │  tokenizer  │      │  expansion   │
        └──────────────┘     └─────────────┘      └──────────────┘
               │                                          │
    ┌──────────┼──────────────────────────────────────────┤
    │          │          │          │          │          │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐
│params │ │pattern│ │ glob  │ │ hist  │ │ math  │ │  text  │
│(3,630)│ │(1,581)│ │(2,501)│ │(1,825)│ │(1,714)│ │  (980) │
└───┬───┘ └───────┘ └───────┘ └───┬───┘ └───────┘ └────────┘
    │                             │
┌───▼───┐ ┌───────┐ ┌───────┐ ┌──▼────┐ ┌────────┐ ┌───────┐
│ utils │ │ jobs  │ │signals│ │prompt │ │  init  │ │options│
│(3,204)│ │(1,667)│ │(1,117)│ │(1,552)│ │  (598) │ │ (877) │
└───────┘ └───────┘ └───────┘ └───────┘ └────────┘ └───────┘
               │
    ┌──────────┼──────────────────────────┐
    │          │          │               │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐    ┌──────▼──────┐
│  zwc  │ │  zle/ │ │  cond │    │  20 modules │
│(1,577)│ │(8,227)│ │  (818)│    │  (16,149)   │
└───────┘ └───────┘ └───────┘    └─────────────┘

COMPSYS — ZSH COMPLETION SYSTEM IN RUST

A standalone Rust crate reimplementing zsh’s compsys — the programmable completion system. 27 modules, 23,319 lines, 154 public functions. Replaces 24,000+ lines of zsh shell functions with compiled Rust backed by Rkyv caching.

23,319
Rust Lines
27
Modules
154
Public Functions
74
Structs
17
Enums
222
Tests
70
Completion Functions
ModuleLinesDescription
menu.rs3,567Menu completion: selection UI, scrolling, columns, groups, colors, accept/reject
cache.rs1,859SQLite mirror tables for compsys: autoload paths, compiled function index, invalidation. Mirror only — the authoritative completion cache is the rkyv-mmap'd shard set (zero-copy hot path); this file backs dbview / SQL inspection.
functions.rs1,244Completion function loading, autoload, function resolution from fpath
base.rs1,177Core completion types, match data, completion context, prefix/suffix handling
main.rs1,077Entry point, CLI, completion request dispatching
generate.rs1,009Completion spec generation from command help output, man pages, --help parsing
zstyle.rs970zstyle pattern-based configuration: :completion:* contexts, lookup, inheritance
compinit.rs831Completion system initialization: dump/load, fpath scan, function registration
zpwr_colors.rs793ZPWR color integration: colored completions, syntax highlighting in menu
arguments.rs767_arguments implementation: option specs, argument actions, exclusive groups
computil.rs675Completion utilities: _describe, _values, _alternative, _combination
zle.rs673ZLE integration: widget binding, cursor positioning, buffer manipulation
compcore.rs640Core completion engine: matching, prefix analysis, suffix insertion
completion.rs635Completion result types, display formatting, grouping
library.rs626Completion library management: function registry, lazy loading, caching
compset.rs616compset command: prefix/suffix matching, cursor word extraction
state.rs495Completion state machine: current word, context stack, match state
system.rs492System completions: users, groups, hosts, pids, signals, file types
compadd.rs458compadd builtin: add matches with prefix, suffix, display, description
matching.rs458Match control: case insensitivity, partial matching, anchored/unanchored
shell_runner.rs399Shell function runner: eval completion functions in isolated environment
compdef.rs305compdef command: register completion functions for commands
files.rs303File completion: _path_files, _files, _directories, glob patterns
describe.rs272_describe: completion with descriptions, columnar display
lib.rs145Crate root: public API, re-exports
TOTAL COMPSYS20,486(25 modules in table; bins/menu_demo.rs + bins/bench_autoload.rs add 2,833 for crate total 23,319)

// 70 COMPLETION FUNCTIONS

Base/Core (35 files)

_wanted, _requested, _dispatch, _setup, _all_labels, _normal, _next_label, _main_complete, _message, _tags, _description, _arguments, _values, _alternative, _describe, _guard, _regex_arguments, _combination, _multi_parts, and more

Base/Utility (30 files)

_path_files, _files, _directories, _users, _groups, _hosts, _pids, _signals, _parameters, _options, _jobs, _command_names, _globquals, _history_complete_word, and more

Unix + Zsh (5 files)

_path_files, _files, _directories (Unix), _command (Zsh) — core file and command completion


FUSEVM + LEX / PARSE (src/ported/)

Runtime bytecode targets the crates.io fusevm crate (pinned in workspace Cargo.toml). Lexing and parsing live in src/ported/lex.rs and src/ported/parse.rs in the runtime crate (the standalone parse package was absorbed back). Stryke / strykelang is a separate repository — it is not part of this workspace; the former Perl-interpreter block here was erroneous pasted content.

// LEX + PARSER (IN-CRATE PORTS)

FileLinesRole
src/ported/lex.rs4,617Lexer port of Src/lex.c — tokens, contexts, alias fusion
src/ported/parse.rs5,015Parser port of Src/parse.c — lists, compounds, redirections
LEX + PARSE9,632two files in src/ported/ (no separate parse crate)

// EXECUTION PIPELINE (ZSHRS)

  Source / REPL input (zsh script)
       │
       ▼
  ┌─────────────────┐     ┌──────────────────┐
  │  Lexer          │────▶│  Parser          │
  │  (lex.rs)       │     │  (parse.rs)      │
  │  token stream   │     │  AST / commands  │
  └────────┬────────┘     └────────┬─────────┘
           │                       │
           └───────────┬───────────┘
                       ▼
              ┌────────────────────┐
              │ compile_zsh (+AOT) │  ──▶  fusevm bytecode (workspace crate)
              │ extensions/        │
              └─────────┬──────────┘
                        ▼
              ┌────────────────────┐
              │ ShellExecutor / VM │  ──▶  builtins, jobs, redirects, zle
              └────────────────────┘

BEYOND THE C PORT — RUNTIME INFRASTRUCTURE

The C-to-Rust port covered above lives under src/ported/ against upstream src/zsh/Src/**/*.c. The numbers below count what zshrs adds — new Rust code with no C ancestor. This is the layer that takes zshrs from “zsh in Rust” to “the first compiled Unix shell with a session-persistent daemon, AOP-intercept recorder, and bidirectional ptmx-attach job supervisor.” Non-port runtime code lives in src/extensions/ — mechanically isolated from src/ported/ by tests/port_purity.rs.

Crate / LayerFilesLinesPub FnsTestsPurpose
src/extensions/ 34 33,474 229 219 The non-port directory. Features zsh C demonstrably does not have: AOT compile (aot.rs, compile_zsh.rs), autoload / plugin / script caches (autoload_cache.rs, plugin_cache.rs, script_cache.rs), fish-style features (fish_features.rs), persistent worker pool (worker.rs), arith JIT compiler (arith_compiler.rs), AST s-exp dump (ast_sexp.rs), ZWC byte-code helpers (zwc.rs, zwc_decode.rs), recorder hooks (recorder.rs), daemon presence (daemon_presence.rs), structured logging (log.rs), keymaps / widgets (zle/keymaps.rs, zle/widgets.rs, zle/widget.rs), ext builtins (ext_builtins.rs), regex module (regex_mod.rs), config (config.rs), overlay snapshot + canonical apply (overlay_snapshot.rs, canonical_apply.rs), subscript / fds / hist (subscript.rs, fds.rs, history.rs), stringsort, completion shim. Re-exported at crate root via pub use crate::* aliases so call sites still resolve to crate::aot::*, etc.
daemon/ 41 23,979 202 91 Singleton daemon: IPC server, HTTP listener (auto-derived OpenAPI 3.1), canonical-state engine, fsnotify, schedule, supervisor (jobs + bidirectional ptmx attach), pub/sub bus, named locks, ask-inbox, snapshots, artifacts, cache. Hosts every z* builtin.
src/recorder/ (feature-gated) 1 1,126 46 0 AOP intercept: every state-mutating dispatcher fires a record event with (kind, name, value, file, line, fn_chain). #[cfg(feature = "recorder")]-gated — deleted by rustc in the default zshrs build, compiled into the separate zshrs-recorder binary. Replaces the static-walker approach every other shell uses for completion/fpath scanning.
fish/ 157 86,917 1,244 175 Fish-style reader, syntax highlighter, autosuggestions, abbreviations, env dispatch, history backend, process control, event system. Largest non-port surface in the workspace.
compsys/ 27 23,319 480 222 Completion-system rkyv mmap, read-only SQL mirror, zstyle. Workspace crate; no C ancestor (zsh's compsys is shell-script, not C).
NEW INFRASTRUCTURE (rows above)260168,8152,201707
Sums cover the five layers in this table only. Workspace-wide Rust LOC (651,206) additionally includes src/ported/, remaining src/ glue, tests/, bins/, and build.rs.

Architectural moves with no zsh equivalent: the 90/10 daemon/shell work split (singleton daemon owns every mutation; thin shell clients are stateless and forkable); the recorder-owns-rebuild stance (no in-daemon walker; zshrs-recorder is the sole producer of recorder-managed canonical subsystems); the single ~/.zshrs/ directory rule (every config + log + sqlite + rkyv shard + socket under one root, configurable via $ZSHRS_HOME); the z* builtin family (zcache / zls / zsend / znotify / zsubscribe / zjob / zsync / zask / zlock / zpublish / zwhere / zd); session-persistent supervised jobs with bidirectional ptmx attach (replaces nohup + screen + pueue + disown); the auto-derived OpenAPI 3.1 surface at GET /openapi from the daemon op registry; the flat zsh-extended-history text file + sibling FTS5 sqlite index; zsh grammar introspection to stdout (lexer token stream, Eprog wordcode layout, parser AST S-expression) via zshrs --dump-* and zshrs_dump (dumptokens, dumpwordcode) in formats byte-diffable against parity harnesses — not shipped as a trio by stock zsh. Full list + governance in CREATORS.md; op-by-op detail in daemon-report.html.


GRAND TOTAL — FULL WORKSPACE

Two Rust packages in one Cargo workspace (zshrs + zshrs-daemon; compsys was folded into zshrs). Combined: 651,206 Rust lines (git ls-files '*.rs' | xargs wc -l), 5,483 pub fn lines (git ls-files '*.rs' | xargs rg '^\s*pub fn '), 580 pub struct, 126 pub enum, 14,638 #[test] lines (git ls-files '*.rs' | xargs rg '^\s*#\[test\]') — each rg over the same tracked .rs set as wc, 2026-05-27.

651,206
Total Rust Lines
5,471
pub fn (rg)
14,638
#[test] Hooks
2
Workspace Crates
CrateLinesFilesPub FnsStructsEnumsTestsShareDescription
zshrs (root, lib zsh)416,8263544,9755221165,943
89.8%
Runtime: src/ (ported + extensions + exec bridge), fish/, bins/, tests/, build.rs. Lines/tests include integration suites.
compsys23,319274807517222
5.0%
Programmable completion: zstyle, compadd, menu selection, SQLite-backed cache.
zshrs-daemon24,2444120238691
5.2%
Singleton daemon: IPC + HTTP/OpenAPI, canonical shards, jobs, fsnotify, pub/sub.
WORKSPACE651,2066135,48358012614,638