Make preview renderer suspend early on line wrap
This commit is contained in:
parent
f8082bc53a
commit
9977a3e9fc
@ -1,8 +1,10 @@
|
|||||||
package fzf
|
package fzf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -852,41 +854,49 @@ func (t *Terminal) printPreview() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.pwindow.Erase()
|
t.pwindow.Erase()
|
||||||
skip := t.previewer.offset
|
|
||||||
extractColor(t.previewer.text, nil, func(str string, ansi *ansiState) bool {
|
maxWidth := t.pwindow.Width()
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lines := strings.Split(str, "\n")
|
|
||||||
for i, line := range lines {
|
|
||||||
limit := t.pwindow.Width()
|
|
||||||
if t.tui.DoesAutoWrap() {
|
if t.tui.DoesAutoWrap() {
|
||||||
limit -= 1
|
maxWidth -= 1
|
||||||
}
|
}
|
||||||
if i == 0 {
|
reader := bufio.NewReader(strings.NewReader(t.previewer.text))
|
||||||
limit -= t.pwindow.X()
|
lineNo := -t.previewer.offset
|
||||||
|
for {
|
||||||
|
line, err := reader.ReadString('\n')
|
||||||
|
eof := err == io.EOF
|
||||||
|
if !eof {
|
||||||
|
line = line[:len(line)-1]
|
||||||
}
|
}
|
||||||
trimmed := []rune(line)
|
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 {
|
if !t.preview.wrap {
|
||||||
trimmed, _ = t.trimRight(trimmed, limit)
|
trimmed, _ = t.trimRight(trimmed, maxWidth-t.pwindow.X())
|
||||||
}
|
|
||||||
lines[i], _ = t.processTabs(trimmed, 0)
|
|
||||||
str = strings.Join(lines, "\n")
|
|
||||||
}
|
}
|
||||||
|
str, _ = t.processTabs(trimmed, 0)
|
||||||
if ansi != nil && ansi.colored() {
|
if ansi != nil && ansi.colored() {
|
||||||
return t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
|
fillRet = t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
|
||||||
|
} else {
|
||||||
|
fillRet = t.pwindow.Fill(str)
|
||||||
}
|
}
|
||||||
return t.pwindow.Fill(str)
|
return fillRet == tui.FillContinue
|
||||||
})
|
})
|
||||||
|
switch fillRet {
|
||||||
|
case tui.FillNextLine:
|
||||||
|
continue
|
||||||
|
case tui.FillSuspend:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t.pwindow.Fill("\n")
|
||||||
|
}
|
||||||
|
if eof {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
t.pwindow.FinishFill()
|
t.pwindow.FinishFill()
|
||||||
if t.previewer.lines > t.pwindow.Height() {
|
if t.previewer.lines > t.pwindow.Height() {
|
||||||
offset := fmt.Sprintf("%d/%d", t.previewer.offset+1, t.previewer.lines)
|
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
|
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")
|
allLines := strings.Split(str, "\n")
|
||||||
for i, line := range allLines {
|
for i, line := range allLines {
|
||||||
lines := wrapLine(line, w.posx, w.width, w.tabstop)
|
lines := wrapLine(line, w.posx, w.width, w.tabstop)
|
||||||
for j, wl := range lines {
|
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.stderr(wl.text)
|
||||||
w.posx += wl.displayWidth
|
w.posx += wl.displayWidth
|
||||||
if j < len(lines)-1 || i < len(allLines)-1 {
|
if j < len(lines)-1 || i < len(allLines)-1 {
|
||||||
if w.posy+1 >= w.height {
|
if w.posy+1 >= w.height {
|
||||||
return false
|
return FillSuspend
|
||||||
}
|
}
|
||||||
w.MoveAndClear(w.posy+1, 0)
|
w.MoveAndClear(w.posy+1, 0)
|
||||||
onMove()
|
onMove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return FillContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LightWindow) setBg() {
|
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.MoveAndClear(w.posy, w.posx)
|
||||||
w.setBg()
|
w.setBg()
|
||||||
return w.fill(text, 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)
|
w.MoveAndClear(w.posy, w.posx)
|
||||||
if bg == colDefault {
|
if bg == colDefault {
|
||||||
bg = w.bg
|
bg = w.bg
|
||||||
|
@ -282,11 +282,14 @@ func (r *FullscreenRenderer) DoesAutoWrap() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *CursesWindow) Fill(str string) bool {
|
func (w *CursesWindow) Fill(str string) FillReturn {
|
||||||
return C.waddstr(w.impl, C.CString(str)) == C.OK
|
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()
|
index := ColorPair{fg, bg, -1}.index()
|
||||||
C.wcolor_set(w.impl, C.short(index), nil)
|
C.wcolor_set(w.impl, C.short(index), nil)
|
||||||
C.wattron(w.impl, C.int(attr))
|
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)
|
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
|
lx := 0
|
||||||
|
|
||||||
var style tcell.Style
|
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
|
var yPos = w.top + w.lastY
|
||||||
|
|
||||||
if yPos >= (w.top + w.height) {
|
if yPos >= (w.top + w.height) {
|
||||||
return false
|
return FillSuspend
|
||||||
}
|
}
|
||||||
|
|
||||||
_screen.SetContent(xPos, yPos, r, nil, style)
|
_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
|
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)
|
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)
|
return w.fillString(str, ColorPair{fg, bg, -1}, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +117,14 @@ const (
|
|||||||
colWhite
|
colWhite
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FillReturn int
|
||||||
|
|
||||||
|
const (
|
||||||
|
FillContinue FillReturn = iota
|
||||||
|
FillNextLine
|
||||||
|
FillSuspend
|
||||||
|
)
|
||||||
|
|
||||||
type ColorPair struct {
|
type ColorPair struct {
|
||||||
fg Color
|
fg Color
|
||||||
bg Color
|
bg Color
|
||||||
@ -216,8 +224,8 @@ type Window interface {
|
|||||||
MoveAndClear(y int, x int)
|
MoveAndClear(y int, x int)
|
||||||
Print(text string)
|
Print(text string)
|
||||||
CPrint(color ColorPair, attr Attr, text string)
|
CPrint(color ColorPair, attr Attr, text string)
|
||||||
Fill(text string) bool
|
Fill(text string) FillReturn
|
||||||
CFill(fg Color, bg Color, attr Attr, text string) bool
|
CFill(fg Color, bg Color, attr Attr, text string) FillReturn
|
||||||
Erase()
|
Erase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user