main
Raw Download raw file
 1package lipgloss
 2
 3import (
 4	"strings"
 5
 6	"github.com/charmbracelet/x/ansi"
 7)
 8
 9// StyleRanges allows to, given a string, style ranges of it differently.
10// The function will take into account existing styles.
11// Ranges should not overlap.
12func StyleRanges(s string, ranges ...Range) string {
13	if len(ranges) == 0 {
14		return s
15	}
16
17	var buf strings.Builder
18	lastIdx := 0
19	stripped := ansi.Strip(s)
20
21	// Use Truncate and TruncateLeft to style match.MatchedIndexes without
22	// losing the original option style:
23	for _, rng := range ranges {
24		// Add the text before this match
25		if rng.Start > lastIdx {
26			buf.WriteString(ansi.Cut(s, lastIdx, rng.Start))
27		}
28		// Add the matched range with its highlight
29		buf.WriteString(rng.Style.Render(ansi.Cut(stripped, rng.Start, rng.End)))
30		lastIdx = rng.End
31	}
32
33	// Add any remaining text after the last match
34	buf.WriteString(ansi.TruncateLeft(s, lastIdx, ""))
35
36	return buf.String()
37}
38
39// NewRange returns a range that can be used with [StyleRanges].
40func NewRange(start, end int, style Style) Range {
41	return Range{start, end, style}
42}
43
44// Range to be used with [StyleRanges].
45type Range struct {
46	Start, End int
47	Style      Style
48}