A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/lsp.rs')
-rw-r--r--src/lsp.rs73
1 files changed, 48 insertions, 25 deletions
diff --git a/src/lsp.rs b/src/lsp.rs
index d3cab0b..9628740 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -6,11 +6,15 @@ use std::thread::spawn;
use std::time::Instant;
use crossbeam::channel::{Receiver, Sender, unbounded};
+use helix_core::syntax::config::{
+ LanguageServerConfiguration, LanguageServerFeatures,
+};
use json_value_merge::Merge;
use lsp_server::Message;
use lsp_types::notification::*;
use lsp_types::request::*;
use lsp_types::*;
+use rootcause::report;
use tokio::sync::oneshot;
use winit::window::Window;
mod client;
@@ -25,8 +29,16 @@ pub fn run(
(tx, rx): (Sender<Message>, Receiver<Message>),
workspace: WorkspaceFolder,
vscode_conf: Option<serde_json::Value>,
-) -> (Client, std::thread::JoinHandle<()>, oneshot::Sender<Arc<dyn Window>>)
-{
+
+ data: (
+ &'static LanguageServerConfiguration,
+ &'static LanguageServerFeatures,
+ ),
+) -> rootcause::Result<(
+ Client,
+ std::thread::JoinHandle<()>,
+ oneshot::Sender<Arc<dyn Window>>,
+)> {
let now = Instant::now();
let (req_tx, req_rx) = unbounded();
let (not_tx, not_rx) = unbounded();
@@ -40,37 +52,48 @@ pub fn run(
.enable_io()
.worker_threads(3)
.thread_name("lsp runtime")
- .build()
- .unwrap(),
+ .build()?,
id: AtomicI32::new(0),
initialized: None,
diagnostics: Box::leak(Box::new(papaya::HashMap::default())),
send_to: req_tx,
req_rx: _req_rx,
not_rx,
+ lsp_data: data,
};
- let mut opts = init_opts::get(workspace);
+ let mut opts = init_opts::get(
+ workspace,
+ &data.0.config,
+ data.1.name == "rust-analyzer",
+ );
if let Some(v) = vscode_conf {
- opts.initialization_options.as_mut().unwrap().merge(&v);
+ match opts.initialization_options {
+ Some(ref mut x) => x.merge(&v),
+ None => opts.initialization_options = Some(v),
+ }
};
- _ = c.request::<Initialize>(&opts).unwrap();
- let x = serde_json::from_value::<InitializeResult>(
- rx.recv().unwrap().response().unwrap().result.unwrap(),
- )
- .unwrap();
- assert_eq!(
- x.capabilities.position_encoding,
- Some(PositionEncodingKind::UTF8)
- );
+ _ = c.request::<Initialize>(&opts)?;
+ let x = rx
+ .iter()
+ .find_map(|x| {
+ serde_json::from_value::<InitializeResult>(
+ x.response()?.result?,
+ )
+ .ok()
+ })
+ .ok_or(report!("lsp {data:?} died?"))?;
+
+ // assert_eq!(
+ // x.capabilities.position_encoding,
+ // Some(PositionEncodingKind::UTF8)
+ // );
c.initialized = Some(x);
c.notify::<lsp_types::notification::Initialized>(
&InitializedParams {},
- )
- .unwrap();
+ )?;
c.notify::<SetTrace>(&SetTraceParams {
value: lsp_types::TraceValue::Verbose,
- })
- .unwrap();
+ })?;
let progress = c.progress;
let d = c.diagnostics;
log::info!("lsp took {:?} to initialize", now.elapsed());
@@ -80,7 +103,7 @@ pub fn run(
window_rx, progress, _req_tx, d, not_tx, rx, req_rx,
)
});
- (c, h, window_tx)
+ Ok((c, h, window_tx))
}
#[derive(Copy, Clone, PartialEq, Eq, std::marker::ConstParamTy, Debug)]
pub enum BehaviourAfter {
@@ -108,15 +131,15 @@ pub enum BehaviourAfter {
// }
// }
// }
-
pub trait Void<T> {
- fn void(self) -> Result<T, ()>;
+ fn void(&self) -> Option<()>;
}
-impl<T, E> Void<T> for Result<T, E> {
- fn void(self) -> Result<T, ()> {
- self.map_err(|_| ())
+impl<T> Void<T> for Option<T> {
+ fn void(&self) -> Option<()> {
+ self.as_ref().map(|_| ())
}
}
+
#[pin_project::pin_project]
pub struct Map<T, U, F: FnMut(T) -> U, Fu: Future<Output = T>>(
#[pin] Fu,