diff --git a/cmd/micro/buffer.go b/cmd/micro/buffer.go index 75d9ba63..9e1cbee0 100644 --- a/cmd/micro/buffer.go +++ b/cmd/micro/buffer.go @@ -408,6 +408,10 @@ func (b *Buffer) Line(n int) string { return string(b.lines[n].data) } +func (b *Buffer) LinesNum() int { + return len(b.lines) +} + // Lines returns an array of strings containing the lines from start to end func (b *Buffer) Lines(start, end int) []string { lines := b.lines[start:end] diff --git a/cmd/micro/cellview.go b/cmd/micro/cellview.go index 4f4853d9..0a64ed9e 100644 --- a/cmd/micro/cellview.go +++ b/cmd/micro/cellview.go @@ -186,4 +186,8 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) { viewLine++ lineN++ } + + for i := top; i < top+height; i++ { + buf.SetMatch(i, nil) + } } diff --git a/cmd/micro/highlight/ftdetect.go b/cmd/micro/highlight/ftdetect.go index 96122554..2d9e296c 100644 --- a/cmd/micro/highlight/ftdetect.go +++ b/cmd/micro/highlight/ftdetect.go @@ -2,11 +2,11 @@ package highlight func DetectFiletype(defs []*Def, filename string, firstLine []byte) *Def { for _, d := range defs { - if isMatch, _ := d.ftdetect[0].MatchString(filename); isMatch { + if d.ftdetect[0].MatchString(filename) { return d } if len(d.ftdetect) > 1 { - if isMatch, _ := d.ftdetect[1].MatchString(string(firstLine)); isMatch { + if d.ftdetect[1].MatchString(string(firstLine)) { return d } } diff --git a/cmd/micro/highlight/highlighter.go b/cmd/micro/highlight/highlighter.go index ed312f0f..fcc32626 100644 --- a/cmd/micro/highlight/highlighter.go +++ b/cmd/micro/highlight/highlighter.go @@ -25,7 +25,8 @@ type State *Region // LineStates is an interface for a buffer-like object which can also store the states and matches for every line type LineStates interface { - LineData() [][]byte + Line(n int) string + LinesNum() int State(lineN int) State SetState(lineN int, s State) SetMatch(lineN int, m LineMatch) @@ -82,34 +83,35 @@ func findAllIndex(regex *regexp.Regexp, str []byte, canMatchStart, canMatchEnd b return regex.FindAllIndex(str, -1) } -func (h *Highlighter) highlightRegion(start int, canMatchEnd bool, lineNum int, line []byte, region *Region) LineMatch { - fullHighlights := make([]uint8, len([]rune(string(line)))) - for i := 0; i < len(fullHighlights); i++ { - fullHighlights[i] = region.group - } - - highlights := make(LineMatch) +func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchEnd bool, lineNum int, line []byte, region *Region, statesOnly bool) LineMatch { + // highlights := make(LineMatch) if start == 0 { - highlights[0] = region.group + if !statesOnly { + highlights[0] = region.group + } } loc := findIndex(region.end, line, start == 0, canMatchEnd) if loc != nil { highlights[start+loc[1]-1] = region.group if region.parent == nil { - highlights[start+loc[1]] = 0 - return combineLineMatch(highlights, - combineLineMatch(h.highlightRegion(start, false, lineNum, line[:loc[0]], region), - h.highlightEmptyRegion(start+loc[1], canMatchEnd, lineNum, line[loc[1]:]))) + if !statesOnly { + highlights[start+loc[1]] = 0 + } + h.highlightRegion(highlights, start, false, lineNum, line[:loc[0]], region, statesOnly) + h.highlightEmptyRegion(highlights, start+loc[1], canMatchEnd, lineNum, line[loc[1]:], statesOnly) + return highlights } - highlights[start+loc[1]] = region.parent.group - return combineLineMatch(highlights, - combineLineMatch(h.highlightRegion(start, false, lineNum, line[:loc[0]], region), - h.highlightRegion(start+loc[1], canMatchEnd, lineNum, line[loc[1]:], region.parent))) + if !statesOnly { + highlights[start+loc[1]] = region.parent.group + } + h.highlightRegion(highlights, start, false, lineNum, line[:loc[0]], region, statesOnly) + h.highlightRegion(highlights, start+loc[1], canMatchEnd, lineNum, line[loc[1]:], region.parent, statesOnly) + return highlights } - if len(line) == 0 { + if len(line) == 0 || statesOnly { if canMatchEnd { h.lastRegion = region } @@ -130,9 +132,14 @@ func (h *Highlighter) highlightRegion(start int, canMatchEnd bool, lineNum int, } if firstLoc[0] != len(line) { highlights[start+firstLoc[0]] = firstRegion.group - return combineLineMatch(highlights, - combineLineMatch(h.highlightRegion(start, false, lineNum, line[:firstLoc[0]], region), - h.highlightRegion(start+firstLoc[1], canMatchEnd, lineNum, line[firstLoc[1]:], firstRegion))) + h.highlightRegion(highlights, start, false, lineNum, line[:firstLoc[0]], region, statesOnly) + h.highlightRegion(highlights, start+firstLoc[1], canMatchEnd, lineNum, line[firstLoc[1]:], firstRegion, statesOnly) + return highlights + } + + fullHighlights := make([]uint8, len([]rune(string(line)))) + for i := 0; i < len(fullHighlights); i++ { + fullHighlights[i] = region.group } for _, p := range region.rules.patterns { @@ -158,9 +165,7 @@ func (h *Highlighter) highlightRegion(start int, canMatchEnd bool, lineNum int, return highlights } -func (h *Highlighter) highlightEmptyRegion(start int, canMatchEnd bool, lineNum int, line []byte) LineMatch { - fullHighlights := make([]uint8, len(line)) - highlights := make(LineMatch) +func (h *Highlighter) highlightEmptyRegion(highlights LineMatch, start int, canMatchEnd bool, lineNum int, line []byte, statesOnly bool) LineMatch { if len(line) == 0 { if canMatchEnd { h.lastRegion = nil @@ -180,12 +185,23 @@ func (h *Highlighter) highlightEmptyRegion(start int, canMatchEnd bool, lineNum } } if firstLoc[0] != len(line) { - highlights[start+firstLoc[0]] = firstRegion.group - return combineLineMatch(highlights, - combineLineMatch(h.highlightEmptyRegion(start, false, lineNum, line[:firstLoc[0]]), - h.highlightRegion(start+firstLoc[1], canMatchEnd, lineNum, line[firstLoc[1]:], firstRegion))) + if !statesOnly { + highlights[start+firstLoc[0]] = firstRegion.group + } + h.highlightEmptyRegion(highlights, start, false, lineNum, line[:firstLoc[0]], statesOnly) + h.highlightRegion(highlights, start+firstLoc[1], canMatchEnd, lineNum, line[firstLoc[1]:], firstRegion, statesOnly) + return highlights } + if statesOnly { + if canMatchEnd { + h.lastRegion = nil + } + + return highlights + } + + fullHighlights := make([]uint8, len(line)) for _, p := range h.def.rules.patterns { matches := findAllIndex(p.regex, line, start == 0, canMatchEnd) for _, m := range matches { @@ -219,11 +235,12 @@ func (h *Highlighter) HighlightString(input string) []LineMatch { for i := 0; i < len(lines); i++ { line := []byte(lines[i]) + highlights := make(LineMatch) if i == 0 || h.lastRegion == nil { - lineMatches = append(lineMatches, h.highlightEmptyRegion(0, true, i, line)) + lineMatches = append(lineMatches, h.highlightEmptyRegion(highlights, 0, true, i, line, false)) } else { - lineMatches = append(lineMatches, h.highlightRegion(0, true, i, line, h.lastRegion)) + lineMatches = append(lineMatches, h.highlightRegion(highlights, 0, true, i, line, h.lastRegion, false)) } } @@ -232,15 +249,14 @@ func (h *Highlighter) HighlightString(input string) []LineMatch { // HighlightStates correctly sets all states for the buffer func (h *Highlighter) HighlightStates(input LineStates) { - lines := input.LineData() - - for i := 0; i < len(lines); i++ { - line := []byte(lines[i]) + for i := 0; i < input.LinesNum(); i++ { + line := []byte(input.Line(i)) + // highlights := make(LineMatch) if i == 0 || h.lastRegion == nil { - h.highlightEmptyRegion(0, true, i, line) + h.highlightEmptyRegion(nil, 0, true, i, line, true) } else { - h.highlightRegion(0, true, i, line, h.lastRegion) + h.highlightRegion(nil, 0, true, i, line, h.lastRegion, true) } curState := h.lastRegion @@ -253,43 +269,39 @@ func (h *Highlighter) HighlightStates(input LineStates) { // It sets all other matches in the buffer to nil to conserve memory // This assumes that all the states are set correctly func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int) { - lines := input.LineData() + for i := startline; i < endline; i++ { + line := []byte(input.Line(i)) + highlights := make(LineMatch) - for i := 0; i < len(lines); i++ { - if i >= startline && i < endline { - line := []byte(lines[i]) - - var match LineMatch - if i == 0 || input.State(i-1) == nil { - match = h.highlightEmptyRegion(0, true, i, line) - } else { - match = h.highlightRegion(0, true, i, line, input.State(i-1)) - } - - input.SetMatch(i, match) + var match LineMatch + if i == 0 || input.State(i-1) == nil { + match = h.highlightEmptyRegion(highlights, 0, true, i, line, false) } else { - input.SetMatch(i, nil) + match = h.highlightRegion(highlights, 0, true, i, line, input.State(i-1), false) } + + input.SetMatch(i, match) } } // ReHighlightStates will scan down from `startline` and set the appropriate end of line state // for each line until it comes across the same state in two consecutive lines func (h *Highlighter) ReHighlightStates(input LineStates, startline int) { - lines := input.LineData() + // lines := input.LineData() h.lastRegion = nil if startline > 0 { h.lastRegion = input.State(startline - 1) } - for i := startline; i < len(lines); i++ { - line := []byte(lines[i]) + for i := startline; i < input.LinesNum(); i++ { + line := []byte(input.Line(i)) + // highlights := make(LineMatch) // var match LineMatch if i == 0 || h.lastRegion == nil { - h.highlightEmptyRegion(0, true, i, line) + h.highlightEmptyRegion(nil, 0, true, i, line, true) } else { - h.highlightRegion(0, true, i, line, h.lastRegion) + h.highlightRegion(nil, 0, true, i, line, h.lastRegion, true) } curState := h.lastRegion lastState := input.State(i) @@ -304,9 +316,8 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) { // ReHighlightLine will rehighlight the state and match for a single line func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) { - lines := input.LineData() - - line := []byte(lines[lineN]) + line := []byte(input.Line(lineN)) + highlights := make(LineMatch) h.lastRegion = nil if lineN > 0 { @@ -315,9 +326,9 @@ func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) { var match LineMatch if lineN == 0 || h.lastRegion == nil { - match = h.highlightEmptyRegion(0, true, lineN, line) + match = h.highlightEmptyRegion(highlights, 0, true, lineN, line, false) } else { - match = h.highlightRegion(0, true, lineN, line, h.lastRegion) + match = h.highlightRegion(highlights, 0, true, lineN, line, h.lastRegion, false) } curState := h.lastRegion diff --git a/cmd/micro/highlight/parser.go b/cmd/micro/highlight/parser.go index 848f701b..bf577526 100644 --- a/cmd/micro/highlight/parser.go +++ b/cmd/micro/highlight/parser.go @@ -27,7 +27,7 @@ func GetGroup(n uint8) string { // Then it has the rules which define how to highlight the file type Def struct { FileType string - ftdetect []*regexp2.Regexp + ftdetect []*regexp.Regexp rules *Rules } @@ -88,7 +88,7 @@ func ParseDef(input []byte) (s *Def, err error) { } else if k == "detect" { ftdetect := v.(map[interface{}]interface{}) if len(ftdetect) >= 1 { - syntax, err := regexp2.Compile(ftdetect["filename"].(string), 0) + syntax, err := regexp.Compile(ftdetect["filename"].(string)) if err != nil { return nil, err } @@ -96,7 +96,7 @@ func ParseDef(input []byte) (s *Def, err error) { s.ftdetect = append(s.ftdetect, syntax) } if len(ftdetect) >= 2 { - header, err := regexp2.Compile(ftdetect["header"].(string), 0) + header, err := regexp.Compile(ftdetect["header"].(string)) if err != nil { return nil, err } diff --git a/cmd/micro/lineArray.go b/cmd/micro/lineArray.go index 30f16798..bd76618a 100644 --- a/cmd/micro/lineArray.go +++ b/cmd/micro/lineArray.go @@ -180,14 +180,6 @@ func (la *LineArray) Substr(start, end Loc) string { return str } -func (la *LineArray) LineData() [][]byte { - lines := make([][]byte, len(la.lines)) - for i, l := range la.lines { - lines[i] = l.data - } - return lines -} - func (la *LineArray) State(lineN int) highlight.State { return la.lines[lineN].state }