From bc9d2abdb67639e06f7002b278341fb498b79456 Mon Sep 17 00:00:00 2001
From: Junegunn Choi <junegunn.c@gmail.com>
Date: Wed, 19 Jul 2017 22:46:16 +0900
Subject: [PATCH] Improve preview window rendering

- Fix incorrect display of the last line when more than a line is
  wrapped above
- Avoid unnecessary flickering of the window
---
 src/terminal.go  |  6 ++++--
 src/tui/light.go | 16 ++++++++++++----
 src/tui/tcell.go |  4 ++++
 src/tui/tui.go   |  1 +
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/terminal.go b/src/terminal.go
index 03381368..81fb8808 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -962,6 +962,7 @@ func (t *Terminal) printPreview() {
 	}
 	reader := bufio.NewReader(strings.NewReader(t.previewer.text))
 	lineNo := -t.previewer.offset
+	height := t.pwindow.Height()
 	var ansi *ansiState
 	for {
 		line, err := reader.ReadString('\n')
@@ -970,7 +971,8 @@ func (t *Terminal) printPreview() {
 			line = line[:len(line)-1]
 		}
 		lineNo++
-		if lineNo > t.pwindow.Height() {
+		if lineNo > height ||
+			t.pwindow.Y() == height-1 && t.pwindow.X() > 0 {
 			break
 		} else if lineNo > 0 {
 			var fillRet tui.FillReturn
@@ -1000,7 +1002,7 @@ func (t *Terminal) printPreview() {
 		}
 	}
 	t.pwindow.FinishFill()
-	if t.previewer.lines > t.pwindow.Height() {
+	if t.previewer.lines > height {
 		offset := fmt.Sprintf("%d/%d", t.previewer.offset+1, t.previewer.lines)
 		pos := t.pwindow.Width() - len(offset)
 		if t.tui.DoesAutoWrap() {
diff --git a/src/tui/light.go b/src/tui/light.go
index 5159aafe..7fc231f8 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -705,6 +705,10 @@ func (w *LightWindow) X() int {
 	return w.posx
 }
 
+func (w *LightWindow) Y() int {
+	return w.posy
+}
+
 func (w *LightWindow) Enclose(y int, x int) bool {
 	return x >= w.left && x < (w.left+w.width) &&
 		y >= w.top && y < (w.top+w.height)
@@ -839,17 +843,20 @@ func (w *LightWindow) fill(str string, onMove func()) FillReturn {
 		for j, wl := range lines {
 			if w.posx >= w.Width()-1 && wl.displayWidth == 0 {
 				if w.posy < w.height-1 {
-					w.MoveAndClear(w.posy+1, 0)
+					w.Move(w.posy+1, 0)
 				}
 				return FillNextLine
 			}
 			w.stderrInternal(wl.text, false)
 			w.posx += wl.displayWidth
+
+			// Wrap line
 			if j < len(lines)-1 || i < len(allLines)-1 {
 				if w.posy+1 >= w.height {
 					return FillSuspend
 				}
-				w.MoveAndClear(w.posy+1, 0)
+				w.MoveAndClear(w.posy, w.posx)
+				w.Move(w.posy+1, 0)
 				onMove()
 			}
 		}
@@ -864,13 +871,13 @@ func (w *LightWindow) setBg() {
 }
 
 func (w *LightWindow) Fill(text string) FillReturn {
-	w.MoveAndClear(w.posy, w.posx)
+	w.Move(w.posy, w.posx)
 	w.setBg()
 	return w.fill(text, w.setBg)
 }
 
 func (w *LightWindow) CFill(fg Color, bg Color, attr Attr, text string) FillReturn {
-	w.MoveAndClear(w.posy, w.posx)
+	w.Move(w.posy, w.posx)
 	if bg == colDefault {
 		bg = w.bg
 	}
@@ -882,6 +889,7 @@ func (w *LightWindow) CFill(fg Color, bg Color, attr Attr, text string) FillRetu
 }
 
 func (w *LightWindow) FinishFill() {
+	w.MoveAndClear(w.posy, w.posx)
 	for y := w.posy + 1; y < w.height; y++ {
 		w.MoveAndClear(y, 0)
 	}
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index 0c80de2b..bed52801 100644
--- a/src/tui/tcell.go
+++ b/src/tui/tcell.go
@@ -164,6 +164,10 @@ func (w *TcellWindow) X() int {
 	return w.lastX
 }
 
+func (w *TcellWindow) Y() int {
+	return w.lastY
+}
+
 func (r *FullscreenRenderer) DoesAutoWrap() bool {
 	return false
 }
diff --git a/src/tui/tui.go b/src/tui/tui.go
index 1ba8ca79..24206160 100644
--- a/src/tui/tui.go
+++ b/src/tui/tui.go
@@ -236,6 +236,7 @@ type Window interface {
 	Close()
 
 	X() int
+	Y() int
 	Enclose(y int, x int) bool
 
 	Move(y int, x int)
-- 
GitLab