mirror of https://github.com/sgoudham/neovide.git
Remote TCP (#557)
* Remote TCP proof of concept * Allow usage of both tcp and child connections using `TxWrapper` * Tidy up and add flag to set tcp target * Add readme section * Remove the need for `Compat<TxWrapper>` as we are wrapping it anywaymacos-click-through
parent
799e043ffd
commit
d8d6f4eac2
@ -0,0 +1,65 @@
|
||||
//! This module contains adaptations of the functions found in
|
||||
//! https://github.com/KillTheMule/nvim-rs/blob/master/src/create/tokio.rs
|
||||
|
||||
use std::{
|
||||
io::{self, Error, ErrorKind},
|
||||
process::Stdio,
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
io::split,
|
||||
net::{TcpStream, ToSocketAddrs},
|
||||
process::Command,
|
||||
spawn,
|
||||
task::JoinHandle,
|
||||
};
|
||||
|
||||
use nvim_rs::compat::tokio::TokioAsyncReadCompatExt;
|
||||
use nvim_rs::{error::LoopError, neovim::Neovim, Handler};
|
||||
|
||||
use crate::bridge::{TxWrapper, WrapTx};
|
||||
|
||||
/// Connect to a neovim instance via tcp
|
||||
pub async fn new_tcp<A, H>(
|
||||
addr: A,
|
||||
handler: H,
|
||||
) -> io::Result<(Neovim<TxWrapper>, JoinHandle<Result<(), Box<LoopError>>>)>
|
||||
where
|
||||
A: ToSocketAddrs,
|
||||
H: Handler<Writer = TxWrapper>,
|
||||
{
|
||||
let stream = TcpStream::connect(addr).await?;
|
||||
let (reader, writer) = split(stream);
|
||||
let (neovim, io) = Neovim::<TxWrapper>::new(reader.compat_read(), writer.wrap_tx(), handler);
|
||||
let io_handle = spawn(io);
|
||||
|
||||
Ok((neovim, io_handle))
|
||||
}
|
||||
|
||||
/// Connect to a neovim instance by spawning a new one
|
||||
///
|
||||
/// stdin/stdout will be rewritten to `Stdio::piped()`
|
||||
pub async fn new_child_cmd<H>(
|
||||
cmd: &mut Command,
|
||||
handler: H,
|
||||
) -> io::Result<(Neovim<TxWrapper>, JoinHandle<Result<(), Box<LoopError>>>)>
|
||||
where
|
||||
H: Handler<Writer = TxWrapper>,
|
||||
{
|
||||
let mut child = cmd.stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
||||
let stdout = child
|
||||
.stdout
|
||||
.take()
|
||||
.ok_or_else(|| Error::new(ErrorKind::Other, "Can't open stdout"))?
|
||||
.compat_read();
|
||||
let stdin = child
|
||||
.stdin
|
||||
.take()
|
||||
.ok_or_else(|| Error::new(ErrorKind::Other, "Can't open stdin"))?
|
||||
.wrap_tx();
|
||||
|
||||
let (neovim, io) = Neovim::<TxWrapper>::new(stdout, stdin, handler);
|
||||
let io_handle = spawn(io);
|
||||
|
||||
Ok((neovim, io_handle))
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
use pin_project::pin_project;
|
||||
use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use tokio::{
|
||||
io::{AsyncWrite, WriteHalf},
|
||||
net::TcpStream,
|
||||
process::ChildStdin,
|
||||
};
|
||||
|
||||
#[pin_project(project = TxProj)]
|
||||
pub enum TxWrapper {
|
||||
Child(#[pin] ChildStdin),
|
||||
Tcp(#[pin] WriteHalf<TcpStream>),
|
||||
}
|
||||
|
||||
impl futures::io::AsyncWrite for TxWrapper {
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<Result<usize, io::Error>> {
|
||||
match self.project() {
|
||||
TxProj::Child(inner) => inner.poll_write(cx, buf),
|
||||
TxProj::Tcp(inner) => inner.poll_write(cx, buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
||||
match self.project() {
|
||||
TxProj::Child(inner) => inner.poll_flush(cx),
|
||||
TxProj::Tcp(inner) => inner.poll_flush(cx),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
||||
match self.project() {
|
||||
TxProj::Child(inner) => inner.poll_shutdown(cx),
|
||||
TxProj::Tcp(inner) => inner.poll_shutdown(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WrapTx {
|
||||
fn wrap_tx(self) -> TxWrapper;
|
||||
}
|
||||
|
||||
impl WrapTx for ChildStdin {
|
||||
fn wrap_tx(self) -> TxWrapper {
|
||||
TxWrapper::Child(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl WrapTx for WriteHalf<TcpStream> {
|
||||
fn wrap_tx(self) -> TxWrapper {
|
||||
TxWrapper::Tcp(self)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue