1
1
mirror of https://github.com/walles/moar.git synced 2024-10-04 07:27:11 +03:00
moar/m/line.go
Johan Walles e0e9ee6610 Start telling screen cells from styled runes
One rune can cover multiple screen cells.
2024-09-15 13:56:50 +02:00

65 lines
1.7 KiB
Go

package m
import (
"regexp"
"github.com/walles/moar/m/linenumbers"
"github.com/walles/moar/m/textstyles"
"github.com/walles/moar/twin"
)
// A Line represents a line of text that can / will be paged
type Line struct {
raw string
plain *string
}
// NewLine creates a new Line from a (potentially ANSI / man page formatted) string
func NewLine(raw string) Line {
return Line{
raw: raw,
plain: nil,
}
}
// Returns a representation of the string split into styled tokens. Any regexp
// matches are highlighted. A nil regexp means no highlighting.
func (line *Line) HighlightedTokens(linePrefix string, search *regexp.Regexp, lineNumber *linenumbers.LineNumber) textstyles.StyledRunesWithTrailer {
plain := line.Plain(lineNumber)
matchRanges := getMatchRanges(&plain, search)
fromString := textstyles.StyledRunesFromString(linePrefix, line.raw, lineNumber)
returnRunes := make([]twin.StyledRune, 0, len(fromString.StyledRunes))
for _, token := range fromString.StyledRunes {
style := token.Style
if matchRanges.InRange(len(returnRunes)) {
if standoutStyle != nil {
style = *standoutStyle
} else {
style = style.WithAttr(twin.AttrReverse)
style = style.WithBackground(twin.ColorDefault)
style = style.WithForeground(twin.ColorDefault)
}
}
returnRunes = append(returnRunes, twin.StyledRune{
Rune: token.Rune,
Style: style,
})
}
return textstyles.StyledRunesWithTrailer{
StyledRunes: returnRunes,
Trailer: fromString.Trailer,
}
}
// Plain returns a plain text representation of the initial string
func (line *Line) Plain(lineNumber *linenumbers.LineNumber) string {
if line.plain == nil {
plain := textstyles.WithoutFormatting(line.raw, lineNumber)
line.plain = &plain
}
return *line.plain
}