m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-14 14:23:47 -05:00

Print --wrap-sign in preview window

Close #4233
This commit is contained in:
Junegunn Choi
2025-02-10 23:58:23 +09:00
parent bfea9e53a6
commit 19ef8891e3
5 changed files with 66 additions and 34 deletions

View File

@@ -1936,6 +1936,7 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
pwidth -= 1 pwidth -= 1
} }
t.pwindow = t.tui.NewWindow(y, x, pwidth, pheight, tui.WindowPreview, noBorder, true) t.pwindow = t.tui.NewWindow(y, x, pwidth, pheight, tui.WindowPreview, noBorder, true)
t.pwindow.SetWrapSign(t.wrapSign, t.wrapSignWidth)
if !hadPreviewWindow { if !hadPreviewWindow {
t.pwindow.Erase() t.pwindow.Erase()
} }

View File

@@ -44,8 +44,9 @@ func (r *LightRenderer) stderr(str string) {
r.stderrInternal(str, true, "") r.stderrInternal(str, true, "")
} }
const CR string = "\x1b[2m" const DIM string = "\x1b[2m"
const LF string = "\x1b[2m␊" const CR string = DIM + "␍"
const LF string = DIM + "␊"
func (r *LightRenderer) stderrInternal(str string, allowNLCR bool, resetCode string) { func (r *LightRenderer) stderrInternal(str string, allowNLCR bool, resetCode string) {
bytes := []byte(str) bytes := []byte(str)
@@ -140,6 +141,8 @@ type LightWindow struct {
tabstop int tabstop int
fg Color fg Color
bg Color bg Color
wrapSign string
wrapSignWidth int
} }
func NewLightRenderer(ttyin *os.File, theme *ColorTheme, forceBlack bool, mouse bool, tabstop int, clearOnExit bool, fullscreen bool, maxHeightFunc func(int) int) (Renderer, error) { func NewLightRenderer(ttyin *os.File, theme *ColorTheme, forceBlack bool, mouse bool, tabstop int, clearOnExit bool, fullscreen bool, maxHeightFunc func(int) int) (Renderer, error) {
@@ -1105,11 +1108,12 @@ type wrappedLine struct {
displayWidth int displayWidth int
} }
func wrapLine(input string, prefixLength int, max int, tabstop int) []wrappedLine { func wrapLine(input string, prefixLength int, initialMax int, tabstop int, wrapSignWidth int) []wrappedLine {
lines := []wrappedLine{} lines := []wrappedLine{}
width := 0 width := 0
line := "" line := ""
gr := uniseg.NewGraphemes(input) gr := uniseg.NewGraphemes(input)
max := initialMax
for gr.Next() { for gr.Next() {
rs := gr.Runes() rs := gr.Runes()
str := string(rs) str := string(rs)
@@ -1131,6 +1135,7 @@ func wrapLine(input string, prefixLength int, max int, tabstop int) []wrappedLin
line = str line = str
prefixLength = 0 prefixLength = 0
width = w width = w
max = initialMax - wrapSignWidth
} }
} }
lines = append(lines, wrappedLine{string(line), width}) lines = append(lines, wrappedLine{string(line), width})
@@ -1140,7 +1145,7 @@ func wrapLine(input string, prefixLength int, max int, tabstop int) []wrappedLin
func (w *LightWindow) fill(str string, resetCode string) FillReturn { func (w *LightWindow) fill(str string, resetCode string) 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, w.wrapSignWidth)
for j, wl := range lines { for j, wl := range lines {
w.stderrInternal(wl.text, false, resetCode) w.stderrInternal(wl.text, false, resetCode)
w.posx += wl.displayWidth w.posx += wl.displayWidth
@@ -1153,6 +1158,11 @@ func (w *LightWindow) fill(str string, resetCode string) FillReturn {
w.MoveAndClear(w.posy, w.posx) w.MoveAndClear(w.posy, w.posx)
w.Move(w.posy+1, 0) w.Move(w.posy+1, 0)
w.renderer.stderr(resetCode) w.renderer.stderr(resetCode)
if len(lines) > 1 {
w.stderrInternal(DIM+w.wrapSign, false, resetCode)
w.renderer.stderr(resetCode)
w.Move(w.posy, w.wrapSignWidth)
}
} }
} }
} }
@@ -1226,6 +1236,11 @@ func (w *LightWindow) EraseMaybe() bool {
return false return false
} }
func (w *LightWindow) SetWrapSign(sign string, width int) {
w.wrapSign = sign
w.wrapSignWidth = width
}
func (r *LightRenderer) HideCursor() { func (r *LightRenderer) HideCursor() {
r.showCursor = false r.showCursor = false
r.csi("?25l") r.csi("?25l")

View File

@@ -53,6 +53,8 @@ type TcellWindow struct {
uri *string uri *string
params *string params *string
showCursor bool showCursor bool
wrapSign string
wrapSignWidth int
} }
func (w *TcellWindow) Top() int { func (w *TcellWindow) Top() int {
@@ -629,6 +631,11 @@ func (w *TcellWindow) EraseMaybe() bool {
return true return true
} }
func (w *TcellWindow) SetWrapSign(sign string, width int) {
w.wrapSign = sign
w.wrapSignWidth = width
}
func (w *TcellWindow) EncloseX(x int) bool { func (w *TcellWindow) EncloseX(x int) bool {
return x >= w.left && x < (w.left+w.width) return x >= w.left && x < (w.left+w.width)
} }
@@ -757,11 +764,18 @@ Loop:
// word wrap: // word wrap:
xPos := w.left + w.lastX + lx xPos := w.left + w.lastX + lx
if xPos >= (w.left + w.width) { if xPos >= w.left+w.width {
w.lastY++ w.lastY++
w.lastX = 0 w.lastX = 0
lx = 0 lx = 0
xPos = w.left xPos = w.left
wgr := uniseg.NewGraphemes(w.wrapSign)
for wgr.Next() {
rs := wgr.Runes()
_screen.SetContent(w.left+lx, w.top+w.lastY, rs[0], rs[1:], style.Dim(true))
lx += uniseg.StringWidth(string(rs))
}
xPos = w.left + lx
} }
yPos := w.top + w.lastY yPos := w.top + w.lastY

View File

@@ -659,6 +659,8 @@ type Window interface {
LinkEnd() LinkEnd()
Erase() Erase()
EraseMaybe() bool EraseMaybe() bool
SetWrapSign(string, int)
} }
type FullscreenRenderer struct { type FullscreenRenderer struct {

View File

@@ -453,7 +453,7 @@ class TestPreview < TestInteractive
tmux.send_keys 'f' tmux.send_keys 'f'
tmux.until do |lines| tmux.until do |lines|
assert_equal '::', lines[0] assert_equal '::', lines[0]
assert_equal ' 3', lines[1] assert_equal ' 3', lines[1]
end end
end end
@@ -527,7 +527,7 @@ class TestPreview < TestInteractive
tmux.send_keys "seq 10 | #{FZF} --preview-border rounded --preview-window '~5,2,+0,<100000(~0,+100,wrap,noinfo)' --preview 'seq 1000'", :Enter tmux.send_keys "seq 10 | #{FZF} --preview-border rounded --preview-window '~5,2,+0,<100000(~0,+100,wrap,noinfo)' --preview 'seq 1000'", :Enter
tmux.until { |lines| assert_equal 10, lines.match_count } tmux.until { |lines| assert_equal 10, lines.match_count }
tmux.until do |lines| tmux.until do |lines|
assert_equal ['╭────╮', '│ 10 │', '│ 0 │', '│ 10 │', '│ 1 │'], lines.take(5).map(&:strip) assert_equal ['╭────╮', '│ 10 │', '│ ↳ 0│', '│ 10 │', '│ ↳ 1│'], lines.take(5).map(&:strip)
end end
end end