diff options
Diffstat (limited to 'helix-lsp')
-rw-r--r-- | helix-lsp/Cargo.toml | 15 | ||||
-rw-r--r-- | helix-lsp/src/lib.rs | 71 |
2 files changed, 86 insertions, 0 deletions
diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml new file mode 100644 index 00000000..6fd59bf4 --- /dev/null +++ b/helix-lsp/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "helix-lsp" +version = "0.1.0" +authors = ["Blaž Hrastnik <blaz@mxxn.io>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lsp-types = { version = "0.82", features = ["proposed"] } +smol = "1.2" +url = "2.1.1" +pathdiff = "0.2.0" +shellexpand = "2.0.0" +glob = "0.3.0" diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs new file mode 100644 index 00000000..14d53bea --- /dev/null +++ b/helix-lsp/src/lib.rs @@ -0,0 +1,71 @@ +use std::{ + collections::HashMap, + process::{ChildStderr, ChildStdin, ChildStdout, Command, Stdio}, +}; + +use smol::io::{BufReader, BufWriter}; +use smol::prelude::*; +use smol::Unblock; + +struct Client { + // process: Command, + reader: BufReader<Unblock<ChildStdout>>, +} + +impl Client { + fn start(cmd: &str, args: &[String]) -> Self { + let mut process = Command::new(cmd) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("Failed to start language server"); + // TODO: impl drop that kills the process + + // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock? + let writer = BufWriter::new(Unblock::new( + process.stdin.take().expect("Failed to open stdin"), + )); + let reader = BufReader::new(Unblock::new( + process.stdout.take().expect("Failed to open stdout"), + )); + let stderr = BufReader::new(Unblock::new( + process.stderr.take().expect("Failed to open stderr"), + )); + + Client { reader } + } + + async fn receiver(&mut self) -> Result<(), std::io::Error> { + let mut headers: HashMap<String, String> = HashMap::default(); + loop { + // read headers + loop { + let mut header = String::new(); + // detect pipe closed if 0 + self.reader.read_line(&mut header).await?; + let header = header.trim(); + + if header.is_empty() { + break; + } + + let parts: Vec<&str> = header.split(": ").collect(); + if parts.len() != 2 { + // return Err(Error::new(ErrorKind::Other, "Failed to parse header")); + panic!() + } + headers.insert(parts[0].to_string(), parts[1].to_string()); + } + + // find content-length + + // read data + // decode via serde_json decoding into jsonrpc_core Output + break; + } + + Ok(()) + } +} |