Aloxaf / fzf-tab

Replace zsh's default completion selection menu with fzf!
MIT License
3.28k stars 94 forks source link

[BUG] Pictures previews not working with chafa and `-f kitty` #303

Open xfzv opened 2 years ago

xfzv commented 2 years ago

I can make sure:

Describe the bug

I followed the wiki for Previews - show file contents.

It works just fine with the following script (taken from the wiki too, slightly modified):

#! /usr/bin/env bash

has_cmd() { command -v "$1" >/dev/null 2>&1 ; }

MIME="$(file -bL --mime-type "$1")"
CATEGORY="${MIME%%/*}"
KIND="${MIME##*/}"

if [[ -d "$1" ]]; then
    has_cmd exa && exa -a --color=always -l -g --git --group-directories-first --icons "$1"
    has_cmd lsd && lsd -al --color=always --icon=always "$1"
elif [[ "$CATEGORY" == "image" ]]; then
    has_cmd chafa && chafa "$1"
    has_cmd exiftool && exiftool "$1"
elif [[ "$CATEGORY" == "text" ]]; then
    has_cmd bat && bat --color=always --line-range :200 "$1"
elif [[ "$CATEGORY" == "video" ]]; then
    has_cmd mediainfo && mediainfo "$1"
else
    lesspipe.sh "$1" | bat --color=always --line-range :200
fi

Relevant part of my fzf-tab config:

zstyle ':fzf-tab:complete:*:*' fzf-preview 'less ${(Q)realpath}'
zstyle ':fzf-tab:complete:*:*' fzf-flags --height=100% --preview-window=right:wrap
zstyle ':fzf-tab:complete:*:options' fzf-preview
zstyle ':fzf-tab:complete:*:argument-1' fzf-preview
export LESSOPEN='|/path/to/lessfilter.sh %s'

However, pictures previews aren't working with chafa when using kitty terminal (and default preview format).

From man chafa:

       -f, --format format
           Set output format; one of [iterm, kitty, sixels, symbols]. The default is iterm, kitty or sixels if the connected terminal
           supports one of these, falling back to symbols ("ANSI art") otherwise.

Since I'm using kitty, running chafa without any argument defaults to -f kitty, which doesn't seem to work:

image

It works fine if run directly in terminal with:

❯ chafa 01.jpg

image

If using

chafa -f symbols "$1"

in the script, it works too, but the preview quality is very bad of course:

image

Environment:

❯  zsh --version
zsh 5.9 (x86_64-pc-linux-gnu)

❯  kitty --version
kitty 0.25.2 created by Kovid Goyal

❯  chafa --version
Chafa version 1.12.3

Am I missing something or is this a fzf limitation?

Thanks.

xfzv commented 2 years ago

I've been playing around with ytfzf:

image

I tried to replace this line from /usr/bin/ytfzf:

chafa)
    printf '\n'
    command_exists "chafa" || die 3 "\nchafa is not installed\n"
-   chafa --format=symbols -s "$((width-4))x$height" "$thumb_path" ;;
+   chafa --format=kitty -s "$((width-4))x$height" "$thumb_path" ;;

and got the exact same issue (wall of random characters instead of image preview) when using ytfzf -t --thumb-view=chafa.

I also noticed these lines and somewhat got it working by replacing (in my lessfilter.sh script)

elif [[ "$CATEGORY" == "image" ]]; then
-    has_cmd chafa && chafa "$1"
+    kitty +kitten icat --clear --transfer-mode file
+    kitty +kitten icat --transfer-mode file "$1"
    has_cmd exiftool && exiftool "$1"

but of course it's very buggy since I removed the --place option and maybe the other options aren't optimal either. The image is displayed full size instead of matching fzf preview window size and the preview stays displayed when moving with arrow keys while in fzf.

So based on what I'm seeing with ytfzf, I guess chafa doesn't play well with fzf and --format kitty. The best way would be to mimic ytfzf implementation with kitty +kitten icat and ueberzug to determine thumbnail position and size.

Maybe someone could help in that regard.

justchokingaround commented 2 years ago

any updates on this?

xfzv commented 11 months ago

@justchokingaround fzf 0.43 now supports Kitty image protocol. It works fine but I'm having some issues with the placement. Not sure how to integrate it in my lessfilter.sh either, I wonder if it could completely replace chafa.

justchokingaround commented 11 months ago

yes, i actually saw the announcement, however even after building from source, the example code didn't seem to work for me in the kitty terminal

xfzv commented 11 months ago

yes, i actually saw the announcement, however even after building from source, the example code didn't seem to work for me in the kitty terminal

I couldn't get it to work either, but these worked for me:

justchokingaround commented 11 months ago

oh nice, thank you, i'll check another day, but this is pretty cool. i think it's a big step forward that fzf has native image support, hopefully this means sixel is possible in the future :pray:

DivineMK commented 5 months ago

fzf now supports image

xfzv commented 5 months ago

@DivineMK thanks for the heads-up. I'm using Kitty and the following works fine in the terminal:

fzf --preview 'fzf-preview.sh {}'

image

but it doesn't work well in the lessfilter script on my end:

# lessfilter.sh

mime="$(file -bL --mime-type "$1")"
category="${mime%%/*}"

# [...]
elif [[ "$category" == "image" ]]; then
  fzf-preview.sh "$1"

image

Any idea?

DivineMK commented 5 months ago

I use it normally. Did you make sure fzf-preview.sh is available globally (putting in $PATH)? Also update fzf and kitty just in case.

xfzv commented 5 months ago

Did you make sure fzf-preview.sh is available globally (putting in $PATH)

