Make preview renderer suspend early on line wrap

pull/794/head
Junegunn Choi 8 years ago
parent f8082bc53a
commit 9977a3e9fc
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

@ -1,8 +1,10 @@
package fzf
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"os/signal"
"regexp"
@ -852,41 +854,49 @@ func (t *Terminal) printPreview() {
return
}
t.pwindow.Erase()
skip := t.previewer.offset
extractColor(t.previewer.text, nil, func(str string, ansi *ansiState) bool {
if skip > 0 {
newlines := numLinesMax(str, skip)
if skip <= newlines {
for i := 0; i < skip; i++ {
str = str[strings.Index(str, "\n")+1:]
}
skip = 0
} else {
skip -= newlines
return true
}
maxWidth := t.pwindow.Width()
if t.tui.DoesAutoWrap() {
maxWidth -= 1
}
reader := bufio.NewReader(strings.NewReader(t.previewer.text))
lineNo := -t.previewer.offset
for {
line, err := reader.ReadString('\n')
eof := err == io.EOF
if !eof {
line = line[:len(line)-1]
}
lines := strings.Split(str, "\n")
for i, line := range lines {
limit := t.pwindow.Width()
if t.tui.DoesAutoWrap() {
limit -= 1
}
if i == 0 {
limit -= t.pwindow.X()
}
trimmed := []rune(line)
if !t.preview.wrap {
trimmed, _ = t.trimRight(trimmed, limit)
lineNo++
if lineNo > t.pwindow.Height() {
break
} else if lineNo > 0 {
var fillRet tui.FillReturn
extractColor(line, nil, func(str string, ansi *ansiState) bool {
trimmed := []rune(str)
if !t.preview.wrap {
trimmed, _ = t.trimRight(trimmed, maxWidth-t.pwindow.X())
}
str, _ = t.processTabs(trimmed, 0)
if ansi != nil && ansi.colored() {
fillRet = t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
} else {
fillRet = t.pwindow.Fill(str)
}
return fillRet == tui.FillContinue
})
switch fillRet {
case tui.FillNextLine:
continue
case tui.FillSuspend:
break
}
lines[i], _ = t.processTabs(trimmed, 0)
str = strings.Join(lines, "\n")
t.pwindow.Fill("\n")
}
if ansi != nil && ansi.colored() {
return t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
if eof {
break
}
return t.pwindow.Fill(str)
})
}
t.pwindow.FinishFill()
if t.previewer.lines > t.pwindow.Height() {
offset := fmt.Sprintf("%d/%d", t.previewer.offset+1, t.previewer.lines)

@ -730,23 +730,29 @@ func wrapLine(input string, prefixLength int, max int, tabstop int) []wrappedLin
return lines
}
func (w *LightWindow) fill(str string, onMove func()) bool {
func (w *LightWindow) fill(str string, onMove func()) FillReturn {
allLines := strings.Split(str, "\n")
for i, line := range allLines {
lines := wrapLine(line, w.posx, w.width, w.tabstop)
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)
}
return FillNextLine
}
w.stderr(wl.text)
w.posx += wl.displayWidth
if j < len(lines)-1 || i < len(allLines)-1 {
if w.posy+1 >= w.height {
return false
return FillSuspend
}
w.MoveAndClear(w.posy+1, 0)
onMove()
}
}
}
return true
return FillContinue
}
func (w *LightWindow) setBg() {
@ -755,13 +761,13 @@ func (w *LightWindow) setBg() {
}
}
func (w *LightWindow) Fill(text string) bool {
func (w *LightWindow) Fill(text string) FillReturn {
w.MoveAndClear(w.posy, w.posx)
w.setBg()
return w.fill(text, w.setBg)
}
func (w *LightWindow) CFill(fg Color, bg Color, attr Attr, text string) bool {
func (w *LightWindow) CFill(fg Color, bg Color, attr Attr, text string) FillReturn {
w.MoveAndClear(w.posy, w.posx)
if bg == colDefault {
bg = w.bg

@ -282,11 +282,14 @@ func (r *FullscreenRenderer) DoesAutoWrap() bool {
return true
}
func (w *CursesWindow) Fill(str string) bool {
return C.waddstr(w.impl, C.CString(str)) == C.OK
func (w *CursesWindow) Fill(str string) FillReturn {
if C.waddstr(w.impl, C.CString(str)) == C.OK {
return FillContinue
}
return FillSuspend
}
func (w *CursesWindow) CFill(fg Color, bg Color, attr Attr, str string) bool {
func (w *CursesWindow) CFill(fg Color, bg Color, attr Attr, str string) FillReturn {
index := ColorPair{fg, bg, -1}.index()
C.wcolor_set(w.impl, C.short(index), nil)
C.wattron(w.impl, C.int(attr))

@ -477,7 +477,7 @@ func (w *TcellWindow) CPrint(pair ColorPair, attr Attr, text string) {
w.printString(text, pair, attr)
}
func (w *TcellWindow) fillString(text string, pair ColorPair, a Attr) bool {
func (w *TcellWindow) fillString(text string, pair ColorPair, a Attr) FillReturn {
lx := 0
var style tcell.Style
@ -511,7 +511,7 @@ func (w *TcellWindow) fillString(text string, pair ColorPair, a Attr) bool {
var yPos = w.top + w.lastY
if yPos >= (w.top + w.height) {
return false
return FillSuspend
}
_screen.SetContent(xPos, yPos, r, nil, style)
@ -520,14 +520,14 @@ func (w *TcellWindow) fillString(text string, pair ColorPair, a Attr) bool {
}
w.lastX += lx
return true
return FillContinue
}
func (w *TcellWindow) Fill(str string) bool {
func (w *TcellWindow) Fill(str string) FillReturn {
return w.fillString(str, ColDefault, 0)
}
func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) bool {
func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) FillReturn {
return w.fillString(str, ColorPair{fg, bg, -1}, a)
}

@ -117,6 +117,14 @@ const (
colWhite
)
type FillReturn int
const (
FillContinue FillReturn = iota
FillNextLine
FillSuspend
)
type ColorPair struct {
fg Color
bg Color
@ -216,8 +224,8 @@ type Window interface {
MoveAndClear(y int, x int)
Print(text string)
CPrint(color ColorPair, attr Attr, text string)
Fill(text string) bool
CFill(fg Color, bg Color, attr Attr, text string) bool
Fill(text string) FillReturn
CFill(fg Color, bg Color, attr Attr, text string) FillReturn
Erase()
}

Loading…
Cancel
Save