From 8adcf5083ffc12532ecca7594a2192acd954dd3a Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 15 Oct 2020 23:32:07 +0900 Subject: wip --- helix-lsp/Cargo.toml | 15 +++++++++++ helix-lsp/src/lib.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 helix-lsp/Cargo.toml create mode 100644 helix-lsp/src/lib.rs (limited to 'helix-lsp') 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 "] +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>, +} + +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 = 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(()) + } +} -- cgit v1.2.3-70-g09d2