Yes, it's in $PATH. Using absolute path instead of fzf-preview.sh doesn't make any difference.

Also update fzf and kitty just in case.

I'm using latest version for both:

% kitty --version
kitty 0.33.1 created by Kovid Goyal

% fzf --version
0.49.0 (62963dc)
DivineMK commented 5 months ago

May I see the whole .lessfilter? Maybe you happen to have other commands for images like chafa as well?

xfzv commented 5 months ago

Also occurs with stripped down lessfilter.sh:

#!/usr/bin/env bash

mime="$(file -bL --mime-type "$1")"
category="${mime%%/*}"

if [[ "$category" == "image" ]]; then
  fzf-preview.sh "$1"
fi
DivineMK commented 5 months ago

From lesspipe documentation you need to use .lessfilter or lessfilter not lessfilter.sh. Or you can edit lesspipe.sh directly but it is not recommended. Edit: I realized you have it working with other functionalities like preview directories so this is not the problem I guess but maybe give it a shot :face_with_head_bandage: ?

xfzv commented 5 months ago

Edit: I realized you have it working with other functionalities like preview directories so this is not the problem I guess but maybe give it a shot 🤕 ?

Yes, the script works just fine apart from that. I'm using:

export LESSOPEN="|lessfilter.sh %s"

as mentioned in the wiki. lessfilter.sh path is is added to $PATH before setting LESSOPEN variable.

DivineMK commented 5 months ago

If running fzf-preview.sh in terminal works then I don't know how to help :cry:. Did you try with different images as well?

xfzv commented 5 months ago

If running fzf-preview.sh in terminal works then I don't know how to help

No worries, thanks for the suggestions! I don't know either. Image previews with lf and Kitty protocol are working just fine too.

Did you try with different images as well?

Yes, multiple formats, same behavior.

Chrispycode commented 4 months ago

Is this still an Issue with kitty, I got it to work with previews like this: https://gist.github.com/Chrispycode/b9a3180ed5f01c4df4c765221d03b8b3

Screencast from 2024-05-21 20-00-40.webm

xfzv commented 4 months ago

@Chrispycode Thanks for the gist.

Can confirm it works for me as well after replacing this line from fzf-preview.sh:

- kitty icat --clear --transfer-mode=memory --unicode-placeholder --stdin=no --place="$dim@0x0" "$file" | sed '$d' | sed $'$s/$/\e[m/'
+ kitty icat --silent --clear --transfer-mode=memory --stdin=no --place="$dim@0x0" "$1" >&2

However, this "$file may be a binary file. See it anyway?" message appears behind the picture (can be seen in your video too):

image

If the picture is wide enough, it's hidden, but if it's not, then it's visible.

Interestingly, I have no issue whatsoever with images preview with ctrl+t using:

export FZF_CTRL_T_OPTS="--preview 'fzf-preview.sh {}'"

Can you get images preview working with your current setup but using fzf-preview.sh instead?

elif [ "$category" = image ]; then
  fzf-preview.sh "$1"

instead of

elif [ "$category" = image ]; then
  kitty icat --silent --clear --transfer-mode=memory --stdin=no --place="$dim@0x0" "$1" >&2

You can get fzf.preview.sh here

Chrispycode commented 4 months ago

The fzf-preview.sh also only works if I add >&2 and then it also returns the message but beneath the image.

elif [ "$category" = image ]; then
  # kitty icat --silent --clear --transfer-mode=memory --stdin=no --place="$dim@0x0" "$1" >&2
  "$DOTS/fzf-preview.sh" "$1" >&2

Screenshot from 2024-05-21 23-07-51

xfzv commented 4 months ago

Same here, not sure why. Also wondering why

export FZF_CTRL_T_OPTS="--preview 'fzf-preview.sh {}'"

works just fine without any tweak.

Thank you for your time!

Chrispycode commented 4 months ago

I got it to work now without the message, seems to be a problem with the LESSOPEN example.

zstyle ':fzf-tab:complete:*:*' fzf-preview '$DOTS/fzf-preview.sh ${(Q)realpath}'
xfzv commented 4 months ago

I got it to work now without the message, seems to be a problem with the LESSOPEN example.

zstyle ':fzf-tab:complete:*:*' fzf-preview '$DOTS/fzf-preview.sh ${(Q)realpath}'

Good catch, it solves the image previews for me too. But this completely bypasses lessfilter.sh for other file types and directories unfortunately.

What seems to cause the issue is to run fzf-preview.sh from lessfilter.sh or using the image preview part.

Maybe switching to

zstyle ':fzf-tab:complete:*:*' fzf-preview '/path/to/fzf-preview.sh ${(Q)realpath}'

and customizing fzf-preview.sh to re-use some elements of lessfilter.sh is a good approach?

Chrispycode commented 4 months ago

yes I only replaced the first case in the fzf-preview.sh for the preview of directories with

if [[ ! $type =~ image/ ]]; then
  if [[ $type =~ =binary ]]; then
    ls -1lah --color "$1"
    exit
  fi
xfzv commented 4 months ago

Maybe switching to

zstyle ':fzf-tab:complete::' fzf-preview '/path/to/fzf-preview.sh ${(Q)realpath}'

and customizing fzf-preview.sh to re-use some elements of lessfilter.sh is a good approach?

Can confirm this approach works fine on my end.

Maybe the wiki should be edited to suggest using fzf-preview instead of less? It seems more reliable, at least for image previews.

Chrispycode commented 4 months ago

I also had the same issue with bat previews where it only shows the first line of the file when using less btw.