summaryrefslogtreecommitdiff
path: root/helix-lsp/src/lib.rs
blob: 14d53bea85ed291c2e97ecf387b4a6460b95bf56 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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(())
    }
}