File: main.go

package info (click to toggle)
golang-github-charmbracelet-x 0.0~git20251028.0cf22f8%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,940 kB
  • sloc: sh: 124; makefile: 5
file content (126 lines) | stat: -rw-r--r-- 2,481 bytes parent folder | download
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)
}