neovim icon indicating copy to clipboard operation
neovim copied to clipboard

:term should forward unknown sequences to host

Open chemzqm opened this issue 8 years ago • 42 comments

iTerm2 version 3 beta support show image inside terminal with command like imgcat, but the image could not be seen with that command inside terminal of neovim. That would also be cool if neovim support show image in buffer with an api .

chemzqm avatar Feb 25 '16 17:02 chemzqm

Some people are already doing this, see https://github.com/neovim/neovim/issues/4056

justinmk avatar Feb 25 '16 17:02 justinmk

@justinmk I'm using latest neovim, but I can't get any image ouput with command imgcat inside the terminal of neovim

chemzqm avatar Feb 26 '16 06:02 chemzqm

It looks like imgcat is using a custom DCS 1337. I am guessing that is not a code that is recognized by libvterm (@leonerd can you confirm), but on the other hand we should forward it to iTerm2, but maybe we aren't?

~~Clearly there is some seequence that is recognized by libvterm to display images as demonstrated by #4056. imgcat could be modified to emit those codes instead?~~

justinmk avatar Feb 26 '16 15:02 justinmk

@justinmk IIRC the method in #4056 does not use terminal codes. It instead calls a image display program that displays the image at the requested location.

That's probably why it doesn't output the image at the correct location when inside neovim. Because it assumes that it is using the full terminal window. So it will not work with splits and so on.

I guess that the iTerm2 codes will eliminate this problem because the terminal will then know where to put the image depending on where it reads the DCS 1337 code

DarkDefender avatar Feb 26 '16 15:02 DarkDefender

imgcat can work well in vim but in neovim it prints chars @justinmk

liubog2008 avatar Jan 16 '19 15:01 liubog2008

~It looks that vterm_state_set_unrecognised_fallbacks is not called though libvterm is updated?~

liubog2008 avatar Jan 16 '19 16:01 liubog2008

Is there any update to this issue? It would be nice to have this feature.

I understand that this is related to forwarding unknown sequences to iTerm2. However, my understanding is that sixel support in libvterm is also an option for displaying images, right? I'm not familiar with the internals/architecture, but is it still the case that neovim's internal screen is composed of unicode characters of fixed size and hence will never be able to display images [1]? Is this unlikely to change?

Screen Shot 2019-06-20 at 1 30 22 AM

With iterm2 3.0.0 beta it is now possible to display sixel images as well [2]. In the screenshot above on the left I'm able to display images using imgcat (iTerm2 escape codes) and using cat (SIXEL).

One valid use case for this feature is that these can be powerful tools for visualization / exploring data in scientific computing from the terminal interactively. It appears that tmux is not planning to support this [3], so neovim's terminal would make a highly appealing option to interactively run code and visualize data, all from the command line.

It'd be really cool to have one or both methods supported in neovim. Thoughts?

[1] https://github.com/neovim/neovim/issues/4500 [2] https://gitlab.com/gnachman/iterm2/issues/3543#note_157693474 [3] https://github.com/tmux/tmux/issues/1613

kdheepak avatar Jun 20 '19 07:06 kdheepak

but is it still the case that neovim's internal screen is composed of unicode characters of fixed size and hence will never be able to display images.

"never" is the wrong word, the question is if it is worth the effort or not. Does the sixel state of a single cell fit into 28 ASCII chars, or something like that? Then we could add support without changing the screen representation fundamentally.

bfredl avatar Jun 20 '19 08:06 bfredl

I'm not sure what you mean by "sixel state" or "a single cell"? I'm also just learning about all of this, so take it for what it is worth. The following information is based on the vt100 reference manual [1].

A single "sixel" encodes information about a six pixel high * one pixel wide column. So each sixel in binary is encoded as a single 6-bit number. This is converted to ascii such that every sixel is within the printable character range of the ASCII character set.

Wouldn't just passing on sixel information to iTerm2 do the trick?

[1] https://www.vt100.net/docs/vt3xx-gp/chapter14.html

kdheepak avatar Jun 20 '19 10:06 kdheepak

Other terminals also appear to be using their own format for displaying images. Kitty for example also has similar escape sequences to iTerm2: https://sw.kovidgoyal.net/kitty/graphics-protocol.html

kdheepak avatar Jun 20 '19 10:06 kdheepak

A single "sixel" encodes information about a six pixel high * one pixel wide column. So each sixel in binary is encoded as a single 6-bit number. This is converted to ascii such that every sixel is within the printable character range of the ASCII character set.

I understood so much. But how many sixels wide is a text cell defined to be? how many "sixel lines" per one text line? Or if this is not defined and varies among terminals/configs, can it be detected somehow?

Wouldn't just passing on sixel information to iTerm2 do the trick?

To keep the vterm in a consistent state we need at least to know how large the sixel area is. But I think users expect if they scroll/rezise the terminal, or display it in a different window, the graphics will be retained, and thus we would like to store the state in our internal screen buffers.

bfredl avatar Jun 20 '19 10:06 bfredl

I’ll comment since #11282 was marked a dupe of this. I am not interested in images so much as other features iterm2 exposes via these codes.

Please consider passing these codes through even if there are questions about the image support since that’s only one of the ways they are used.

nall avatar Oct 25 '19 04:10 nall

Although dithered, you can use asciimatics to view a dithered image in a neovim terminal or tmux:

https://stackoverflow.com/a/59223021/26510

bradparks avatar Dec 26 '19 15:12 bradparks

Any progress or decisions made on this? Adding my intended use case just in case that helps tip the scale:

  • images (specifically graphs/plots) in neovim's terminal would go a long way to using neovim as a python IDE for machine learning.

ElPiloto avatar Oct 10 '20 21:10 ElPiloto

