2024-01-05 08:31:33 +03:00
|
|
|
package m
|
|
|
|
|
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
|
2024-01-06 18:34:20 +03:00
|
|
|
"github.com/walles/moar/m/linenumbers"
|
2024-01-05 11:12:17 +03:00
|
|
|
"github.com/walles/moar/m/textstyles"
|
2024-01-05 08:31:33 +03:00
|
|
|
"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.
|
2024-01-06 18:40:13 +03:00
|
|
|
func (line *Line) HighlightedTokens(linePrefix string, search *regexp.Regexp, lineNumber *linenumbers.LineNumber) textstyles.CellsWithTrailer {
|
|
|
|
plain := line.Plain(lineNumber)
|
2024-01-05 08:31:33 +03:00
|
|
|
matchRanges := getMatchRanges(&plain, search)
|
|
|
|
|
2024-01-06 18:40:13 +03:00
|
|
|
fromString := textstyles.CellsFromString(linePrefix+line.raw, lineNumber)
|
2024-01-05 08:31:33 +03:00
|
|
|
returnCells := make([]twin.Cell, 0, len(fromString.Cells))
|
|
|
|
for _, token := range fromString.Cells {
|
|
|
|
style := token.Style
|
|
|
|
if matchRanges.InRange(len(returnCells)) {
|
|
|
|
if standoutStyle != nil {
|
|
|
|
style = *standoutStyle
|
|
|
|
} else {
|
|
|
|
style = style.WithAttr(twin.AttrReverse)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
returnCells = append(returnCells, twin.Cell{
|
|
|
|
Rune: token.Rune,
|
|
|
|
Style: style,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-01-05 08:33:43 +03:00
|
|
|
return textstyles.CellsWithTrailer{
|
2024-01-05 08:31:33 +03:00
|
|
|
Cells: returnCells,
|
|
|
|
Trailer: fromString.Trailer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Plain returns a plain text representation of the initial string
|
2024-01-06 18:34:20 +03:00
|
|
|
func (line *Line) Plain(lineNumber *linenumbers.LineNumber) string {
|
2024-01-05 08:31:33 +03:00
|
|
|
if line.plain == nil {
|
2024-01-06 18:34:20 +03:00
|
|
|
plain := textstyles.WithoutFormatting(line.raw, lineNumber)
|
2024-01-05 08:31:33 +03:00
|
|
|
line.plain = &plain
|
|
|
|
}
|
|
|
|
return *line.plain
|
|
|
|
}
|