main
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}