mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-26 03:13:29 +04:00
lsp: Gracefully fail if binary doesn't exist.
This commit is contained in:
parent
9dfd6f6bbc
commit
5aed1f3c00
@ -34,15 +34,25 @@ pub struct Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub fn start(ex: &Executor, cmd: &str, args: &[String]) -> (Self, Receiver<Call>) {
|
pub fn start(ex: &Executor, cmd: &str, args: &[String]) -> Result<(Self, Receiver<Call>)> {
|
||||||
let mut process = Command::new(cmd)
|
// smol makes sure the process is reaped on drop, but using kill_on_drop(true) maybe?
|
||||||
|
let process = Command::new(cmd)
|
||||||
.args(args)
|
.args(args)
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn();
|
||||||
.expect("Failed to start language server");
|
|
||||||
// smol makes sure the process is reaped on drop, but using kill_on_drop(true) maybe?
|
// use std::io::ErrorKind;
|
||||||
|
let mut process = match process {
|
||||||
|
Ok(process) => process,
|
||||||
|
Err(err) => match err.kind() {
|
||||||
|
// ErrorKind::NotFound | ErrorKind::PermissionDenied => {
|
||||||
|
// return Err(Error::Other(err.into()))
|
||||||
|
// }
|
||||||
|
_kind => return Err(Error::Other(err.into())),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
|
// TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
|
||||||
let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
|
let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
|
||||||
@ -65,7 +75,7 @@ pub fn start(ex: &Executor, cmd: &str, args: &[String]) -> (Self, Receiver<Call>
|
|||||||
// TODO: async client.initialize()
|
// TODO: async client.initialize()
|
||||||
// maybe use an arc<atomic> flag
|
// maybe use an arc<atomic> flag
|
||||||
|
|
||||||
(client, incoming)
|
Ok((client, incoming))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_request_id(&self) -> jsonrpc::Id {
|
fn next_request_id(&self) -> jsonrpc::Id {
|
||||||
|
@ -104,7 +104,7 @@ pub fn parse(method: &str, params: jsonrpc::Params) -> Notification {
|
|||||||
use smol::channel::Receiver;
|
use smol::channel::Receiver;
|
||||||
|
|
||||||
pub struct Registry {
|
pub struct Registry {
|
||||||
inner: HashMap<LanguageId, Arc<Client>>,
|
inner: HashMap<LanguageId, Option<Arc<Client>>>,
|
||||||
|
|
||||||
pub incoming: SelectAll<Receiver<Call>>,
|
pub incoming: SelectAll<Receiver<Call>>,
|
||||||
}
|
}
|
||||||
@ -140,17 +140,19 @@ pub fn get(
|
|||||||
// TODO: lookup defaults for id (name, args)
|
// TODO: lookup defaults for id (name, args)
|
||||||
|
|
||||||
// initialize a new client
|
// initialize a new client
|
||||||
let (mut client, incoming) = Client::start(&ex, &config.command, &config.args);
|
let (mut client, incoming) =
|
||||||
|
Client::start(&ex, &config.command, &config.args).ok()?;
|
||||||
|
|
||||||
// TODO: run this async without blocking
|
// TODO: run this async without blocking
|
||||||
smol::block_on(client.initialize()).unwrap();
|
smol::block_on(client.initialize()).unwrap();
|
||||||
|
|
||||||
s_incoming.push(incoming);
|
s_incoming.push(incoming);
|
||||||
|
|
||||||
Arc::new(client)
|
Some(Arc::new(client))
|
||||||
})
|
})
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
return Some(language_server);
|
return language_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
Loading…
Reference in New Issue
Block a user