stdio
and Unix only.Expand description
Utilities to deal with stdin/stdout communication channel for Language Servers.
Typically Language Servers serves on stdin/stdout by default. But generally they cannot be read
or written asynchronously usually, due to technical reasons.
(Eg. tokio::io::stdin
delegates reads
to blocking threads.)
This mod defines PipeStdin
and PipeStdout
for only stdin/stdout with pipe-like
backends, which actually supports asynchronous reads and writes. This currently means one of:
- FIFO pipes. Eg. named pipes mkfifo(3) and unnamed pipes pipe(2).
- Sockets. Eg. TCP connections and UNIX domain sockets unix(7).
- Character devices. Eg. tty(4) or pty(7).
When calling PipeStdin::lock
, it locks the stdin using std::io::stdin
, set its mode to
asynchronous, and exposes an a raw Read
interface bypassing the std’s buffer.
Caveats
Since PipeStd{in,out}
bypass the std’s internal buffer. You should not leave any data in that
buffer (via std::io::stdin
, print!
-like macros and etc.). Otherwise they will be
ignored during PipeStd{in,out}
operations, which is typically a logic error.
Asynchrous I/O drivers
For runtime/drivers with uniform interfaces for sync-async conversion like async_io::Async
,
wrapping PipeStd{in,out}
inside it just works.
use futures::AsyncWriteExt;
let mut stdout = async_io::Async::new(async_lsp::stdio::PipeStdout::lock()?)?;
stdout.write_all(b"truly async, without spawning blocking task!").await?;
For tokio
runtime, their interface is
less ergonomic.
We provide a wrapper method PipeStdin::lock_tokio
for an tokio::io::AsyncRead
compatible interface. PipeStdout
works in class. All of them are gated under feature
tokio
.
Structs
- Locked stdin for asynchronous read.
- Locked stdout for asynchronous read.