summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2017-01-11 22:13:40 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2017-01-11 22:13:40 +0900
commit9977a3e9fcdc2d2feda2f8cd2990a89c21804e56 (patch)
tree9a4657c2bb6733dfd3304f7531aa51cae66c4b6f /src
parentf8082bc53a5bc736558d5952a34b527f12815878 (diff)
Make preview renderer suspend early on line wrap
Diffstat (limited to 'src')
-rw-r--r--src/terminal.go72
-rw-r--r--src/tui/light.go16
-rw-r--r--src/tui/ncurses.go9
-rw-r--r--src/tui/tcell.go10
-rw-r--r--src/tui/tui.go12
5 files changed, 73 insertions, 46 deletions
diff --git a/src/terminal.go b/src/terminal.go
index ce63adf1..0353157e 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -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)
diff --git a/src/tui/light.go b/src/tui/light.go
index 4725ef56..248477c7 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -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
diff --git a/src/tui/ncurses.go b/src/tui/ncurses.go
index f6feefc6..3e636ba2 100644
--- a/src/tui/ncurses.go
+++ b/src/tui/ncurses.go
@@ -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))
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index b6f08192..3399d32b 100644
--- a/src/tui/tcell.go
+++ b/src/tui/tcell.go
@@ -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)
}
diff --git a/src/tui/tui.go b/src/tui/tui.go
index eb504f8c..33358e85 100644
--- a/src/tui/tui.go
+++ b/src/tui/tui.go
@@ -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()
}