Better softwrap

This commit is contained in:
Zachary Yedidia 2019-12-24 16:01:08 -05:00
parent 432f1f3363
commit 3b306c1d3b
8 changed files with 27 additions and 43 deletions

View File

@ -40,7 +40,7 @@ func (h *BufPane) ScrollDown(n int) {
func (h *BufPane) MousePress(e *tcell.EventMouse) bool {
b := h.Buf
mx, my := e.Position()
mouseLoc := h.GetMouseLoc(buffer.Loc{mx, my})
mouseLoc := h.LocFromVisual(buffer.Loc{mx, my})
h.Cursor.Loc = mouseLoc
if h.mouseReleased {
if b.NumCursors() > 1 {
@ -1410,7 +1410,7 @@ func (h *BufPane) SpawnMultiCursorSelect() bool {
func (h *BufPane) MouseMultiCursor(e *tcell.EventMouse) bool {
b := h.Buf
mx, my := e.Position()
mouseLoc := h.GetMouseLoc(buffer.Loc{X: mx, Y: my})
mouseLoc := h.LocFromVisual(buffer.Loc{X: mx, Y: my})
c := buffer.NewCursor(b, mouseLoc)
b.AddCursor(c)
b.MergeCursors()

View File

@ -241,7 +241,7 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
// Mouse was just released
mx, my := e.Position()
mouseLoc := h.GetMouseLoc(buffer.Loc{X: mx, Y: my})
mouseLoc := h.LocFromVisual(buffer.Loc{X: mx, Y: my})
// Relocating here isn't really necessary because the cursor will
// be in the right place from the last mouse event

View File

@ -103,7 +103,7 @@ func (t *TabList) HandleEvent(event tcell.Event) {
mx, my := e.Position()
switch e.Buttons() {
case tcell.Button1:
ind := t.GetMouseLoc(buffer.Loc{mx, my})
ind := t.LocFromVisual(buffer.Loc{mx, my})
if ind != -1 {
t.SetActive(ind)
}

View File

@ -25,10 +25,8 @@ type BufWindow struct {
sline *StatusLine
lineHeight []int
hasCalcHeight bool
gutterOffset int
drawStatus bool
gutterOffset int
drawStatus bool
}
// NewBufWindow creates a new window at a location in the screen with a width and height
@ -36,7 +34,6 @@ func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
w := new(BufWindow)
w.View = new(View)
w.X, w.Y, w.Width, w.Height, w.Buf = x, y, width, height, buf
w.lineHeight = make([]int, height)
w.active = true
w.sline = NewStatusLine(w)
@ -58,10 +55,6 @@ func (v *View) SetView(view *View) {
func (w *BufWindow) Resize(width, height int) {
w.Width, w.Height = width, height
w.lineHeight = make([]int, height)
w.hasCalcHeight = false
// This recalculates lineHeight
w.GetMouseLoc(buffer.Loc{width, height})
w.Relocate()
}
@ -120,8 +113,7 @@ func (w *BufWindow) Clear() {
// but if softwrap is enabled things get complicated since one buffer
// line can take up multiple lines in the view
func (w *BufWindow) Bottomline() int {
// TODO: possible non-softwrap optimization
if !w.Buf.Settings["softwrap"].(bool) || !w.hasCalcHeight {
if !w.Buf.Settings["softwrap"].(bool) {
h := w.StartLine + w.Height - 1
if w.drawStatus {
h--
@ -129,15 +121,10 @@ func (w *BufWindow) Bottomline() int {
return h
}
prev := 0
for _, l := range w.lineHeight {
if l >= prev {
prev = l
} else {
break
}
}
return prev
l := w.LocFromVisual(buffer.Loc{0, w.Height})
log.Println("Bottom line:", l.Y)
return l.Y
}
// Relocate moves the view window so that the cursor is in view
@ -152,7 +139,7 @@ func (w *BufWindow) Relocate() bool {
if w.drawStatus {
h--
}
if b.LinesNum() <= h || !w.hasCalcHeight {
if b.LinesNum() <= h {
height = w.Height
}
ret := false
@ -189,15 +176,15 @@ func (w *BufWindow) Relocate() bool {
return ret
}
func (w *BufWindow) GetMouseLoc(svloc buffer.Loc) buffer.Loc {
// LocFromVisual takes a visual location (x and y position) and returns the
// position in the buffer corresponding to the visual location
// Computing the buffer location requires essentially drawing the entire screen
// to account for complications like softwrap, wide characters, and horizontal scrolling
// If the requested position does not correspond to a buffer location it returns
// the nearest position
func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
b := w.Buf
// TODO: possible non-softwrap optimization
// if !b.Settings["softwrap"].(bool) {
// l := b.LineBytes(svloc.Y)
// return buffer.Loc{b.GetActiveCursor().GetCharPosInLine(l, svloc.X), svloc.Y}
// }
hasMessage := len(b.Messages) > 0
bufHeight := w.Height
if w.drawStatus {
@ -293,11 +280,12 @@ func (w *BufWindow) GetMouseLoc(svloc buffer.Loc) buffer.Loc {
return bloc
}
if bloc.Y+1 >= b.LinesNum() || vloc.Y+1 >= bufHeight {
return bloc
}
bloc.X = w.StartCol
bloc.Y++
if bloc.Y >= b.LinesNum() {
break
}
}
return buffer.Loc{}
@ -378,7 +366,6 @@ func (w *BufWindow) displayBuffer() {
bufWidth--
}
w.hasCalcHeight = true
if b.Settings["syntax"].(bool) && b.SyntaxDef != nil {
for _, c := range b.GetCursors() {
// rehighlight starting from where the cursor is
@ -544,8 +531,6 @@ func (w *BufWindow) displayBuffer() {
nColsBeforeStart--
}
w.lineHeight[vloc.Y] = bloc.Y
totalwidth := w.StartCol - nColsBeforeStart
for len(line) > 0 {
r, size := utf8.DecodeRune(line)
@ -586,7 +571,6 @@ func (w *BufWindow) displayBuffer() {
break
}
vloc.X = 0
w.lineHeight[vloc.Y] = bloc.Y
// This will draw an empty line number because the current line is wrapped
w.drawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
}

View File

@ -65,7 +65,7 @@ func (i *InfoWindow) SetView(v *View) {}
func (i *InfoWindow) SetActive(b bool) {}
func (i *InfoWindow) IsActive() bool { return true }
func (i *InfoWindow) GetMouseLoc(vloc buffer.Loc) buffer.Loc {
func (i *InfoWindow) LocFromVisual(vloc buffer.Loc) buffer.Loc {
c := i.Buffer.GetActiveCursor()
l := i.Buffer.LineBytes(0)
n := utf8.RuneCountInString(i.Msg)

View File

@ -25,7 +25,7 @@ func NewTabWindow(w int, y int) *TabWindow {
return tw
}
func (w *TabWindow) GetMouseLoc(vloc buffer.Loc) int {
func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
x := -w.hscroll
for i, n := range w.Names {

View File

@ -44,7 +44,7 @@ func (w *TermWindow) IsActive() bool {
return w.active
}
func (w *TermWindow) GetMouseLoc(vloc buffer.Loc) buffer.Loc {
func (w *TermWindow) LocFromVisual(vloc buffer.Loc) buffer.Loc {
return vloc
}

View File

@ -20,7 +20,7 @@ type Window interface {
Relocate() bool
GetView() *View
SetView(v *View)
GetMouseLoc(vloc buffer.Loc) buffer.Loc
LocFromVisual(vloc buffer.Loc) buffer.Loc
Resize(w, h int)
SetActive(b bool)
IsActive() bool