>_POWERLINERS — RUST POWERLINE
A Rust port of Python's powerline-status — the canonical statusline / prompt renderer used by tmux, zsh, bash, vim, ipython. The Python implementation pays a ~100 ms interpreter-startup tax on every render; powerliners is a single static binary with sub-millisecond startup.
Why a port?
- Python interpreter startup adds ~100 ms per render — on every keystroke that triggers a zsh `precmd` redraw, every tmux statusline tick, every shell continuation line.
- At zpwr scale (256-thread workstation, 100+ zsh-in-tmux sessions), powerline-status compounds into seconds of cumulative latency per minute.
- Rust gives a static binary, microsecond startup, zero runtime deps, cross-arch builds, and predictable memory.
- The upstream theme grammar (JSON files in
powerline/config/) is preserved verbatim — users keep their themes unchanged.
Targets
tmux
statusline + window-list + continuation lines
zsh
PS1 / RPROMPT segments, precmd integration
bash
PS1 / PROMPT_COMMAND segments
vim
statusline + tabline (without `+python3` dependency)
ipython
REPL prompt (via shell hook, not embedded)
Port discipline
Every fn name landed in src/ported/ must exist in upstream powerline Python source. Enforced by tests/ported_fn_names_match_py.rs against docs/powerline_py_functions.txt (currently 631 names extracted from github.com/powerline/powerline). Maintainer-approved Rust-only exemptions live in tests/data/fake_fn_allowlist.txt.
# regenerate the upstream allowlist ./scripts/regen_py_functions.sh # audit will fail with a list of any invented fn names cargo test --test ported_fn_names_match_py
This pattern mirrors the zshrs ported_fn_names_match_c.rs enforcement — the audit test is load-bearing and must not be weakened.
Status
Port is structurally complete at the function level. 134 of 137 upstream Python files are at DONE tier per the citation-density classifier (scripts/gen_port_checklist.py); the 3 remaining NEAR files are class-only Python sources (readline.py, zsh.py, powerline-i3.py) at the classifier's architectural ceiling. The Rust port spans ~62,168 LOC across src/ported/ with 2,102 lib tests + 2 audit tests + 219 parity tests passing. Parity tests pipe identical inputs through the upstream Python interpreter (via the vendored powerline-status) and the Rust port, asserting byte/value-identical results — 11 real port bugs were surfaced by this harness and fixed in-tree (ThreadedSegment.daemon, Spec.did_type, encoding locale lookup, _clear_special_values UB, Spec.ident regex, Spec.context_message recursion, Spec.tuple bounds, Spec.unknown_msg/_spec dispatch, NON_PRINTABLE_RE inversion, Spec.printable/unsigned). Every fn name under src/ported/ traces to one of 631 upstream Python fn names (or to tests/data/fake_fn_allowlist.txt for maintainer-approved exemptions); every ported body carries // py:NNN line-citations against upstream powerline/. End-to-end statusline rendering against a real .json theme tree depends on the Powerline orchestrator chain (Powerline class + Renderer base + segment dispatcher) — wired up at the unit level, integration-glue is the remaining substrate. Watch tags for milestone bumps.
Install
# source + build
git clone https://github.com/MenkeTechnologies/powerliners.git
cd powerliners
cargo build
ls target/debug/powerliners target/debug/powerline-{render,lint,config,daemon}
Five binaries land in target/debug/: powerliners (demo CLI for ported leaf utilities), powerline-render, powerline-lint, powerline-config, and powerline-daemon. The daemon lifecycle (UNIX socket bind, daemonize, pidfile lock, accept loop, EOF shutdown) is fully functional; render returns a placeholder string until the Powerline orchestrator integration completes. powerline-render / powerline-lint / powerline-config shim through the ported scripts/ module mains — argparse and dispatch live, full pipelines depend on the same orchestrator chain.
Bundled segments
src/extensions/ ships net-new segments above upstream powerline-status, dispatched as standard built-ins via the daemon's ADAPTERS table. All accept a format theme arg and ship NF-default icons with Unicode + ASCII fallbacks (controlled by POWERLINERS_ICONS).
| segment | summary |
|---|---|
powerliners.gpu.gpu_usage_percent | Vendor-dispatched GPU compute % (nvidia-smi → rocm-smi → intel_gpu_top → ioreg fallback). |
powerliners.gpu.gpu_vram | GPU VRAM USED/TOTAL via the same dispatch chain. |
powerliners.disk.disk_usage | Filesystem USED/TOTAL for any mount. |
powerliners.disk.disk_usage_percent | Filesystem percent-used. |
powerliners.disk.disk_io | Live read/write throughput for any device. Tokens: {recv}/{sent} (human-formatted) / {recv_bytes}/{sent_bytes}. |
powerliners.thermal.thermal | CPU/GPU temp + fan RPM. /sys/class/hwmon on Linux, powermetrics/istats on macOS. |
powerliners.vcs.git_status | Single-probe git status — branch, ahead/behind, dirty/staged/untracked, stash count, action (rebase/merge/cherry-pick), tag at HEAD. github-remote detection prepends the octocat glyph. |
powerliners.docker.containers | Container counts via docker ps. Tokens: {running} / {total} / {images} / {stopped}. Falls through silently when the daemon is unreachable. |
powerliners.k8s.kubecontext | Current kubectl context + active namespace. Honors $KUBECONFIG cascade; hide_default arg suppresses the namespace fragment when it equals the configured default. |
powerliners.proc.process_count | POSIX process tally via ps -eo stat=. Tokens: {total}/{running}/{sleeping}/{zombie}/{dwait}/{stopped}. warn_zombie flips the highlight group when defunct processes are present. |
powerliners.github.ci_status | Current branch's HEAD check-runs via gh api repos/:o/:r/commits/:sha/check-runs, disk-cached by SHA (default ttl_secs=30). Tokens: {icon}/{state}/{passed}/{failed}/{running}/{total}. State-picked highlight group plus information:regular neutral fallback so the chunk renders in any colorscheme. |
powerliners.aws.context | Active AWS profile + region. Pure-fs probe of $AWS_PROFILE/$AWS_REGION/$AWS_DEFAULT_REGION then ~/.aws/config (handles the [profile NAME] quirk). Tokens: {icon}/{profile}/{region}. hide_default_profile strips the profile fragment when it equals default. |
powerliners.gcp.context | Active gcloud configuration's project + account. Pure-fs probe of ~/.config/gcloud/active_config + configurations/config_<NAME>. Env overrides $CLOUDSDK_ACTIVE_CONFIG_NAME / $CLOUDSDK_CORE_PROJECT / $CLOUDSDK_CORE_ACCOUNT win. |
powerliners.fusevm.jit_cache | fusevm Cranelift JIT cache stats — recursively walks $FUSEVM_JIT_CACHE / $XDG_CACHE_HOME/fusevm-jit / ~/.cache/fusevm-jit. Tokens: {icon}/{count}/{entries}/{harddisk}/{size} (du -sh-style block allocation)/{bytes} (raw disk bytes)/{logical_size}/{logical_bytes} (stat-style content sum). |
powerliners.zshrs.rkyv_cache | Single-file stat of the zshrs authoritative rkyv archive at $ZSHRS_RKYV_CACHE / $ZSHRS_HOME/scripts.rkyv / $XDG_DATA_HOME/zshrs/scripts.rkyv / ~/.zshrs/scripts.rkyv. Same {size} / {bytes} / {logical_*} token surface as fusevm.jit_cache. |
powerliners.stryke.rkyv_cache | Single-file stat of ~/.stryke/scripts.rkyv (stryke's bytecode store, Cranelift-JIT'd via the shared fusevm runtime). |
powerliners.awkrs.rkyv_cache | Single-file stat of ~/.awkrs/scripts.rkyv. |
powerliners.zshrs.version | Latest installed zshrs version (parsed from <bin> --version). In-process TTL cache (default 300 s, configurable via ttl_secs) so the daemon doesn't fork on every prompt tick. Tokens: {icon}/{version}. Returns None when the binary isn't on PATH. |
powerliners.stryke.version | Same as zshrs.version for the stryke binary — handles the This is stryke vX.Y.Z — ... prefix shape via the shared extract_version SemVer scanner. |
powerliners.awkrs.version | Same shared helper, default binary awkrs. |
powerliners.exec.exec | User-defined exec adapter — spawn an arbitrary script, parse stdout, render with a user-supplied format. Resolves via bare "function": "exec" as well as the dotted path. |
All segments live under src/extensions/<module>.rs and register through the daemon's ADAPTERS table in src/bin/shared/render_runtime.rs — see the audit section below for the live icon → segment cross-reference.
Glyph rendering
Every glyph below is a real Nerd Font codepoint loaded into this page via the @font-face block in docs/hud-static.css. The font is the official SymbolsNerdFont subset (~270 KB) served from jsdelivr CDN, with a unicode-range directive gating the load to PUA ranges only (U+E000-F8FF + U+F0000-FFFFD):
@font-face {
font-family: 'SymbolsNerdFont';
font-display: swap;
src: url('https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@master/patched-fonts/NerdFontsSymbolsOnly/SymbolsNerdFont-Regular.ttf') format('truetype');
unicode-range: U+E000-F8FF, U+F0000-FFFFD;
}
Body text and code blocks continue to render in Share Tech Mono / Orbitron — only PUA codepoints resolve through the NF subset, so the font swap has no layout impact. The same chain operates at runtime via POWERLINERS_ICONS: unset/default → NF glyph, =unicode → text-presentation Unicode fallback (e.g. ✓ ✗ 🐳 ⎈ ⛁), =ascii → label-style ASCII (e.g. OK FAIL D: k8s: D:).
Icon audit
Every Nerd Font codepoint shipped by src/extensions/icons.rs is listed here with its canonical upstream identity (verified against ryanoasis/nerd-fonts master, NF 3.4.0 default load order, legacy i_material.sh excluded). Each glyph below renders live via the SymbolsNerdFont @font-face declaration in hud-static.css — if a shipped glyph fails to match its claimed identity, it would be immediately visible in this table.
Three-tier fallback chain: Nerd Font (default) → Unicode (POWERLINERS_ICONS=unicode, text-presentation only) → ASCII (POWERLINERS_ICONS=ascii, label-style for non-UTF8 terminals).
A. Icon getters (24)
| fn | codepoint | NF name | source | NF | Unicode | ASCII | used by segment |
|---|---|---|---|---|---|---|---|
icons::disk() | U+F0A0 | i_fa_hard_drive | i_fa.sh | | ⛁ | D: | disk_io, disk_usage, disk_usage_percent |
icons::cpu() | U+F4BC | i_oct_cpu | i_oct.sh | | ⚙ | CPU: | ad_cpu_load_percent, thermal |
icons::gpu() | U+F2DB | i_fa_microchip | i_fa.sh | | ⎚ | GPU: | gpu_usage_percent, gpu_vram, thermal |
icons::memory() | U+EFC5 | i_fa_memory | i_fa.sh | | ▤ | MEM: | ad_mem_usage_percent, gpu_vram, mem_usage |
icons::thermometer() | U+F2C8 | i_fa_temperature_three_quarters | i_fa.sh | | 🌡 | T: | — unused |
icons::branch() | U+E0A0 | i_pl_branch | i_ple.sh | | ⎇ | b: | git_status |
icons::github() | U+F09B | i_fa_github | i_fa.sh | | 🐙 | gh: | ci_status, git_status |
icons::tag() | U+F02B | i_fa_tag | i_fa.sh | | ⚑ | tag: | git_status |
icons::docker() | U+F0868 | i_md_docker | i_md.sh | | 🐳 | D: | containers |
icons::kubernetes() | U+F10FE | i_md_kubernetes | i_md.sh | | ⎈ | k8s: | kubecontext |
icons::process() | U+F0493 | i_md_cog | i_md.sh | | ⚙ | P: | process_count |
icons::aws() | U+F0E0F | i_md_aws | i_md.sh | | aws | aws | context |
icons::gcp() | U+F11F6 | i_md_google_cloud | i_md.sh | | gcp | gcp | context |
icons::ci_ok() | U+F49E | i_oct_check_circle | i_oct.sh | | ✅ | OK | ci_status |
icons::ci_fail() | U+F52F | i_oct_x_circle | i_oct.sh | | ❌ | FAIL | ci_status |
icons::ci_run() | U+F46A | i_oct_sync | i_oct.sh | | 🔄 | RUN | ci_status |
icons::count() | U+F0222 | i_md_file_multiple | i_md.sh | | ▤ | n= | jit_cache |
icons::harddisk() | U+F02CA | i_md_harddisk | i_md.sh | | ⛁ | d= | jit_cache |
icons::swap() | U+F04E1 | i_md_swap_horizontal | i_md.sh | | ⇄ | SWAP: | ad_mem_swap_percentage, mem_swap |
icons::io() | U+F0E79 | i_md_arrow_up_down | i_md.sh | | ⇅ | IO: | disk_io |
icons::fusevm() | U+F01FA | i_md_engine | i_md.sh | | ⚙ | jit: | jit_cache |
icons::zshrs() | U+F07B7 | i_md_console_line | i_md.sh | | ❯ | zshrs: | rkyv_cache |
icons::stryke() | U+E769 | i_dev_perl | i_dev.sh | | λ | stryke: | rkyv_cache |
icons::awkrs() | U+E741 | i_dev_awk | i_dev.sh | | $0 | awkrs: | rkyv_cache |
B. Segment defaults (24)
Default format strings shipped by each powerliners.* / powerlinemem.* adapter when the theme JSON omits format. Live NF render uses the same glyphs as Table A.
| segment name | icons used | live NF render |
|---|---|---|
powerliners.gpu.gpu_usage_percent | | 47% |
powerliners.gpu.gpu_vram | | 8.2G/12G |
powerliners.disk.disk_usage | | 142G/512G |
powerliners.disk.disk_usage_percent | | 28% |
powerliners.disk.disk_io | | R 23M W 5M |
powerliners.thermal.thermal | | 67°C 1240RPM |
powerliners.vcs.git_status | | main ⇡2 |
powerliners.docker.containers | | 4/7 |
powerliners.k8s.kubecontext | | prod:default |
powerliners.proc.process_count | | 348 |
powerliners.github.ci_status | | 5/5 |
powerliners.aws.context | | prod@us-east-1 |
powerliners.gcp.context | | my-proj:me@e.com |
powerliners.fusevm.jit_cache | | 207 828K |
powerliners.zshrs.rkyv_cache | | 4.00K |
powerliners.stryke.rkyv_cache | | 34.9M |
powerliners.awkrs.rkyv_cache | | 8.00K |
powerliners.zshrs.version | | 0.11.26 |
powerliners.stryke.version | | 0.16.8 |
powerliners.awkrs.version | | 0.4.13 |
powerlinemem.mem_usage.mem_usage | | 12G/32G |
powerlinemem.mem_usage.mem_usage_percent | | 47% |
powerlinemem.mem_usage.mem_swap | | 1.2G/4G |
powerlinemem.mem_usage.mem_swap_percent | | 30% |
Anti-fakery rationale: a future maintainer who swaps a glyph (intentionally or by typo) without updating both the code AND this audit table will produce visibly wrong rendering on this page — the symptom is observable, not hidden behind a Rust unit test. The used-by-segment column on Table A is computed from the real adapter code in src/bin/shared/render_runtime.rs at build time (each fn ad_X body is scanned for icons::Y() calls and cross-referenced against the ADAPTERS dispatch table); a getter listed as — unused is dead code awaiting either a consumer or removal. The i_material.sh legacy MDI set is intentionally excluded from verification since NF 3.4.0 does not load it by default; codepoints that collide between i_oct.sh and legacy i_material.sh (e.g. U+F52F) resolve via the Octicons subset in any standard Nerd Font install.