Skip to content

v0.9.0

Choose a tag to compare

@cwt cwt released this 31 Aug 05:48
· 164 commits to main since this release

szn v0.9.0

56 commits since v0.8.2. 959 tests passing.


Headline: Configurable Scrollback History, Zero-Allocation Ring Buffer, Runtime Log Control, and a 44-Bug Sweep

v0.9.0 is a major feature, performance, and reliability release. It introduces configurable per-pane scrollback history limits (history-limit) powered by a circular ring-buffer deque with zero-allocation steady-state line recycling, dynamic runtime log level control via the SZN_LOG environment variable, robust command-line argument quoting and escape parsing, extended terminal input compatibility (kitty keyboard normalization, DECSET 1003 mouse_any, alternate-screen mouse wheel arrow forwarding), and closes 44 bug entries (#395–#439) across memory safety, rendering, and IPC dispatch.


Key Improvements & Features

1. Configurable Scrollback History & Zero-Allocation Ring Buffer (#360, #361)

  • Configurable history-limit Option: Added history-limit session option (default: 2000, min: 0, max: 1000000) configurable via ~/.szn.conf / ~/.tmux.conf or dynamically at runtime using szn set-option -g history-limit <N>.
  • Circular Ring-Buffer Deque: Rewrote the scrollback history backend from an unbounded linear array into a fixed-capacity circular ring deque (GridLine circular indexing).
  • Line Cell Buffer Recycling: Evicted history lines at the ring boundary have their cell buffers recycled into the new line entering the bottom of the screen. Steady-state scrolling is now 100% zero-allocation, preventing session arena growth.
  • In-Place Grid Recycling: Added Pane.saveGrid and updated restoreSavedGrid to recycle visible line buffers in-place when dimensions match, eliminating multi-megabyte heap churn during clock-mode and choose-buffer mode toggles.
  • Dynamic Capacity Scaling: Implemented Grid.setHistoryLimit to dynamically resize active ring buffers across running panes, supporting instant eviction on limit reduction and linear normalization on expansion.

2. Runtime Log Level Control (SZN_LOG)

  • Environment Variable Control: Added SZN_LOG environment variable support (debug, info, warn, err) to control log verbosity at runtime without recompiling or modifying config files.
  • Diagnostic Demotion: Demoted high-frequency routine diagnostic messages from .info to .debug, keeping standard operational logs clean and informative.

3. Command Line & Configuration Parser Fidelity

  • Argv Quote & Escape Handling (#436): Implemented full argument tokenization in cmd.parse supporting single quotes ('...'), double quotes ("..."), and backslash escapes (\ ). Complex commands such as bind-key X "split-window -h; select-pane -R" now parse and execute seamlessly.
  • Combined Short Options & Scope Flags (#415): Enhanced configuration parser to handle combined short flags (e.g. -d -v), flag routing (-g, -w, -s), set-environment, and if-shell directives.
  • Interrupted Read Resilience (#437): Added EINTR retry handling to the load-buffer file read loop.
  • Session Init Rollback (#438): Automatically rolls back partially-initialized sessions in cmdNewSession if active window or pane setup fails.

4. Terminal Emulation & Extended Input Support

  • Alternate-Screen Mouse Wheel Forwarding (#427): Mouse wheel scrolling inside alternate-screen TUIs (less, vim, man) forwards Up/Down arrow key sequences (\x1bOA / \x1bOB), matching tmux behavior.
  • DECSET 1003 Any-Event Mouse Tracking (#422): Added full support for mouse_any tracking (all cursor motion events reported).
  • Kitty Keyboard Protocol Normalization (#430): Normalized kitty u-mode key codepoints for Tab, Enter, Escape, Backspace, arrow keys, Home, End, PageUp/Down, and F1–F12 into .special, .arrow, and .function variants so standard keybindings match predictably.
  • DCS & Sixel Discrimination (#429): Discard DCS sequences with intermediate bytes (such as DECRQSS ESC P $ q) instead of misrouting them into the Sixel parser.
  • Wide & Combining Character Width in Status Bar (#432): status.visibleLen accurately measures multi-byte UTF-8 CJK and combining characters using char_width.charWidth to prevent status range hit-test misalignments.

5. Memory Safety, IPC Flow Control & Server Hardening

  • MessageReader UAF on Client Detach (#428): Removed deferred reader consume in handleClient packet loop and ensured immediate return upon client detachment.
  • Render Output Flow Control (#431): Routed all frame emissions through appendClientOutFrame with high-watermark backpressure checks and output buffer limits.
  • PTY & Process Lifecycle Hardening (#395, #411, #439): Eliminated double-free and leaks on Pty.spawn fork failures, ensured idempotent Pty.deinit, bound PTY input buffer queuing to 1 MiB, and cleared reaped process IDs on pane destruction.
  • Pane Border Cache Invalidation (#433): Automatically invalidates cached pane border format expansions on resize, split, and layout restructuring.
  • Sixel Image Anchoring & Resize Eviction (#434, #435): Correctly shifts image anchor offsets during DECSTBM region scrolling and evicts out-of-bounds unreferenced images upon terminal resize.
  • Display Out-Queue Atomicity (#402, #418): Guaranteed atomic packet queuing and clean teardown of detached display clients.
  • Zero-Session Server Shutdown (#407, #408): Automatically cleans up and shuts down the server when the last window/session is closed.

44 Bug Fixes (#395–#439)

Category Bugs Resolved
Memory Lifecycle & Safety #395, #396, #398, #407, #408, #411, #428, #438, #439
Grid & Scrollback Deque #360, #361, #405, #421
Sixel Graphics & Screen #399, #406, #419, #420, #434, #435
Server IPC & Flow Control #400, #401, #402, #403, #404, #418, #423, #425, #431
Command & Config Parsers #397, #410, #413, #414, #415, #417, #433, #436, #437
Input & Terminal Emulation #409, #416, #422, #426, #427, #429, #430, #432

Testing & Quality Assurance

Metric v0.8.2 v0.9.0
Total Passing Tests 927 959
New Regression Tests — 32
Open Bugs in Tracker 0 0
Build Status Debug & ReleaseSafe Debug, ReleaseSafe & ReleaseFast passing