image.nvim icon indicating copy to clipboard operation
image.nvim copied to clipboard

Is sixel is in Consideration?

Open niksingh710 opened this issue 2 years ago • 22 comments

As I remember earlier sixel was mentioned in README for future but now I guess it is removed.?

niksingh710 avatar Oct 23 '23 04:10 niksingh710

I think you are talking about this plugin: https://github.com/samodostal/image.nvim

Which actually has the same name but developed completely separately. And in the world of lazy.nvim, I'm not sure if it is possible to install both due to name collision.

pysan3 avatar Oct 23 '23 04:10 pysan3

I think you are talking about this plugin: samodostal/image.nvim

Which actually has the same name developed completely separately. And in the world of lazy.nvim, I'm not sure if it is possible to install both due to name collision.

nop, i guess i do remember it was for this one.

here check this commit https://github.com/3rd/image.nvim/blob/e82623458a08d9f43a67ef84e34dacf5c19f007b/README.md it contains sixel

niksingh710 avatar Oct 23 '23 04:10 niksingh710

Oh, sorry :sweat_smile:

pysan3 avatar Oct 23 '23 04:10 pysan3

Hey, the answer is yesss! Didn't get to it yet, but it's definitely comming.

There's already something like this, I need to reach out to @bytesnake as they've done a lot of work on this already.

It's a funny story, I made the vimage experiment as well, a few years ago #nevergiveup :joy:

https://www.reddit.com/r/vim/s/L5llxvrl9s

3rd avatar Oct 23 '23 06:10 3rd

Sixel support will be amazing

r3k2 avatar Dec 09 '23 17:12 r3k2

Considering Sixel support would be beneficial as it opens compatibility with multiple terminal emulators beyond Kitty, such as iTerm2, Alacritty, wezterm, and others. I primarily use iTerm2, so I was contemplating the iTerm Image Protocol, but if Sixel support is achieved, it seems like a comprehensive solution.

daiki0381 avatar Dec 15 '23 05:12 daiki0381

+1, kitty protocol only works on kitty. Sixel is the industry standard.

Zeioth avatar Jan 19 '24 14:01 Zeioth

Sixel support landed in tmux master recently. I concur that would be the bees knees.

stephenprater avatar Jan 22 '24 09:01 stephenprater

@stephenprater this is amazing news!

3rd avatar Jan 22 '24 10:01 3rd

Have been using it for a long time and it is stable. Also used it with fzf as it now also got sixel.

niksingh710 avatar Jan 23 '24 05:01 niksingh710

Any news on this? I have FOOT terminal and LF with other parts of my GNU/Linux system all with sway/Wayland and Sixel only piece missing is Neovim with sixel.

r3k2 avatar Feb 28 '24 21:02 r3k2

Any news on this? I have FOOT terminal and LF with other parts of my GNU/Linux system all with sway/Wayland and Sixel only piece missing is Neovim with sixel.

I'm in the same boat. Sixel is the way to go here where more terminal emulators support it than any other protocol that I know of. Now that tmux supports it and it also propagates over ssh, I think it would provide the most cohesive experience for remote development workflows.

This does the job (credit to the original author - my fork fixes building on more up-to-date toolchains), but it is quite taxing on system resources.

a-priestley avatar Mar 18 '24 11:03 a-priestley

There's a new lua plugin to bring sixel to neovim: sixelview.nvim.

I'm the author of neither of these plugins but I hope someone can step up to migrate this plugin into image.nvim/image/backends.

pysan3 avatar Mar 18 '24 12:03 pysan3

I had a go at merging the functions in sixelview.nvim into a something that resembles what is done for the ueberzug here [1]. There are quite a bit of issues:

  • ~~Image has a very large chance (>80%) of not rendering in full. This was also an issue in sixelview, so there might be additional parsing we need to do to the sixel string before we can run the renderer. (I'm also no sure why the display is inconsistent)~~ (Edit: fixed in latest commit)
  • I'm not sure how to have a performance way of clearing sixel image in neovim. The only way I know of is to run :mode. (Edit I'ved tried to create a dummy sixel image on the fly, but that breaks the rendering completely.)

If someone is more knowledgeable in how to process sixel output, let me know what I might proceed.

[1] https://github.com/yimuchen/image.nvim/blob/sixel_support/lua/image/backends/sixel.lua

yimuchen avatar May 16 '24 15:05 yimuchen

Perhaps this contribution can shed light on implementing sixel in this plugin. I recently developed a preview that supports sixel for fzf-tab, I leave the code here. The function is called draw and it works perfectly.

#!/usr/bin/env sh

CELL_HEIGHT=22
CELL_WIDTH=12

HEIGHT=$(($FZF_PREVIEW_LINES * $CELL_HEIGHT))
MAX_WIDTH=$(($FZF_PREVIEW_COLUMNS * $CELL_WIDTH))

TMP="/tmp/fzf-preview"
LTMP="$HOME/.cache/fzf-preview"
CACHEFILE="$TMP/$(echo "$1" | base64).png"
LCACHEFILE="$LTMP/$(echo "$1" | base64).png"

maketemp() {
	[ ! -d "$TMP" ] && mkdir -p "$TMP"
	[ ! -d "$LTMP" ] && mkdir -p "$LTMP"
}

previewclear() {
	printf '\033[2J\033[H' # Clear screen
}

text() {
	bat --pager=never --wrap never --style="changes" --color="always" "$1" -p
}