Also curious about this. Could help to implement GUI elements for neovim.

yatli avatar Oct 13 '20 09:10 yatli

It is possible to display images by disabling embedded libterm during build with -DUSE_BUNDLED_LIBVTERM=OFF.

tejasvi avatar Feb 12 '21 11:02 tejasvi

it requires this patch tho https://github.com/arakiken/libvterm/commit/2500d7ad1c7f74162d70e3089fc95934044b8759

@leonerd does it look like something that could be included upstream?

bfredl avatar Feb 13 '21 09:02 bfredl

It is not working with iTerm2: image

Without this version of libvterm it wouldn't even show those question marks, but now that I installed the sixel branch of arakiken's version of libvterm it shows these question marks

sassanh avatar Feb 13 '21 10:02 sassanh

Image support would be awesome. It seems the issue title is a bit of a misstatement, thought: just forwarding unknown sequences to host would not make for great support, then scrollback, windows and views etc will have no chance of working correctly. It looks like libvterm and neovim need to support the image protocols for terminals explicitly (and unofficial libvterm patches for this are posted in earlier comments in this issue). Issue #4500 has a more specific target and is sixel-specific, but any image protocol would be a good start.

bluss avatar May 22 '21 10:05 bluss

Has arakiken's patch been merged into upstream libvterm yet? There is a build of neovim at nat-chan/Neovim-DRCS-SIXEL-dtach that uses that patch and shows sixels working

starptr avatar Jul 21 '21 20:07 starptr

What's the overall status here then? The original subject is about forwarding unrecognised sequences - I'm fairly sure libvterm already has facility to do that now. Is there something still missing in it? If so let me know and I can add it.

If not, and that ability is there now perhaps we can close this issue, in favour of a different one discussing particular things to be handled..?

leonerd avatar Sep 01 '22 21:09 leonerd

Thanks for the update! Are these facilities documented somewhere? How can I learn about it?

sassanh avatar Sep 02 '22 10:09 sassanh

Are these facilities documented somewhere? How can I learn about it?

The VTermStateFallbacks structure in include/vterm.h

leonerd avatar Sep 02 '22 10:09 leonerd

The typical use case mentioned here was imgcat. Assuming that works now, we can close this. Thanks @leonerd

justinmk avatar Sep 03 '22 02:09 justinmk

@justinmk I tried imgcat in terminal buffers with both v0.7.2 and the nightly build, but I think it still doesn't work.

jaekyeom avatar Sep 03 '22 05:09 jaekyeom

I registered this osc callback:

static int oscCallback(const char *c, size_t s, void *a)
{
  int fd;
  fd = open("/tmp/log", O_WRONLY | O_CREAT | O_APPEND, 0644);

  write(fd, "\e]", 2);
  write(fd, c, s);
  write(fd, "\7", 1);

  close(fd);
  return 1;
}

VTermParserCallbacks callbacks = {
  .osc = oscCallback,
};
...
  vterm_state_set_unrecognised_fallbacks(state, &callbacks, NULL);

then I was able to do these in Neovim terminal and see the results in another normal iTerm2 terminal by running tail -f /tmp/log in it:

  1. Cursor shape changes
  2. Changing iTerm 2 title

Everything worked as expected when I cat /tmp/log except imgcat, oscCallback is not triggered when imgcat runs. Seems like libvterm is doing its job. But when instead of fd I wrote to stdout, things got ugly and part of the prompt rendered out of the terminal window in another buffer. I guess in Neovim realm, communicating with the underlying terminal Is not as easy as directly writing to stdout.

We may be able to get rid of the virtual cursor and let the running application (bash, fish, node, etc) directly set the cursor shape by communicating with the underlying terminal emulator.

Also it may break some people's workflow, commands that were ignored in the past, now reach the underlying terminal emulator, there may be resize commands, setting title commands, setting working directory commands, etc so it will be a breaking change (someone may have an iTerm2 script that does something based on the title of the terminal and doesn't expect Neovim's embedded terminal change that, etc) so we may want to start with a feature flag that is disabled by default.

Note for @leonerd: imgcat did not work as none of the fallback callbacks were called after running imgcat, I'm going to read the code to find out what are the conditions for calling osc callback and which condition is not satisfied with imgcat output. Please let me know if you have any suggestions.

sassanh avatar Sep 05 '22 13:09 sassanh

I have no idea what imgcat is. Is it supposed to be outputting OSCs? I'll need some more reference to understand all this.

leonerd avatar Sep 05 '22 13:09 leonerd

Sure, this is the script: https://iterm2.com/utilities/imgcat Yes it is supposed to be outputting OSCs, I attach a sample output here

sassanh avatar Sep 05 '22 13:09 sassanh

I don't know whether https://github.com/eddieantonio/imgcat is the same one, but for that I notice that it only outputs OSCs when talking to a real iTerm2. When talking to some other terminal it just emits a grid of Unicode half-linedrawing characters, with foreground + background colours set, allowing it to paint pixels in colours regardless of what the terminal is.

How did you capture that sample output? Is it captured from within the shell inside nvim's :term?

leonerd avatar Sep 05 '22 13:09 leonerd

I ran this command in a terminal opened by :term in Neovim:

imgcat "<IMAGE_PATH>" > /tmp/sample_imgcat_output.osc

sassanh avatar Sep 05 '22 14:09 sassanh

Ah wait a second - the oscCallback function you defined earlier isn't even compatible with the required signature. The fallbacks structure requires:

  int (*osc)(int command, VTermStringFragment frag, void *user);

following the VTermStringFragment API. Perhaps that's the problem here?

leonerd avatar Sep 05 '22 15:09 leonerd