Skip to content

Commit

Permalink
feat(vt): add htop example
Browse files Browse the repository at this point in the history
  • Loading branch information
aymanbagabas committed Nov 10, 2024
1 parent 8cc6e3d commit b4e8e7a
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 25 deletions.
27 changes: 14 additions & 13 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,28 @@ module examples
go 1.18

require (
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.1.0.20241105155825-ead55032fd81
github.com/charmbracelet/lipgloss/v2 v2.0.0-20241105145349-c8e32d1b422c
github.com/charmbracelet/x/ansi v0.4.4
github.com/charmbracelet/x/cellbuf v0.0.5
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/charmbracelet/x/ansi v0.4.5
github.com/charmbracelet/x/cellbuf v0.0.6-0.20241106170917-eb0997d7d743
github.com/charmbracelet/x/input v0.2.0
github.com/charmbracelet/x/vt v0.0.0-00010101000000-000000000000
github.com/creack/pty v1.1.24
golang.org/x/image v0.22.0
)

require (
github.com/charmbracelet/colorprofile v0.1.6 // indirect
github.com/charmbracelet/x/input v0.2.0 // indirect
github.com/charmbracelet/colorprofile v0.1.7 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
)

require (
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/charmbracelet/x/term v0.2.0
github.com/charmbracelet/x/wcwidth v0.0.0-20241011142426-46044092ad91 // indirect
github.com/charmbracelet/x/windows v0.2.0 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/rivo/uniseg v0.4.7
github.com/rivo/uniseg v0.4.7 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
)

replace github.com/charmbracelet/x/ansi => ../ansi
Expand All @@ -36,6 +35,8 @@ replace github.com/charmbracelet/x/term => ../term

replace github.com/charmbracelet/x/input => ../input

replace github.com/charmbracelet/x/vt => ../vt

replace github.com/charmbracelet/x/windows => ../windows

replace github.com/charmbracelet/x/exp => ../exp
22 changes: 10 additions & 12 deletions examples/go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.1.0.20241105155825-ead55032fd81 h1:J40lkNAii38iaDD8B/Eh2+mHL2U7DzS48RqXe0ap5OQ=
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.1.0.20241105155825-ead55032fd81/go.mod h1:24niqT9RbtXhWg8zLRU/v/xTixlo1+DUsHQZ3+kez5Y=
github.com/charmbracelet/colorprofile v0.1.6 h1:nMMqCns0c0DfCwNGdagBh6SxutFqkltSxxKk5S9kt+Y=
github.com/charmbracelet/colorprofile v0.1.6/go.mod h1:3EMXDxwRDJl0c17eJ1jX99MhtlP9OxE/9Qw0C5lvyUg=
github.com/charmbracelet/lipgloss/v2 v2.0.0-20241105145349-c8e32d1b422c h1:rzZvGgEkGHwO34rdQuxR6yR2O/EGWw6PGV4g/w3FyPU=
github.com/charmbracelet/lipgloss/v2 v2.0.0-20241105145349-c8e32d1b422c/go.mod h1:M8oXIuQtauwIZFuFREK6cYi+2fu0YNiBFnmCP7N8c2c=
github.com/charmbracelet/colorprofile v0.1.7 h1:q7PtMQrRBBnLNE2EbtbNUtouu979EivKcDGGaimhyO8=
github.com/charmbracelet/colorprofile v0.1.7/go.mod h1:d3UYToTrNmsD2p9/lbiya16H1WahndM0miDlJWXWf4U=
github.com/charmbracelet/x/wcwidth v0.0.0-20241011142426-46044092ad91 h1:D5OO0lVavz7A+Swdhp62F9gbkibxmz9B2hZ/jVdMPf0=
github.com/charmbracelet/x/wcwidth v0.0.0-20241011142426-46044092ad91/go.mod h1:Ey8PFmYwH+/td9bpiEx07Fdx9ZVkxfIjWXxBluxF4Nw=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
Expand All @@ -17,10 +15,10 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
124 changes: 124 additions & 0 deletions examples/htop/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"io"
"log"
"os"
"os/exec"
"sync/atomic"
"time"

"github.com/charmbracelet/x/termios"
"github.com/charmbracelet/x/vt"
"github.com/creack/pty"
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
"golang.org/x/sys/unix"
)

const (
fontWidth = 7
fontHeight = 13
)

func drawChar(img *image.RGBA, x, y int, fg color.Color, text string) {
point := fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
if fg == nil {
fg = color.White
}
d := &font.Drawer{
Dst: img,
Src: image.NewUniform(fg),
Face: basicfont.Face7x13,
Dot: point,
}
d.DrawString(text)
}

var counter int32 = 1

func putImage(vt *vt.Terminal) {
rows, cols := vt.Height(), vt.Width()
img := image.NewRGBA(image.Rect(0, 0, cols*fontWidth, rows*fontHeight))
draw.Draw(img, img.Bounds(), &image.Uniform{color.Black}, image.ZP, draw.Src)

for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
cell, ok := vt.At(col, row)
if !ok {
log.Printf("failed to get at %d %d", row, col)
}
txt := cell.Content
if len(txt) > 0 && txt[0] != 0 {
fg, bg := cell.Style.Fg, cell.Style.Bg
if bg == nil {
bg = color.Black
}

// Draw background
x0, y0 := (col+1)*fontWidth, ((row+1)*fontHeight)-11
x1, y1 := x0+fontWidth, y0+fontHeight
draw.Draw(img, image.Rect(x0, y0, x1, y1), &image.Uniform{bg}, image.ZP, draw.Over)

drawChar(img, (col+1)*fontWidth, (row+1)*fontHeight, fg, txt)
}
}
}

f, err := os.Create(fmt.Sprintf("output%d.png", counter))
if err != nil {
log.Fatal(err)
}

defer f.Close()
err = png.Encode(f, img)
if err != nil {
log.Fatal(err)
}

atomic.AddInt32(&counter, 1)
}

const (
width = 165
height = 25
)

func main() {
vt := vt.NewTerminal(width, height)
cmd := exec.Command("htop")

go func() {
for {
time.Sleep(1 * time.Second)
putImage(vt)
}
}()

go func() {
time.Sleep(5 * time.Second)
cmd.Process.Kill()
}()

ptm, err := pty.Start(cmd)
if err != nil {
log.Fatal(err)
}

if err := termios.SetWinsize(int(ptm.Fd()), &unix.Winsize{Row: uint16(height), Col: uint16(width)}); err != nil {
log.Fatal(err)
}

go io.Copy(ptm, vt)
go io.Copy(vt, ptm)

if err := cmd.Wait(); err != nil {
log.Fatal(err)
}
}

0 comments on commit b4e8e7a

Please sign in to comment.