1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
// Package main demonstrates cellbuf usage.
package main
import (
"log"
"os"
"runtime"
"github.com/charmbracelet/x/ansi"
"github.com/charmbracelet/x/cellbuf"
"github.com/charmbracelet/x/input"
"github.com/charmbracelet/x/term"
)
func main() {
w, h, err := term.GetSize(os.Stdout.Fd())
if err != nil {
log.Fatalf("getting terminal size: %v", err)
}
state, err := term.MakeRaw(os.Stdin.Fd())
if err != nil {
log.Fatalf("making raw: %v", err)
}
defer term.Restore(os.Stdin.Fd(), state) //nolint:errcheck
const altScreen = true
if !altScreen {
h = 10
}
termType := os.Getenv("TERM")
scr := cellbuf.NewScreen(os.Stdout, w, h, &cellbuf.ScreenOptions{
Term: termType,
RelativeCursor: !altScreen,
AltScreen: altScreen,
})
defer scr.Close() //nolint:errcheck
drv, err := input.NewReader(os.Stdin, termType, 0)
if err != nil {
log.Fatalf("creating input driver: %v", err)
}
modes := []ansi.Mode{
ansi.ButtonEventMouseMode,
ansi.SgrExtMouseMode,
}
os.Stdout.WriteString(ansi.SetMode(modes...)) //nolint:errcheck,gosec
defer os.Stdout.WriteString(ansi.ResetMode(modes...)) //nolint:errcheck
x, y := (w/2)-10, h/2
text := ansi.SetHyperlink("https://charm.sh") +
ansi.Style{}.Reverse().Styled(" !Hello, world! ") +
ansi.ResetHyperlink()
scrw := cellbuf.NewScreenWriter(scr)
render := func() {
scr.Fill(cellbuf.NewCell('你'))
scrw.PrintCropAt(x, y, text, "")
scr.Render()
scr.Flush() //nolint:errcheck,gosec
}
resize := func(nw, nh int) {
if !altScreen {
nh = h
w = nw
}
scr.Resize(nw, nh)
render()
}
if runtime.GOOS != "windows" {
// Listen for resize events
go listenForResize(func() {
nw, nh, _ := term.GetSize(os.Stdout.Fd())
resize(nw, nh)
})
}
// First render
render()
for {
evs, err := drv.ReadEvents()
if err != nil {
log.Fatalf("reading events: %v", err)
}
for _, ev := range evs {
switch ev := ev.(type) {
case input.WindowSizeEvent:
resize(ev.Width, ev.Height)
case input.MouseClickEvent:
x, y = ev.X, ev.Y
case input.KeyPressEvent:
switch ev.String() {
case "ctrl+c", "q":
return
case "left", "h":
x--
case "down", "j":
y++
case "up", "k":
y--
case "right", "l":
x++
}
}
}
render()
}
}
func init() {
f, err := os.OpenFile("cellbuf.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666) //nolint:gosec
if err != nil {
log.Fatal(err)
}
log.SetOutput(f)
}
|