aboutsummaryrefslogtreecommitdiff
path: root/helix-lsp
diff options
context:
space:
mode:
Diffstat (limited to 'helix-lsp')
-rw-r--r--helix-lsp/Cargo.toml15
-rw-r--r--helix-lsp/src/lib.rs71
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(())
+ }
+}