From 21ab64e96213ec99cf3f6f207690ffe710713fcc Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 2 Nov 2023 01:35:36 +0900 Subject: [PATCH] sixel: Export $FZF_PREVIEW_TOP to the preview command (#2544) So that it can determine if it should subtract 1 from $FZF_PREVIEW_LINES to avoid scrolling issue of Sixel image that touches the bottom of the screen. --- bin/fzf-preview.sh | 27 ++++++++++++++++++++------- man/man1/fzf.1 | 3 +++ src/terminal.go | 5 ++--- src/tui/dummy.go | 1 + src/tui/light.go | 4 ++++ src/tui/tcell.go | 4 ++++ src/tui/tui.go | 1 + 7 files changed, 35 insertions(+), 10 deletions(-) diff --git a/bin/fzf-preview.sh b/bin/fzf-preview.sh index ae4c6521..d72cd2d4 100755 --- a/bin/fzf-preview.sh +++ b/bin/fzf-preview.sh @@ -13,14 +13,14 @@ if [[ $# -ne 1 ]]; then fi file=${1/#\~\//$HOME/} -type=$(file --mime-type "$file") - -dim=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES} -if [[ $dim = x ]]; then - dim=$(stty size | awk '{print $2 "x" $1}') -fi +type=$(file --dereference --mime -- "$file") if [[ ! $type =~ image/ ]]; then + if [[ $type =~ =binary ]]; then + file "$1" + exit + fi + # Sometimes bat is installed as batcat. if command -v batcat > /dev/null; then batname="batcat" @@ -32,7 +32,19 @@ if [[ ! $type =~ image/ ]]; then fi ${batname} --style="${BAT_STYLE:-numbers}" --color=always --pager=never -- "$file" -elif [[ $KITTY_WINDOW_ID ]]; then + exit +fi + +dim=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES} +if [[ $dim = x ]]; then + dim=$(stty size < /dev/tty | awk '{print $2 "x" $1}') +elif ! [[ $KITTY_WINDOW_ID ]] && (( FZF_PREVIEW_TOP + FZF_PREVIEW_LINES == $(stty size < /dev/tty | awk '{print $1}') )); then + # Avoid scrolling issue when the Sixel image touches the bottom of the screen + # * https://github.com/junegunn/fzf/issues/2544 + dim=${FZF_PREVIEW_COLUMNS}x$((FZF_PREVIEW_LINES - 1)) +fi + +if [[ $KITTY_WINDOW_ID ]]; then # 1. 'memory' is the fastest option but if you want the image to be scrollable, # you have to use 'stream'. # @@ -42,6 +54,7 @@ elif [[ $KITTY_WINDOW_ID ]]; then kitty icat --clear --transfer-mode=memory --stdin=no --place="$dim@0x0" "$file" | sed '$d' | sed $'$s/$/\e[m/' elif command -v chafa > /dev/null; then chafa -f sixel -s "$dim" "$file" + # Add a new line character so that fzf can display multiple images in the preview window echo else file "$file" diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 8666ec02..309be90e 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -548,6 +548,9 @@ they represent the exact size of the preview window. (It also overrides by the default shell, so prefer to refer to the ones with \fBFZF_PREVIEW_\fR prefix.) +fzf also exports \fB$FZF_PREVIEW_TOP\fR and \fB$FZF_PREVIEW_LEFT\fR so that +the preview command can determine the position of the preview window. + A placeholder expression starting with \fB+\fR flag will be replaced to the space-separated list of the selected lines (or the current line if no selection was made) individually quoted. diff --git a/src/terminal.go b/src/terminal.go index 494fa462..878e3d9a 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -2067,9 +2067,6 @@ Loop: if requiredLines > 0 { if y+requiredLines == height { - if t.tui.MaxY() == t.pwindow.Top()+height { - t.tui.PassThrough("\x1b[1T") - } t.pwindow.Move(height-1, maxWidth-1) t.previewed.filled = true break Loop @@ -2790,6 +2787,8 @@ func (t *Terminal) Loop() { env = append(env, "FZF_PREVIEW_"+lines) env = append(env, columns) env = append(env, "FZF_PREVIEW_"+columns) + env = append(env, fmt.Sprintf("FZF_PREVIEW_TOP=%d", t.tui.Top()+t.pwindow.Top())) + env = append(env, fmt.Sprintf("FZF_PREVIEW_LEFT=%d", t.pwindow.Left())) } cmd.Env = env diff --git a/src/tui/dummy.go b/src/tui/dummy.go index 13c2aeec..cceb4478 100644 --- a/src/tui/dummy.go +++ b/src/tui/dummy.go @@ -41,6 +41,7 @@ func (r *FullscreenRenderer) Close() {} func (r *FullscreenRenderer) Size() TermSize { return TermSize{} } func (r *FullscreenRenderer) GetChar() Event { return Event{} } +func (r *FullscreenRenderer) Top() int { return 0 } func (r *FullscreenRenderer) MaxX() int { return 0 } func (r *FullscreenRenderer) MaxY() int { return 0 } diff --git a/src/tui/light.go b/src/tui/light.go index e9cf04eb..d26a48f6 100644 --- a/src/tui/light.go +++ b/src/tui/light.go @@ -720,6 +720,10 @@ func (r *LightRenderer) Close() { r.restoreTerminal() } +func (r *LightRenderer) Top() int { + return r.yoffset +} + func (r *LightRenderer) MaxX() int { return r.width } diff --git a/src/tui/tcell.go b/src/tui/tcell.go index cd723e32..d0a710a3 100644 --- a/src/tui/tcell.go +++ b/src/tui/tcell.go @@ -172,6 +172,10 @@ func (r *FullscreenRenderer) Init() { initTheme(r.theme, r.defaultTheme(), r.forceBlack) } +func (r *FullscreenRenderer) Top() int { + return 0 +} + func (r *FullscreenRenderer) MaxX() int { ncols, _ := _screen.Size() return int(ncols) diff --git a/src/tui/tui.go b/src/tui/tui.go index 2ebb5e72..7ba437aa 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -494,6 +494,7 @@ type Renderer interface { GetChar() Event + Top() int MaxX() int MaxY() int