Tennis: The High-Performance Terminal Umpire for Structured Data
How a minimalist Zig tool uses terminal sensing and heuristic sniffing to solve the oldest problems in CLI data visualization.

tennis is a small CLI for printing stylish CSV tables in your terminal. Rows will be truncated to fit and it'll automatically pick nice colors to match your terminal. Written in Zig.
- Tennis queries the terminal via escape sequences to automatically adjust color contrast and detect data delimiters.
- The custom Doomicode engine calculates the visual width of complex Unicode characters to prevent table wrapping.
- Zig’s memory management allows the tool to process massive datasets by lazily allocating memory only for visible rows.
- The application provides zero-config visualization by acting as a constraint solver for terminal layout.
The Zero-Config Mirage
Dumping a CSV into a terminal usually results in a wall of unreadable text. Standard utilities assume the user wants raw output, leaving alignment and formatting as an exercise for the reader. Tools that do attempt formatting often require strict flags to declare delimiters or fail completely when rendering white text on a light terminal background. Tennis solves this through environmental sympathy.
Instead of demanding configuration, it senses its surroundings. It queries the terminal emulator via OSC 11 escape sequences to detect the background color, automatically adjusting its rendering palette for high contrast. Simultaneously, a built-in sniffer samples the input stream to guess the file format and delimiter.
Measuring the Unmeasurable
Formatting a table in a terminal requires knowing exactly how wide each column is. This is notoriously difficult due to the complexities of Unicode and emojis, where string length in bytes rarely matches the visual width in terminal cells. The project tackles this with a custom implementation called Doomicode.
Once the true widths are known, the layout engine acts as a constraint solver. It compares the natural width of the data against the physical width of the terminal. If the table is too wide, it proportionally shrinks the columns down to a defined lower bound before safely truncating the text. This guarantees the table never wraps and breaks the grid.
Zig's Mechanical Sympathy
The choice of Zig provides a distinct advantage in performance and distribution. The entire application compiles to a tiny, dependency-free binary. The codebase demonstrates a deep mechanical sympathy for memory management, utilizing scratch buffers during the CSV loading phase.
By reusing exactly the same memory block to process every field in a row before committing the final result, the tool minimizes expensive allocations. Furthermore, it employs lazy processing. If a user only wants to view the first ten rows of a massive dataset, the formatter only allocates and aligns those visible rows, skipping the rest entirely.
The Competitive Baseline
Tennis occupies a specific niche between raw text viewers and heavy data processing pipelines. It is a viewer first, designed for immediate visual comprehension rather than complex data mutation.
| Tool | Primary Focus | Auto-Format | Terminal BG Sensing |
|---|---|---|---|
| cat / column | Raw text dumping | No | No |
| qsv | Data processing (Rust) | Requires flags | No |
| visidata | Interactive exploration | Yes | No |
| tennis | Zero-config visualization | Automatic | Yes |
By focusing entirely on the presentation layer and abstracting away the friction of configuration, it turns the terminal back into a first-class environment for understanding structured data.