Add beginning of cellview as well as improved ViewTypes

This is the beginning of the view refactor (#515). It's just
the start and is untested for now.
This commit is contained in:
Zachary Yedidia
2017-02-13 16:11:57 -05:00
parent 9b51069041
commit 94175d1aa6
2 changed files with 117 additions and 5 deletions

108
cmd/micro/cellview.go Normal file
View File

@@ -0,0 +1,108 @@
package main
import (
"github.com/mattn/go-runewidth"
"github.com/zyedidia/tcell"
)
func min(a, b int) int {
if a <= b {
return a
}
return b
}
func VisualToCharPos(visualIndex int, str string, tabsize int) int {
visualPos := 0
charPos := 0
for _, c := range str {
width := StringWidth(string(c), tabsize)
if visualPos+width > visualIndex {
return charPos
}
visualPos += width
charPos++
}
return 0
}
type Char struct {
visualLoc Loc
realLoc Loc
char rune
style tcell.Style
}
type CellView struct {
lines [][]*Char
}
func (c *CellView) Draw(buf *Buffer, start, top, height, left, width int) {
tabsize := buf.Settings["tabsize"].(int)
softwrap := buf.Settings["softwrap"].(bool)
indentchar := []rune(buf.Settings["indentchar"].(string))[0]
if len(c.lines) != height {
c.lines = make([][]*Char, height)
}
viewLine := 0
lineN := top
for viewLine < height {
lineStr := string(buf.lines[lineN])
line := []rune(lineStr)
colN := VisualToCharPos(left, lineStr, tabsize)
viewCol := 0
// We'll either draw the length of the line, or the width of the screen
// whichever is smaller
lineLength := min(len(line), width)
if len(c.lines[viewLine]) != lineLength {
c.lines[viewLine] = make([]*Char, lineLength)
}
wrap := false
// We only need to wrap if the length of the line is greater than the width of the terminal screen
if softwrap && len(line) > width {
wrap = true
// We're going to draw the entire line now
lineLength = len(line)
}
for viewCol < lineLength {
char := line[colN]
colN++
if char == '\t' {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, indentchar, tcell.StyleDefault}
// TODO: this always adds 4 spaces but it should really add just the remainder to the next tab location
viewCol += tabsize
} else if runewidth.RuneWidth(char) > 1 {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, tcell.StyleDefault}
viewCol += runewidth.RuneWidth(char)
} else {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, tcell.StyleDefault}
viewCol++
}
if wrap && viewCol > width {
viewLine++
viewCol = 0
// If we go too far soft wrapping we have to cut off
if viewLine >= height {
break
}
}
}
// newline
viewLine++
lineN++
}
}

View File

@@ -11,12 +11,16 @@ import (
"github.com/zyedidia/tcell"
)
type ViewType int
type ViewType struct {
readonly bool // The file cannot be edited
scratch bool // The file cannot be saved
}
const (
vtDefault ViewType = iota
vtHelp
vtLog
var (
vtDefault = ViewType{false, false}
vtHelp = ViewType{true, true}
vtLog = ViewType{true, true}
vtScratch = ViewType{false, true}
)
// The View struct stores information about a view into a buffer.