Add ASCII rendering fallback for terminals without image protocols#158
Open
jpeletier wants to merge 5 commits into
Open
Add ASCII rendering fallback for terminals without image protocols#158jpeletier wants to merge 5 commits into
jpeletier wants to merge 5 commits into
Conversation
Adds a new ImageProtocol::Ascii variant that renders git commit graphs using Unicode box-drawing characters (─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼) instead of terminal graphics protocols. Each graph column becomes a single character cell, with commit nodes rendered as `*` and colored per branch. Auto-detection now conservatively falls back to ASCII when the terminal doesn't support Kitty graphics or recognized iTerm2-compatible protocols (iTerm.app, WezTerm, mintty, VSCode, or LC_TERMINAL=iTerm2). This makes the tool work out-of-the-box in standard terminals like gnome-terminal, alacritty, xterm, and others, while preserving fancy image rendering for terminals that support it. Users can explicitly select ASCII mode with `--protocol ascii` or configure it in their serie config file.
Honor the configured GraphStyle in ASCII rendering: use rounded corners (╭╮╰╯) for Rounded and angular (┌┐└┘) for Angular. Render commit nodes as ● instead of * for better visual weight.
Honor --graph-width double in ASCII mode (was previously forced to single). In double-width mode each graph column spans two character cells: a symbol followed by a filler that becomes ─ when a horizontal edge crosses the gap, or a space otherwise. Distinguish merges from branch sources by the corner type in the row: LeftTop/RightTop corners signal a parent merging up from below, so the commit renders as ○ with a > or < arrow pointing into it from the adjacent filler slot. Branch sources (LeftBottom/RightBottom corners) keep the solid ● glyph and a plain ─ filler. Extract render_ascii_row from build_ascii_prepared_image so the row-level rendering can be unit-tested without constructing a full Graph. Adds 38 unit tests covering edge_directions, ascii_symbol for both styles, single and double width row rendering, merge-vs-branch-source discrimination, and > / < arrow placement.
Update README, mdBook docs, and JSON config schema to cover the new ASCII rendering mode added in this branch. Also reframes the project tagline from "uses image-display protocols" to "uses image-display protocols where available, with a Unicode fallback otherwise", and rewrites the FAQ entry that previously stated there was no fallback. - README: add `ascii` to the protocol enum in the help block and to the "Supported terminals" list; soften the tagline. - docs/introduction: match README tagline. - docs/faq: replace "no fallback" answer with a list of the supported rendering modes and how to force ASCII. - docs/configurations/config-file-format: add `ascii` to the `core.option.protocol` enum and describe what each value does. - docs/getting-started/command-line-options: list `ascii`, document the new auto-detect order (Kitty → iTerm-family terminals → ASCII), and note that ASCII honors --graph-style and --graph-width. - docs/getting-started/compatibility: add an "ASCII fallback" section describing the supported glyph variants, expand the tmux entry to cover the ASCII case, and note that previously-unsupported environments (Sixel-only terminals, other multiplexers) still work via ASCII. - config.schema.json: add `ascii` to the protocol enum.
auto_detect() correctly degraded the Kitty branch to KittyUnicode (which wraps escapes in a tmux passthrough envelope) when running under tmux, but the iTerm2 branch had no equivalent guard. Since iterm2_encode emits a raw \x1b]1337;...\x07 OSC sequence with no passthrough wrapping, a tmux session that leaks TERM_PROGRAM=iTerm.app (the common case) would get the iTerm2 protocol selected and silently render nothing — defeating the whole point of the ASCII fallback added in this branch. Gate iTerm2 on !detect_tmux(). Under tmux without Kitty, auto_detect now returns Ascii, which matches what compatibility.md already claims. Extract the if/else into decide_protocol(kitty, iterm, tmux) so the matrix is testable without process-global env-var mocking. Adds 7 unit tests covering every combination of signals. Reported in code review at #1.
Owner
Author
|
Got it--I did this because I was frustrated I downloaded |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Unicode box-drawing fallback (
--protocol ascii) so serie works in any terminal — gnome-terminal, alacritty, xterm, Windows Terminal, etc. — without needing the Kitty or iTerm2 image protocols. Auto-detect now uses it as the default for terminals it cannot identify, instead of unconditionally trying iTerm2.What changed
ImageProtocol::Asciivariant, selectable via--protocol asciiorcore.option.protocol = \"ascii\"in config.KITTY_WINDOW_ID/ Ghostty, iTerm2 whenTERM_PROGRAMmatchesiTerm.app/WezTerm/mintty/vscode(orLC_TERMINAL=iTerm2), and ASCII otherwise.● ─ │ ╭ ╮ ╰ ╯(rounded) or┌ ┐ └ ┘corners with--graph-style angular.○for merge commits and>/<arrows in the filler slot showing which side the merged-in branch enters from. Merges are detected byLeftTop/RightTopcorner edges in the row (branch-source commits stay as●).edge_directions,ascii_symbolfor both styles,render_ascii_rowsingle + double width, merge-vs-branch-source discrimination, and arrow placement. Test count: 83 unit + 19 integration (was 45 + 19).config.schema.json.Example
A synthetic repo with three feature branches merged back to master, rendered with
--protocol ascii --graph-width double --graph-style rounded:Each merge commit shows as
○with a<(or>) arrow pointing into it from the side the merged-in branch curls down to. Branch-source commits (likem5,m3) stay as●because their corner edges areLeftBottom/RightBottom, notLeftTop/RightTop. Branch colors come from the existing palette.In single-width mode the same graph collapses to one character per column:
Test plan
cargo test --releasepasses (102 tests total)cargo build --releaseproduces a clean binary--protocol ascii --graph-style angular— produces angular corners--protocol ascii --graph-width double— produces○+ arrows on merges