peektea v0.2: Split-Pane Previews and Inline Images Land
Maneshwar, creator of git-lrc, just shipped a significant update to peektea, the terminal-based file browser. The headline feature: a side-by-side preview panel that opens with a single keypress. Press p and the right half of the terminal shows the content of the file under the cursor. Press p again, it closes.
But the implementation details are what make this update worth a closer look.
Async Loading with Bubble Tea Commands
Previewing files can't block the TUI. Reading a large text file or spawning chafa for image conversion takes time. The solution: Bubble Tea's tea.Cmd pattern. The loadPreview function returns a tea.Cmd that runs a goroutine and sends a previewMsg back to the model when done. Here's the core:
type previewMsg struct{ content string }
func loadPreview(path string, entry os.DirEntry, width, height int) tea.Cmd {
return func() tea.Msg {
if entry.IsDir() {
return previewMsg{content: previewDir(path, width, height)}
}
if isImageExt(entry.Name()) {
return previewMsg{content: previewImage(path, width, height)}
}
return previewMsg{content: previewText(path, width, height)}
}
}
While the command runs, the model sets previewLoading = true and the panel shows "loading…". The TUI stays fully responsive — you can keep navigating while a slow preview loads. When the goroutine finishes, the message arrives via Update and the panel renders the result.
Image Previews via chafa
peektea now renders images inline in the terminal using chafa, a terminal image converter that outputs colored Unicode blocks. The previewImage function calls chafa with --size WxH to fit the preview panel exactly:
func previewImage(path string, width, height int) string {
if _, err := exec.LookPath("chafa"); err != nil {
return "[image — install chafa for inline preview]"
}
out, err := exec.Command("chafa",
"--size", fmt.Sprintf("%dx%d", width, height),
path,
).Output()
if err != nil {
return fmt.Sprintf("[image preview failed: %v]", err)
}
return strings.TrimRight(string(out), "\n")
}
If chafa isn't installed, the panel shows a helpful message instead of crashing. The peektea init command now checks for chafa at setup and prints the install command for your distro if missing.
Binary Detection
Opening a binary file as text produces garbage. peektea uses the standard heuristic — checking the first 512 bytes for null bytes, the same method used by git diff:
func isBinary(path string) bool {
f, err := os.Open(path)
if err != nil {
return false
}
defer f.Close()
buf := make([]byte, 512)
n, _ := f.Read(buf)
for _, b := range buf[:n] {
if b == 0 {
return true
}
}
return false
}
Binary files get a clean [binary file] notice instead of noise.
Adaptive Panel Sizing
peektea handles four preview types: text (first N lines, tab-expanded, truncated to panel width), images (via chafa), directories (lists contents with same styling as browser), and binaries (notice).
The terminal size is tracked via Bubble Tea's tea.WindowSizeMsg:
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
The left panel width adapts: it starts at 50 characters and expands to fit the longest filename in the current directory, but always leaves at least 30 characters for the preview panel. Navigate into a directory with long filenames and the left panel widens; navigate out and it shrinks back.
The Hint Bar
The hint bar at the bottom of the left panel is pinned to the last terminal row. The panel fills the gap between the last file entry and the bottom with blank lines, so the hint always sits at the floor — feels like a proper pane.
What's Next
The to-do list is getting shorter. Already done: image previews and split-pane preview. Coming next: filter-as-you-type (using Bubble Tea's textinput component) and a hidden file toggle. The pattern — model grows, Update handles new keys, View renders new state — still scales.
Why This Matters for Developers
peektea is part of a broader trend: terminal-based tools that rival GUI file managers. The async loading pattern using Bubble Tea commands is a clean reference for any TUI project. If you're building terminal UIs in Go, this update shows how to handle long-running tasks without blocking the interface.
Try peektea today. Star the repo on GitHub. And if you're using AI agents that write code, check out git-lrc — it hooks into git commit and reviews every diff before it lands.


