KillTheMule / nvim-rs

A rust library for neovim clients
Apache License 2.0
216 stars 24 forks source link

Support for different runtimes conflicts with embedding neovim #12

Closed KillTheMule closed 3 years ago

KillTheMule commented 4 years ago

cc @vhakulinen, @Kethku

The reason is that for embedding neovim we need to get the child neovim's Stdin/Stdout as AsyncWrite/AsyncReaders, and those types are only provided tokio. I've learned today that those types cannot be used with a different runtime. The same seems to go e.g. for the types provided by async_std, but each one from that has something equivalent in tokio.

So the state of this lib (referring to the futures branch is that:

The last bullet point is a real pity, since GUIs need to embed neovim, and some prominent ones use gtk-rs, which brings it's own runtime. As far as I can see though, it can "only" run futures, but does not provide any IO types to use for the communication, or spawn neovim as a subprocess so we can get handles to stdio in an async fashion.

Question 1: Am I mistaken? If so, this could still be made to work with glib. Question 2: As a workaround, we could try to spawn a dedicated IO thread that provides an async shim. Not sure how complicated that is, but is this even a feasible workaround?

vhakulinen commented 4 years ago

I managed to get nvim-rs to run on top of gtk's io loop (in gnvim). All I had to do was to create similar compatibility layer for gtk's types as you already have for tokio: https://github.com/vhakulinen/gnvim/blob/88853ddc6cbee5ea15db3eb88eb06d055f95ddf6/src/nvim_gio/compat.rs. Then, it was just matter of creating the handler and spawner (both implemented in a same struct): https://github.com/vhakulinen/gnvim/blob/88853ddc6cbee5ea15db3eb88eb06d055f95ddf6/src/nvim_bridge/mod.rs#L898-L983.

This took like 12 hours of type golfing to get everything just right. I ended up relaying a runtime ThreadGuard (which was already implemented in gnvim), because gtk objects aren't Send.

KillTheMule commented 4 years ago

Awesome! I've been experimenting with using a local spawn to accomodate for the single-threaded runtime, but it's pretty ugly, and I'm not even sure I'd get it to work. I'll probably look into it at a later point, but for now I guess I'll integrate your code ;)

KillTheMule commented 3 years ago

So the situation is that you can use any runtime you want, provided you can get something that implements AsyncRead/AsyncWrite. We're providing convenience function for tokio and async-std (glib is planned).

Incompatibility of the feature flags is not nice, but further discussion should be in https://github.com/KillTheMule/nvim-rs/issues/36.