mirror of
https://github.com/walles/moar.git
synced 2024-09-11 12:15:43 +03:00
parent
41e2efc05b
commit
251513ef66
@ -41,11 +41,11 @@ func NewLine(raw string) Line {
|
||||
|
||||
// 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(search *regexp.Regexp) cellsWithTrailer {
|
||||
func (line *Line) HighlightedTokens(linePrefix string, search *regexp.Regexp) cellsWithTrailer {
|
||||
plain := line.Plain()
|
||||
matchRanges := getMatchRanges(&plain, search)
|
||||
|
||||
fromString := cellsFromString(line.raw)
|
||||
fromString := cellsFromString(linePrefix + line.raw)
|
||||
returnCells := make([]twin.Cell, 0, len(fromString.Cells))
|
||||
for _, token := range fromString.Cells {
|
||||
style := token.Style
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
func tokenize(input string) []twin.Cell {
|
||||
line := NewLine(input)
|
||||
return line.HighlightedTokens(nil).Cells
|
||||
return line.HighlightedTokens("", nil).Cells
|
||||
}
|
||||
|
||||
func rowsToString(cellLines [][]twin.Cell) string {
|
||||
|
39
m/pager.go
39
m/pager.go
@ -4,8 +4,10 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/chroma/v2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/walles/moar/twin"
|
||||
)
|
||||
@ -93,6 +95,16 @@ type Pager struct {
|
||||
// If true, pager will clear the screen on return. If false, pager will
|
||||
// clear the last line, and show the cursor.
|
||||
DeInit bool
|
||||
|
||||
// Render the UI using this style
|
||||
ChromaStyle *chroma.Style
|
||||
|
||||
// Render the UI using this formatter
|
||||
ChromaFormatter *chroma.Formatter
|
||||
|
||||
// Optional ANSI to prefix each text line with. Initialised using
|
||||
// ChromaStyle and ChromaFormatter.
|
||||
linePrefix string
|
||||
}
|
||||
|
||||
type _PreHelpState struct {
|
||||
@ -428,6 +440,32 @@ func (p *Pager) onRune(char rune) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pager) initStyle() {
|
||||
if p.ChromaStyle == nil && p.ChromaFormatter == nil {
|
||||
return
|
||||
}
|
||||
if p.ChromaStyle == nil || p.ChromaFormatter == nil {
|
||||
panic("Both ChromaStyle and ChromaFormatter should be set or neither")
|
||||
}
|
||||
|
||||
stringBuilder := strings.Builder{}
|
||||
err := (*p.ChromaFormatter).Format(&stringBuilder, p.ChromaStyle, chroma.Literator(chroma.Token{
|
||||
Type: chroma.Other,
|
||||
Value: "XXX",
|
||||
}))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
string := stringBuilder.String()
|
||||
cutoff := strings.Index(string, "XXX")
|
||||
if cutoff < 0 {
|
||||
panic("XXX not found in " + string)
|
||||
}
|
||||
|
||||
p.linePrefix = string[:cutoff]
|
||||
}
|
||||
|
||||
// StartPaging brings up the pager on screen
|
||||
func (p *Pager) StartPaging(screen twin.Screen) {
|
||||
log.Trace("Pager starting")
|
||||
@ -443,6 +481,7 @@ func (p *Pager) StartPaging(screen twin.Screen) {
|
||||
ConsumeLessTermcapEnvs()
|
||||
|
||||
p.screen = screen
|
||||
p.initStyle()
|
||||
|
||||
go func() {
|
||||
for range p.reader.moreLinesAdded {
|
||||
|
@ -583,6 +583,15 @@ func TestClearToEndOfLine_ClearFromStartScrolledRight(t *testing.T) {
|
||||
assert.DeepEqual(t, actual, expected, cmp.AllowUnexported(twin.Style{}))
|
||||
}
|
||||
|
||||
func TestInitStyle(t *testing.T) {
|
||||
testMe := Pager{
|
||||
ChromaStyle: styles.Registry["gruvbox"],
|
||||
ChromaFormatter: &formatters.TTY16m,
|
||||
}
|
||||
testMe.initStyle()
|
||||
assert.Equal(t, testMe.linePrefix, "\x1b[38;2;235;219;178m")
|
||||
}
|
||||
|
||||
func benchmarkSearch(b *testing.B, highlighted bool) {
|
||||
// Pick a go file so we get something with highlighting
|
||||
_, sourceFilename, _, ok := runtime.Caller(0)
|
||||
|
@ -204,7 +204,7 @@ func (p *Pager) renderLines() ([]renderedLine, string, overflowState) {
|
||||
// lineNumber and numberPrefixLength are required for knowing how much to
|
||||
// indent, and to (optionally) render the line number.
|
||||
func (p *Pager) renderLine(line *Line, lineNumber int) ([]renderedLine, overflowState) {
|
||||
highlighted := line.HighlightedTokens(p.searchPattern)
|
||||
highlighted := line.HighlightedTokens(p.linePrefix, p.searchPattern)
|
||||
var wrapped [][]twin.Cell
|
||||
overflow := didFit
|
||||
if p.WrapLongLines {
|
||||
|
6
moar.go
6
moar.go
@ -199,8 +199,8 @@ func parseUnprintableStyle(styleOption string) (m.UnprintableStyle, error) {
|
||||
|
||||
func parseScrollHint(scrollHint string) (twin.Cell, error) {
|
||||
scrollHint = strings.ReplaceAll(scrollHint, "ESC", "\x1b")
|
||||
hintParser := m.NewLine(scrollHint)
|
||||
parsedTokens := hintParser.HighlightedTokens(nil).Cells
|
||||
hintAsLine := m.NewLine(scrollHint)
|
||||
parsedTokens := hintAsLine.HighlightedTokens("", nil).Cells
|
||||
if len(parsedTokens) == 1 {
|
||||
return parsedTokens[0], nil
|
||||
}
|
||||
@ -492,6 +492,8 @@ func main() {
|
||||
pager.ScrollLeftHint = *scrollLeftHint
|
||||
pager.ScrollRightHint = *scrollRightHint
|
||||
pager.SideScrollAmount = int(*shift)
|
||||
pager.ChromaStyle = style
|
||||
pager.ChromaFormatter = formatter
|
||||
|
||||
pager.TargetLineNumberOneBased = targetLineNumberOneBased
|
||||
if *follow && pager.TargetLineNumberOneBased == 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user