archive() {
	local filename="$1"
	local extension="${filename##*.}"

	# Determine the tool to use based on the file extension
	case "$extension" in
	zip)
		unzip -l "$filename" | awk 'NR>3 {print $4}'
		;;
	tar | tgz | tar.gz)
		tar -tf "$filename"
		;;
	tar.bz2 | tbz2)
		tar -tjf "$filename"
		;;
	tar.xz | txz)
		tar -tJf "$filename"
		;;
	rar)
		unrar l "$filename" | awk '/^[ ]+[0-9]/ {print $NF}'
		;;
	7z)
		7z l "$filename" | awk 'NR>18 {print $NF}'
		;;
	*)
		echo "Unsupported file type: $extension"
		;;
	esac
}

draw() {
	dimensions=$(identify -format "%wx%h" "$1")
	original_width=$(echo $dimensions | cut -d'x' -f1)
	original_height=$(echo $dimensions | cut -d'x' -f2)
	aspect_ratio=$(echo "scale=4; $original_width / $original_height" | bc)
	WIDTH=$(echo "scale=0; $HEIGHT * $aspect_ratio / 1" | bc)
	if [ "$WIDTH" -gt "$MAX_WIDTH" ]; then
		WIDTH=$MAX_WIDTH
		HEIGHT=$(echo "scale=0; $WIDTH / $aspect_ratio / 1" | bc)
	fi
	img2sixel -w "$WIDTH" -h "$HEIGHT" "$1"
}

image() {
	draw "$1"
}

# https://ffmpeg.org/ffmpeg-filters.html#showspectrum-1
audio() {
	[ ! -f "$CACHEFILE" ] && ffmpeg -loglevel 0 -y -i "$1" -lavfi "showspectrumpic=s=hd480:legend=0:gain=5:color=intensity" "$CACHEFILE"
	draw "$CACHEFILE"
}

video() {
	[ ! -f "$LCACHEFILE" ] && ffmpegthumbnailer -i "$1" -o "$LCACHEFILE" -s 1024 -q 10 &>/dev/null
	draw "$LCACHEFILE"
}

pdf() {
	[ ! -f "$CACHEFILE.png" ] && pdftoppm -png -singlefile "$1" "$CACHEFILE" -scale-to 1024
	draw "$CACHEFILE.png"
}

epub() {
	[ ! -f "$CACHEFILE" ] && epub-thumbnailer "$1" "$CACHEFILE" 1024
	draw "$CACHEFILE"
}

main() {
	previewclear
	maketemp
	mimetype=$(file -b --mime-type "$1")

	case $mimetype in
	application/epub*)
		epub "$1"
		;;
	application/pdf)
		pdf "$1"
		;;
	application/zip | application/x-tar | *rar | application/gzip)
		archive "$1"
		;;
	audio/*)
		audio "$1"
		;;
	image/*)
		image "$1"
		;;
	text/*)
		text "$1"
		;;
	video/*)
		video "$1"
		;;
	inode/directory)
		[ "${1##*/..*}" = "" ] && echo || eza --icons --color=always --tree --level=2 --git "$1"
		;;
	*)
		text "$1"
		;;
	esac
}

main "$1"

CRAG666 avatar Jun 25 '24 03:06 CRAG666

Would love Sixel support. I've taken a crack at it in my own plugin (virt_lines is the most recent branch), but I feel like I've had to do a lot of dirty things to get it to work nicely, namely:

  • I use Konsole+tmux, which isn't as kind as I'd like it to be for Sixels. Screen refreshes use :mode and, if $TMUX is set, detach and immediately reattach the session. This is the cleanest workaround I know of, but causes flashing on lower-end machines.
  • Some applications (looking at you, pexpect) don't like forwarding dimensions available via TIOCGWINSZ to their child pseudoterminals. I came up with a pstree hack to try retrieving them from parent tty devices which seems to do the trick, though.
  • Trying to support Neovim 0.7 as well as 0.10 ~~because my work laptop still runs Ubuntu 22.04~~. The worst polyfill I've had to do here involves disabling virt_lines-style extmarks, since placing that correctly involves going through nvim_win_text_height.
  • Fold keybinds (zf, zo) are rebound to also redraw Sixel extmarks, if necessary.
    • Adding a new virt_lines extmark outside of the plugin misaligns things, though.

I also never looked into how to slice Sixels more cleanly, which would be better than completely rerendering with ImageMagick (like I'm doing). At the very least, I'm wrapping magick directly, instead of depending on the Luarock (#124).

I'm in the same boat. Sixel is the way to go here where more terminal emulators support it than any other protocol that I know of. Now that tmux supports it and it also propagates over ssh, I think it would provide the most cohesive experience for remote development workflows.

This does the job (credit to the original author - my fork fixes building on more up-to-date toolchains), but it is quite taxing on system resources.

That was actually the plugin I was working off of (initially in Python, then in straight Lua). I split out the markdown stuff into another plugin, if you're interested (virt_lines is also the most recent branch there).

queue-miscreant avatar Aug 21 '24 10:08 queue-miscreant

Thanks a lot for the hints! In the first version I used the pstree workaround as well. Sixels are definitely interesting and I'll work towards that, right now the focus is on finishing the first rewrite which has pluggable renderers and will support direct use of the magick CLI as well (will probably be the default since everyone has issues with the rock), and after I'll build a custom fast renderer to move in the direction of a graphics library as well. In the end I'd like to offload the whole render-and-send-to-term-in-whatever-way part to an external program so that the editor only has to manage editor stuff and offload most logic, only providing a proxy maybe for writing to the tty, if even that is needed. Thanks again, will revisit soon!

3rd avatar Aug 21 '24 20:08 3rd