vev-vt
A Go library for reading terminal output and keeping track of what should appear
on screen. It powers vev.
Feed it the bytes from a shell or command. It handles text, colors, cursor
movement, scrolling and resizing. You can then read the screen, save its history,
or use the ansi package to draw it in a terminal.
This library does not start processes or manage a PTY. Your application does
that and passes the output to vev-vt.
Install
Requires Go 1.27 or newer.
go get github.com/bnema/vev-vt
Alpha software: APIs and saved-history formats can change between versions.
The current history format does not read older VTH3 data.
Read terminal output
package main
import (
"fmt"
vt "github.com/bnema/vev-vt"
)
func main() {
screen := vt.NewScreen(80, 24)
screen.Write([]byte("Hello, \x1b[31mworld\x1b[0m!"))
// Colors and escape sequences are processed, not included in the text.
for x := 0; x < 13; x++ {
fmt.Printf("%c", screen.Cell(x, 0).Rune)
}
fmt.Println() // Hello, world!
}
Use screen.Resize(columns, rows) when the terminal size changes.
Use screen.Snapshot() when you need a copy that stays unchanged as new output
arrives.
Scrollback is the text that has moved above the visible screen.
// Your application chooses these limits; vev-vt has no default budget.
config := vt.HistoryConfig{
MaxBytes: 20_000_000, // At most 20 MB of history data.
MaxRows: 5_000, // Optional: also keep at most 5,000 lines.
}
screen := vt.NewScreenWithHistory(80, 24, config)
vev-vt enforces the limits your application supplies. The PTY transports bytes;
it does not store scrollback. The oldest lines are removed when a supplied limit
is reached. Limits apply to each
screen separately and exclude the visible screen. The byte limit measures
uncompressed history data, not total process memory.
History guide →: limit settings, saving/restoring history and
optional compression during idle time.
A few rules
- Serialize
Write, Resize, Snapshot, reads and history mutations in one
goroutine, or protect them with your own lock.
- Rows returned by the API are copies. Changing one does not change the screen.
- Use
vt.DefaultStyle() for terminal-default colors, not vt.Style{}.
- Callbacks run during
screen.Write; keep them short.
API ownership and styles →
Packages
| Package |
Use it for |
vev-vt |
Parse terminal output, read the screen and manage history. |
vev-vt/core |
Work with cells, styles and writable grids. |
vev-vt/ansi |
Render a screen or grid as ANSI terminal output. |
vev-vt/graphics |
Read supported terminal images and their positions. |
Supported image features →
Development
go test ./...
go test ./... -race
go vet ./...
Storage benchmarks and design decisions →
source
1# vev-vt
2
3A Go library for reading terminal output and keeping track of what should appear
4on screen. It powers [vev](https://github.com/bnema/vev).
5
6Feed it the bytes from a shell or command. It handles text, colors, cursor
7movement, scrolling and resizing. You can then read the screen, save its history,
8or use the `ansi` package to draw it in a terminal.
9
10This library does **not** start processes or manage a PTY. Your application does
11that and passes the output to vev-vt.
12
13## Install
14
15Requires Go 1.27 or newer.
16
17```sh
18go get github.com/bnema/vev-vt
19```
20
21**Alpha software:** APIs and saved-history formats can change between versions.
22The current history format does not read older VTH3 data.
23
24## Read terminal output
25
26```go
27package main
28
29import (
30 "fmt"
31
32 vt "github.com/bnema/vev-vt"
33)
34
35func main() {
36 screen := vt.NewScreen(80, 24)
37 screen.Write([]byte("Hello, \x1b[31mworld\x1b[0m!"))
38
39 // Colors and escape sequences are processed, not included in the text.
40 for x := 0; x < 13; x++ {
41 fmt.Printf("%c", screen.Cell(x, 0).Rune)
42 }
43 fmt.Println() // Hello, world!
44}
45```
46
47Use `screen.Resize(columns, rows)` when the terminal size changes.
48Use `screen.Snapshot()` when you need a copy that stays unchanged as new output
49arrives.
50
51## Keep scrollback
52
53Scrollback is the text that has moved above the visible screen.
54
55```go
56// Your application chooses these limits; vev-vt has no default budget.
57config := vt.HistoryConfig{
58 MaxBytes: 20_000_000, // At most 20 MB of history data.
59 MaxRows: 5_000, // Optional: also keep at most 5,000 lines.
60}
61screen := vt.NewScreenWithHistory(80, 24, config)
62```
63
64vev-vt enforces the limits your application supplies. The PTY transports bytes;
65it does not store scrollback. The oldest lines are removed when a supplied limit
66is reached. Limits apply to each
67screen separately and exclude the visible screen. The byte limit measures
68uncompressed history data, **not total process memory**.
69
70[History guide →](docs/history.md): limit settings, saving/restoring history and
71optional compression during idle time.
72
73## A few rules
74
75- Serialize `Write`, `Resize`, `Snapshot`, reads and history mutations in one
76 goroutine, or protect them with your own lock.
77- Rows returned by the API are copies. Changing one does not change the screen.
78- Use `vt.DefaultStyle()` for terminal-default colors, not `vt.Style{}`.
79- Callbacks run during `screen.Write`; keep them short.
80
81[API ownership and styles →](docs/ownership.md)
82
83## Packages
84
85| Package | Use it for |
86| --- | --- |
87| `vev-vt` | Parse terminal output, read the screen and manage history. |
88| `vev-vt/core` | Work with cells, styles and writable grids. |
89| `vev-vt/ansi` | Render a screen or grid as ANSI terminal output. |
90| `vev-vt/graphics` | Read supported terminal images and their positions. |
91
92[Supported image features →](docs/graphics.md)
93
94## Development
95
96```sh
97go test ./...
98go test ./... -race
99go vet ./...
100```
101
102[Storage benchmarks and design decisions →](docs/storage-optimization.md)