diff --git a/oviewer/document.go b/oviewer/document.go index a67b83c5..20cc2c6a 100644 --- a/oviewer/document.go +++ b/oviewer/document.go @@ -209,6 +209,8 @@ type LineC struct { str string // for converting the width of str and lc. pos widthPos + // columnRanges is the range of columnRanges. + columnRanges []columnRange // valid is true if the line is valid. valid bool // The number of the section in the screen. @@ -219,6 +221,12 @@ type LineC struct { eolStyle tcell.Style } +// columnRange represents the start and end positions of a columnRange. +type columnRange struct { + start int + end int +} + // NewDocument creates and initializes a new [Document] with default settings. // It returns a pointer to the Document and an error if the cache initialization fails. func NewDocument() (*Document, error) { diff --git a/oviewer/prepare_draw.go b/oviewer/prepare_draw.go index 5a145b87..32b62096 100644 --- a/oviewer/prepare_draw.go +++ b/oviewer/prepare_draw.go @@ -336,6 +336,9 @@ func (root *Root) setLines(lines map[int]LineC, startLN int, endLN int) map[int] for lN := startLN; lN < endLN; lN++ { line := m.getLineC(lN) if line.valid { + if root.Doc.ColumnMode { + line = root.columnRanges(line) + } RangeStyle(line.lc, 0, len(line.lc), root.StyleBody) root.styleContent(line) } @@ -422,11 +425,7 @@ func (*Root) plainStyle(lc contents) { // columnHighlight applies the style of the column highlight. func (root *Root) columnHighlight(line LineC) { - if root.Doc.ColumnWidth { - root.columnWidthHighlight(line) - return - } - root.columnDelimiterHighlight(line) + root.applyColumnStyles(line) } // multiColorHighlight applies styles to multiple words (regular expressions) individually. @@ -454,48 +453,47 @@ func (root *Root) searchHighlight(line LineC) { } } -// columnHighlight applies the style of the column highlight. -func (root *Root) columnDelimiterHighlight(line LineC) { +// columnRanges sets the column ranges. +func (root *Root) columnRanges(line LineC) LineC { + if root.Doc.ColumnWidth { + line.columnRanges = root.columnWidthRanges(line) + } else { + line.columnRanges = root.columnDelimiterRange(line) + } + return line +} + +// columnDelimiterRange returns the ranges of the columns. +func (root *Root) columnDelimiterRange(line LineC) []columnRange { m := root.Doc indexes := allIndex(line.str, m.ColumnDelimiter, m.ColumnDelimiterReg) if len(indexes) == 0 { - return + return nil } - numC := len(root.StyleColumnRainbow) + var columnRanges []columnRange start := line.pos.x(0) for columnNum := 0; columnNum < len(indexes); columnNum++ { end := line.pos.x(indexes[columnNum][0]) delmEnd := line.pos.x(indexes[columnNum][1]) - if m.ColumnRainbow { - RangeStyle(line.lc, start, end, root.StyleColumnRainbow[columnNum%numC]) - } - if columnNum == m.columnCursor { - RangeStyle(line.lc, start, end, root.StyleColumnHighlight) - } + columnRanges = append(columnRanges, columnRange{start: start, end: end}) start = delmEnd } // The last column. - columnNum := len(indexes) end := line.pos.x(len(line.str)) - if m.ColumnRainbow { - RangeStyle(line.lc, start, end, root.StyleColumnRainbow[columnNum%numC]) - } - if columnNum == m.columnCursor { - RangeStyle(line.lc, start, end, root.StyleColumnHighlight) - } + columnRanges = append(columnRanges, columnRange{start: start, end: end}) + return columnRanges } -// columnWidthHighlight applies the style of the column width highlight. -func (root *Root) columnWidthHighlight(line LineC) { +// columnWidthRanges returns the ranges of the columns. +func (root *Root) columnWidthRanges(line LineC) []columnRange { m := root.Doc indexes := m.columnWidths if len(indexes) == 0 { - return + return nil } - numC := len(root.StyleColumnRainbow) - + var columnRanges []columnRange start, end := 0, 0 for c := 0; c < len(indexes)+1; c++ { if m.Converter == convAlign { @@ -503,14 +501,24 @@ func (root *Root) columnWidthHighlight(line LineC) { } else { end = findColumnEnd(line.lc, indexes, c, start) } + columnRanges = append(columnRanges, columnRange{start: start, end: end}) + start = end + 1 + } + return columnRanges +} + +// applyColumnStyles applies the styles to the columns based on the calculated ranges. +func (root *Root) applyColumnStyles(line LineC) { + m := root.Doc + numC := len(root.StyleColumnRainbow) + for c, colRange := range line.columnRanges { if m.ColumnRainbow { - RangeStyle(line.lc, start, end, root.StyleColumnRainbow[c%numC]) + RangeStyle(line.lc, colRange.start, colRange.end, root.StyleColumnRainbow[c%numC]) } if c == m.columnCursor { - RangeStyle(line.lc, start, end, root.StyleColumnHighlight) + RangeStyle(line.lc, colRange.start, colRange.end, root.StyleColumnHighlight) } - start = end + 1 } } diff --git a/oviewer/prepare_draw_test.go b/oviewer/prepare_draw_test.go index ec19a1cb..c479b340 100644 --- a/oviewer/prepare_draw_test.go +++ b/oviewer/prepare_draw_test.go @@ -742,7 +742,8 @@ func TestRoot_columnDelimiterHighlight(t *testing.T) { m.columnCursor = tt.fields.columnCursor root.StyleColumnHighlight = OVStyle{Bold: true} line := root.Doc.getLineC(tt.args.lineNum) - root.columnDelimiterHighlight(line) + line.columnRanges = root.columnDelimiterRange(line) + root.columnHighlight(line) if line.str != tt.want.str { t.Errorf("\nline: %v\nwant: %v\n", line.str, tt.want.str) } @@ -815,7 +816,8 @@ func TestRoot_columnWidthHighlight(t *testing.T) { t.Log(m.columnWidths) m.columnCursor = tt.fields.columnCursor line := root.Doc.getLineC(tt.args.lineNum) - root.columnWidthHighlight(line) + line.columnRanges = root.columnWidthRanges(line) + root.columnHighlight(line) if line.str != tt.want.str { t.Errorf("\nline: %v\nwant: %v\n", line.str, tt.want.str) }