File: main.go

package info (click to toggle)
golang-github-charmbracelet-ultraviolet 0.0~git20251017.d4ace4d-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 872 kB
  • sloc: makefile: 3
file content (100 lines) | stat: -rw-r--r-- 2,328 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
package main

import (
	"context"
	"log"
	"os"

	uv "github.com/charmbracelet/ultraviolet"
	"github.com/charmbracelet/ultraviolet/screen"
	"github.com/charmbracelet/x/ansi"
)

func main() {
	// Create a new terminal screen
	t := uv.NewTerminal(os.Stdin, os.Stdout, os.Environ())
	// Or simply use...
	// t := uv.DefaultTerminal()

	// Create a new program
	// Start the program
	if err := t.Start(); err != nil {
		log.Fatalf("failed to start program: %v", err)
	}

	fixed := uv.Rect(10, 10, 40, 20)
	display := func() {
		// Display the frame with the styled string
		// We want the component to occupy the given area which is the
		// entire screen because we're using the alternate screen buffer.
		screen.FillArea(t, &uv.Cell{
			Content: " ",
			Style:   uv.Style{Fg: ansi.Red},
		}, fixed)
		// We will use the StyledString component to simplify displaying
		// text on the screen.
		ss := uv.NewStyledString("Hello, World!")
		carea := fixed
		carea.Min.X = (carea.Max.X / 2) - 6
		carea.Min.Y = (carea.Max.Y / 2) - 1
		carea.Max.X = carea.Min.X + 12
		carea.Max.Y = carea.Min.Y + 1
		ss.Draw(t, carea)
		if err := t.Display(); err != nil {
			log.Fatal(err)
		}
	}

	// We want to be able to stop the terminal input loop
	// whenever we call cancel().
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// This will block until we close the events
	// channel or cancel the context.
LOOP:
	for {
		select {
		case <-ctx.Done():
			break LOOP
		case ev := <-t.Events():
			switch ev := ev.(type) {
			case uv.WindowSizeEvent:
				t.Resize(ev.Width, ev.Height)
				t.Erase()
			case uv.KeyPressEvent:
				if ev.MatchString("q", "ctrl+c") {
					cancel() // This will stop the loop
				} else if ev.MatchString("ctrl+z") {
					t.Erase()
					if err := t.Display(); err != nil {
						log.Fatal(err)
					}
					if t.Pause() != nil {
						log.Fatal("failed to shutdown terminal")
					}

					uv.Suspend()

					if err := t.Resume(); err != nil {
						log.Fatal("failed to resume terminal")
					}
				}
			}
		}

		display()
	}

	if err := t.Shutdown(context.Background()); err != nil {
		log.Fatal(err)
	}
}

func init() {
	f, err := os.OpenFile("uv_debug.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
	if err != nil {
		log.Fatalf("failed to open log file: %v", err)
	}
	log.SetOutput(f)
}