main
Raw Download raw file
 1package lipgloss
 2
 3import (
 4	"strings"
 5
 6	"github.com/charmbracelet/x/ansi"
 7	"github.com/muesli/termenv"
 8)
 9
10// whitespace is a whitespace renderer.
11type whitespace struct {
12	re    *Renderer
13	style termenv.Style
14	chars string
15}
16
17// newWhitespace creates a new whitespace renderer. The order of the options
18// matters, if you're using WithWhitespaceRenderer, make sure it comes first as
19// other options might depend on it.
20func newWhitespace(r *Renderer, opts ...WhitespaceOption) *whitespace {
21	w := &whitespace{
22		re:    r,
23		style: r.ColorProfile().String(),
24	}
25	for _, opt := range opts {
26		opt(w)
27	}
28	return w
29}
30
31// Render whitespaces.
32func (w whitespace) render(width int) string {
33	if w.chars == "" {
34		w.chars = " "
35	}
36
37	r := []rune(w.chars)
38	j := 0
39	b := strings.Builder{}
40
41	// Cycle through runes and print them into the whitespace.
42	for i := 0; i < width; {
43		b.WriteRune(r[j])
44		j++
45		if j >= len(r) {
46			j = 0
47		}
48		i += ansi.StringWidth(string(r[j]))
49	}
50
51	// Fill any extra gaps white spaces. This might be necessary if any runes
52	// are more than one cell wide, which could leave a one-rune gap.
53	short := width - ansi.StringWidth(b.String())
54	if short > 0 {
55		b.WriteString(strings.Repeat(" ", short))
56	}
57
58	return w.style.Styled(b.String())
59}
60
61// WhitespaceOption sets a styling rule for rendering whitespace.
62type WhitespaceOption func(*whitespace)
63
64// WithWhitespaceForeground sets the color of the characters in the whitespace.
65func WithWhitespaceForeground(c TerminalColor) WhitespaceOption {
66	return func(w *whitespace) {
67		w.style = w.style.Foreground(c.color(w.re))
68	}
69}
70
71// WithWhitespaceBackground sets the background color of the whitespace.
72func WithWhitespaceBackground(c TerminalColor) WhitespaceOption {
73	return func(w *whitespace) {
74		w.style = w.style.Background(c.color(w.re))
75	}
76}
77
78// WithWhitespaceChars sets the characters to be rendered in the whitespace.
79func WithWhitespaceChars(s string) WhitespaceOption {
80	return func(w *whitespace) {
81		w.chars = s
82	}
83}