-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Images preview support for terminals witch sixel #2544
Comments
I was just about to ask the exact same thing. @junegunn, would it be possible? |
Since wayland is lacking something like ueberzug, I'm currently using sixels on foot in wayland to display images in a terminal. Therefore I'm also interested in this. I've never done any golang programming, but looked into the preview window code and noticed that currently Device Control ANSI codes ( Since sixel data is often an enormous control sequence, painting any pixel multiple times, it may not be desirable in something focused on speed like fzf, I'd like to hear whether this feature would even be merged if somebody implements it. Despite that I thought about getting it to work. The problem:The length and format of a string with sixel data is unpredictable (depends on console, font and font size) and introduces one or more newlines since any text printed after a sixel will be put one line below the last pixel. How to go about it:Any sixel data must therefore be parsed by fzf using (potentially non portable) xterm specific control sequences ( Is it worth it?If I'm not missing any easy workaround, this is a lot of work. Please correct me if I have misunderstood parts of fzf, or of the sixel graphics escape codes! |
If you use private mode 8452, the cursor will be left to the right, on the last line of the sixel, instead of on a newline.
In my benchmarks of foot, it was pretty clear that the bottleneck is the producer. I.e. the one encoding the sixel. Sending the escape and parsing it in the terminal is nowhere near as demanding. I have seen mpv, and notcurses, peg one or more cores while foot is using ~20-25% of a single core. Thus, one might want to consider pre-generating the sixel escapes, and/or cache already rendered sixels.
An alternative, that doesn't read stdin, is to use the |
@junegunn any thoughts about this issue? |
I'm also interested in ways to do that. |
While sixel support would be amazing, just a sidenote for people who don't not know it: ANSI based terminal rendering of images is pretty decent meanwhile - and works in fzf previews w/o problems: https://hpjansson.org/chafa/gallery/ |
As now ueberzug is not maintained I think it's a great time to rethink this issue. The sixel implementation would be really nice. |
Is there any thoughts given on this? |
@PJungkamp summarized it well above. I'm not familiar with the spec so I don't even know if it's possible to implement it inside fzf, and even if it is, it's going to be a hell lot of work. So I'm not interested in pursuing the goal, but feel free to send a pull request if you can pull it off. |
I wish you would revisit this. In terms of the spec, it's not terribly complicated. It's an escape sequence, followed by a prefix, followed by pixel data encoded in a particular way. The main thing to properly forward the escape sequences to the terminal, and to not mangle the pixel data. The terminal does the work of rendering. They're drawn in place at the cursor position. A lot of terminal emulators support full-color sixel graphics now. The more people use it, the more other emulators are likely to adopt it as well. The thing is, it's based on an actual hardware graphics terminal from the 1980s, so it's well-established. I am not familiar with how FZF's preview window works, but some support for this would really expand the reach of what FZF can do. |
After adding Kitty graphics support with a minimal code change using pass-through mechanism, @aeghn made me realize a similar approach could be taken to support Sixel as well (#3479 (reply in thread)). I'm experimenting with the idea in b1a0ab8. Haven't decided if I'm going to keep it. It works fine with a single Sixel image but it's unlikely to work well with anything beyond that. |
FINALLY!! |
So do you have plan to add features like displaying text alongside or scrolling along with the image? (This video is copied from #3479 from my fork) preview.webmI think it would be very cool if we could scroll the images in the fzf preview window (like pdf preview?). If you decide to keep this option, I will be very happy to continue exploring things about sixel to work with fzf. |
Only if the amount of the required code is small. After all, this is a "preview" window rather than a full-fledged viewer. I would advise users to launch a proper viewer program, examine the contents, and come back to fzf using FWIW, it is currently possible to do those things with Kitty graphics protocol thanks to its "placeholder" mechanism. There are several competing protocols for image support on the terminal. Honestly, I have little experience with them, but for now, I prefer Kitty protocol because it's noticeably faster than Sixel, and it works on tmux, unlike Sixel. |
Thank you for such a wonderful app and your great effort on the features which would help people living in terminal. |
tmux officially supports sixel when compiled with |
I think @junegunn is referring to the default setting, as someone pointed out in discussion #3479 (comment). |
I am using sixel in fzf from a few days and it has been working awesomely fine in tmux. |
Progress: * Sixel image can now be displayed with other text, and is scrollable * If an image can't be displayed entirely due to the scroll offset, fzf will render a wireframe to indicate that an image should be displayed * Renamed $FZF_PREVIEW_{WIDTH,HEIGHT} to $FZF_PREVIEW_PIXEL_{WIDTH,HEIGHT} for clarity * Added bin/fzf-preview.sh script to demonstrate how to display an image using Kitty or Sixel protocol An example: ls *.jpg | fzf --preview='seq $((FZF_PREVIEW_LINES*9/10)); fzf-preview.sh {}; seq 100' A known issue: * If you reduce the size of the preview window, the image may extend beyond the preview window
So here's some progress: sixel-scroll.movI have tried to implement the image placement with a minimal amount of Sixel-related code. The code is not polished and it has some issues and limitations some of which are not easy to fix. But it works on a basic level. |
Hey @junegunn, thank you very much for this! Really great. I've faced a few issues however (running on Arch, I3, xterm 388, fzf-git):
EDIT: reducing the width (say
|
Just to be sure, are you testing the latest revision? The previous commit renamed |
Using the latest rev now. Removed I also noticed that sometimes (specially when the previous file was a text file, tough also happens with images) the preview of the previous file is not properly cleared. Btw, the whole thing feels snappier and less resource intensive now. Switched to |
@leo-arch May I ask if you could upload those images? |
Tried with EDIT: I still need to subtract 1 from FZF_PREVIEW_LINES to prevent the interface from becoming crazy. Here's my chafa command: chafa -f sixel -s ${FZF_PREVIEW_COLUMNS}x$((FZF_PREVIEW_LINES - 1)) {} This is required when you add a border to the preview window, say |
It looks like we were not on the same page. Reverted the height calculation. Use
I can't reproduce the problem. |
Hey, not a big deal anyway @junegunn, but it's definitely there (at least for me). |
@leo-arch I can't reproduce the problem on my iTerm2 with any type of border. # Press space to change the border style
FZF_DEFAULT_OPTS= fzf --preview 'fzf-preview.sh {}' --bind 'space:change-preview-window(border-left|border-top|border-bottom|border-horizontal|border-vertical|border-double|border-block|noborder)+clear-screen+refresh-preview' Please post a screenshot (or preferably a screencast) of the situation. |
@leo-arch Oh wait, I'm noticing a rendering problem when I move between the selections. |
I see the pattern. The issue arises when there is no border at the bottom.
|
This is the main problem I have run into in my fork previously, I just remove the bottom booder and decrease the image size. Hope you could find the cause and solve it. chafa "$1" -f sixel -s $((${FZF_PREVIEW_COLUMNS}-2))x$(($FZF_PREVIEW_LINES/9*10)) --animate false |
Hmm, it looks like there's no simple solution to the problem. The whole screen shifts up by a row as soon as fzf passes the Sixel image data to the underlying terminal. The situation is also reproducible without using fzf. # The image is shifted up. The cursor is on the last line which is empty.
chafa -f sixel -s ${COLUMNS}x${LINES} long-image.jpg; sleep 5
This might be the only solution at hand, but it's not ideal because fzf can use the last line for other text data just fine. So we're reporting an incorrect value just for Sixel. # Make sure that the preview window covers the last line
fzf --no-margin --no-padding --no-border --preview-window border-none --preview 'echo -n "$FZF_PREVIEW_LINES / ";seq $FZF_PREVIEW_LINES' |
Agreed. So, what about exporting an environment variable and then testing against it to construct the chafa command in if [ -n "$FZF_PREVIEW_NO_BOTTOM_BORDER" ]; then
chafa -f sixel -s "${FZF_PREVIEW_COLUMNS}x$((FZF_PREVIEW_LINES - 1))" "$file"
else
chafa -f sixel -s "${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}" "$file"
fi I know, it's far from elegant and hacky, but should work. Another alternative (cleaner but less exact) would be to always perform the subtraction: it's not even a noticeable loss after all. |
When a Sixel image touches the bottom of the screen, the whole screen scrolls up one line to make room for the cursor. Add an ANSI escape code to compensate for the movement. Unfortunately, the movement of the screen is sometimes noticeable. fzf --preview='fzf-preview.sh {}' --preview-window border-left
278dce9 fixes the issue, at least on iTerm2 where I tested it. As noted in the commit message, the momentary movement of the screen is sometimes noticeable, but I can't think of a better solution. |
Do you have any idea under what conditions this happens? |
Some terminals like Wezterm leave the cursor on the last row of a sixel to avoid this behavior. Because of that, the last commit 278dce9 breaks the UI on Wezterm when using I think the easiest solution to this is to just use the shorter preview window and leave room for the cursor. Another solution is to use |
Terminals _used to_ leave the cursor under the sixel (thus causing scrolling).
Since it was discovered that this isn't what the real hardware did, terminals have started working towards leaving the cursor on the last row instead. Not sure if all terminals have gotten the memo or not though... I know xterm and foot do this.
So, hopefully this is a problem that will fix itself in the future...
It should also be noted that there may still be some confusion; some terminals leave the cursor on the row containing the bottom pixel of the last sixel row, while others leave it at the row containing the upper pixel of the last sixel row. This matters when the last sixel row spans multiple text rows. Real hardware did the latter, I believe.
|
Huh, that was what I was worried about, the inconsistencies between the terminal emulators. I'm going to have to revert the patch then. I was not completely happy with the result anyway; while scrolling up fixes the whole viewport, the top line is lost. |
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.
21ab64e is another take on the issue. We export $FZF_PREVIEW_TOP to the preview command so that it can determine whether it should subtract 1 from $FZF_PREVIEW_LINES or not. Removed the scrolling trick.
|
It works great now. Thanks @junegunn! |
Thank you for your help and feedback. I'm going to close this thread. Please open a new one if you encounter any problems or have any suggestions. |
Hello. Is it possible to implement images preview support for terminal which support sixel?
The text was updated successfully, but these errors were encountered: