Skip to content

tui: images are drawn in the terminal, through tmux too - #43

Merged
ralyodio merged 1 commit into
mainfrom
feat/tui-inline-images
Sep 13, 2026
Merged

ralyodio merged 1 commit into
mainfrom
feat/tui-inline-images

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

What

v on a PNG, JPEG, GIF, WebP or BMP now draws the image under the panes instead of a hex dump.

  • The file is read whole (up to 8 MB) and handed to the terminal over the iTerm2 inline-image protocol (WezTerm, iTerm2, Konsole) or the kitty graphics protocol (kitty, Ghostty), chosen from hqtui's emulator guess. An icon is drawn at its own size; a photo is shrunk to the box, aspect kept.
  • tmux: the sequence rides in a DCS passthrough envelope, and diskpush tui runs tmux set -p allow-passthrough on for its own pane at startup, so it works without touching anyone's config.
  • The image is written after hqtui's frame event into cells the view left blank, once, and again only when the file or the box changes. It is taken down with a kitty delete or an iTerm2 full repaint.
  • A terminal that cannot draw it shows the line PNG 2172×724. Drawn below when the terminal can (WezTerm, kitty, iTerm2, Konsole); x opens it elsewhere. over an empty box.

Tests

25 new tests: protocol choice, natural-size against fitted boxes, both encodings (kitty chunking included), the tmux envelope and cursor placement, header parsing for all five formats, the document kind, and the frame-driven placement, tmux wrapping, kitty delete and iTerm2 repaint through a fake app. 706 tests pass repo-wide; typecheck is clean.

The built binary was driven in a pty twice: plain, and with the tmux client itself inside the pty on a private server with no config. Both streams carried exactly one OSC 1337 at the panel's cell with a 380,192-byte payload identical to logo.png; the pane option read on mid-run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AhtFxxWvkm4izFq8Y1RQBo

A PNG, JPEG, GIF, WebP or BMP under the cursor is now read whole (up to
8 MB) and handed to the terminal over the iTerm2 inline-image protocol
(WezTerm, iTerm2, Konsole) or the kitty graphics protocol (kitty,
Ghostty), chosen from hqtui's guess at the emulator. Under tmux the
sequence rides in a DCS passthrough envelope, and `diskpush tui` sets
`allow-passthrough on` for its own pane at startup so nobody has to edit
a config. A terminal that cannot draw it shows a blank box under a line
saying what the image is and that x opens it elsewhere.

The image is not part of the frame: hqtui diffs cells and an image is
not a cell, so it is written after the frame event into cells the view
left blank, once, and again only when the file or the box changes. It
is taken down with a kitty delete or, for iTerm2, a full repaint. An
icon is drawn at its own size; a photo is shrunk to the box.

Verified by capturing the raw bytes of the built binary in a pty, both
plain and with the tmux client itself in the pty: one OSC 1337 at the
panel's cell, 380,192 bytes of payload identical to logo.png.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AhtFxxWvkm4izFq8Y1RQBo
@ralyodio
ralyodio merged commit 87617a3 into main Sep 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant