func visualToCharPos(visualIndex int, lineN int, str string, buf *Buffer, tabsize int) (int, int, *tcell.Style) {
charPos := 0
+ var lineIdx int
var lastWidth int
var style *tcell.Style
- for i := range str {
- width := StringWidth(str[:i], tabsize)
+ var width int
+ var rw int
+ for i, c := range str {
+ // width := StringWidth(str[:i], tabsize)
if group, ok := buf.Match(lineN)[charPos]; ok {
- s := GetColor(group)
+ s := GetColor(group.String())
style = &s
}
if i != 0 {
charPos++
+ lineIdx += rw
}
lastWidth = width
+ rw = 0
+ if c == '\t' {
+ rw = tabsize - (lineIdx % tabsize)
+ width += rw
+ } else {
+ rw = runewidth.RuneWidth(c)
+ width += rw
+ }
}
return -1, -1, style
// This is only different from char if it's for example hidden character
drawChar rune
style tcell.Style
+ width int
}
type CellView struct {
}
func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
+ if width <= 0 {
+ return
+ }
+
+ matchingBrace := Loc{-1, -1}
+ // bracePairs is defined in buffer.go
+ if buf.Settings["matchbrace"].(bool) {
+ for _, bp := range bracePairs {
+ if buf.Cursor.RuneUnder(buf.Cursor.X) == bp[0] {
+ matchingBrace = buf.FindMatchingBrace(bp, buf.Cursor.Loc)
+ break
+ }
+ left := buf.Cursor.Loc.X
+ if buf.Settings["matchbraceleft"].(bool) {
+ left -= 1
+ if left < 0 {
+ left = 0
+ }
+ }
+ if buf.Cursor.RuneUnder(left) == bp[1] {
+ matchingBrace = buf.FindMatchingBrace(
+ bp, Loc{X: left, Y: buf.Cursor.Loc.Y})
+ }
+ }
+ }
+
tabsize := int(buf.Settings["tabsize"].(float64))
softwrap := buf.Settings["softwrap"].(bool)
- indentchar := []rune(buf.Settings["indentchar"].(string))[0]
+ indentrunes := []rune(buf.Settings["indentchar"].(string))
+ // if empty indentchar settings, use space
+ if indentrunes == nil || len(indentrunes) == 0 {
+ indentrunes = []rune{' '}
+ }
+ indentchar := indentrunes[0]
start := buf.Cursor.Y
- if buf.Settings["syntax"].(bool) {
+ if buf.Settings["syntax"].(bool) && buf.syntaxDef != nil {
if start > 0 && buf.lines[start-1].rehighlight {
buf.highlighter.ReHighlightLine(buf, start-1)
buf.lines[start-1].rehighlight = false
}
- buf.highlighter.ReHighlight(buf, start)
+ buf.highlighter.ReHighlightStates(buf, start)
+
+ buf.highlighter.HighlightMatches(buf, top, top+height)
}
c.lines = make([][]*Char, 0)
break
}
if group, ok := buf.Match(lineN)[colN]; ok {
- curStyle = GetColor(group)
+ curStyle = GetColor(group.String())
}
char := line[colN]
if viewCol >= 0 {
- c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle}
+ st := curStyle
+ if colN == matchingBrace.X && lineN == matchingBrace.Y && !buf.Cursor.HasSelection() {
+ st = curStyle.Reverse(true)
+ }
+ if viewCol < len(c.lines[viewLine]) {
+ c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, st, 1}
+ }
}
if char == '\t' {
+ charWidth := tabsize - (viewCol+left)%tabsize
if viewCol >= 0 {
c.lines[viewLine][viewCol].drawChar = indentchar
- viewCol += tabsize - viewCol%tabsize
- } else {
- viewCol += tabsize
+ c.lines[viewLine][viewCol].width = charWidth
+
+ indentStyle := curStyle
+ ch := buf.Settings["indentchar"].(string)
+ if group, ok := colorscheme["indent-char"]; ok && !IsStrWhitespace(ch) && ch != "" {
+ indentStyle = group
+ }
+
+ c.lines[viewLine][viewCol].style = indentStyle
}
- // viewCol += tabsize
+
+ for i := 1; i < charWidth; i++ {
+ viewCol++
+ if viewCol >= 0 && viewCol < lineLength && viewCol < len(c.lines[viewLine]) {
+ c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
+ }
+ }
+ viewCol++
} else if runewidth.RuneWidth(char) > 1 {
- viewCol += runewidth.RuneWidth(char)
+ charWidth := runewidth.RuneWidth(char)
+ if viewCol >= 0 {
+ c.lines[viewLine][viewCol].width = charWidth
+ }
+ for i := 1; i < charWidth; i++ {
+ viewCol++
+ if viewCol >= 0 && viewCol < lineLength && viewCol < len(c.lines[viewLine]) {
+ c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
+ }
+ }
+ viewCol++
} else {
viewCol++
}
}
if group, ok := buf.Match(lineN)[len(line)]; ok {
- curStyle = GetColor(group)
+ curStyle = GetColor(group.String())
}
// newline
viewLine++
lineN++
}
+
+ for i := top; i < top+height; i++ {
+ if i >= buf.NumLines {
+ break
+ }
+ buf.SetMatch(i, nil)
+ }
}