1use std::{
2 collections::HashMap,
3 ffi::OsString,
4 future::Future,
5 ops::DerefMut,
6 path::{Path, PathBuf},
7 sync::Arc,
8};
9
10use lsp_types::{notification, request, CodeActionKind, ServerCapabilities};
11use parking_lot::{Mutex, RwLock};
12use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
13
14use crate::IOKind;
15use crate::{
16 io::{IoHandler, NotificationHandler, ResponseHandler, IO},
17 listener::Listener,
18 utils::Subscription,
19 AnyNotification,
20};
21
22pub struct LanguageServerBinary {
28 pub path: PathBuf,
29 pub envs: Option<HashMap<String, String>>,
30 pub args: Vec<OsString>,
31}
32
33pub struct LanguageServer {
34 io: IO,
35 listener: Listener,
36 pub output_done_rx: UnboundedReceiver<String>,
37 code_action_kind: Option<Vec<CodeActionKind>>,
38 capabilities: RwLock<ServerCapabilities>,
39}
40
41impl LanguageServer {
42 pub fn new(
63 binary: LanguageServerBinary,
64 id: i32,
65 root_path: &Path,
66 capture: Arc<Mutex<Option<String>>>,
67 code_action_kind: Option<Vec<CodeActionKind>>,
68 ) -> anyhow::Result<Self> {
69 let (request_tx, request_rx) = unbounded_channel::<String>();
70 let (notification_tx, notification_rx) = unbounded_channel::<AnyNotification>();
71 let (output_done_tx, output_done_rx) = unbounded_channel();
72
73 let notification_handlers =
74 Arc::new(Mutex::new(HashMap::<_, NotificationHandler>::default()));
75 let response_handlers =
76 Arc::new(Mutex::new(Some(HashMap::<_, ResponseHandler>::default())));
77
78 let io_handlers = Arc::new(Mutex::new(HashMap::<_, IoHandler>::default()));
79
80 let io = IO::new(
81 id,
82 binary,
83 response_handlers.clone(),
84 io_handlers.clone(),
85 request_rx,
86 notification_tx,
87 output_done_tx,
88 root_path,
89 capture,
90 )?;
91 let listener = Listener::new(
92 notification_rx,
93 notification_handlers,
94 response_handlers,
95 io_handlers,
96 request_tx,
97 )?;
98
99 Ok(Self {
100 io,
101 listener,
102 output_done_rx,
103 code_action_kind,
104 capabilities: Default::default(),
105 })
106 }
107
108 pub async fn request<T: request::Request>(
120 &self,
121 params: T::Params,
122 ) -> anyhow::Result<T::Result> {
123 self.listener.request::<T>(params).await
124 }
125
126 pub async fn notify<T: notification::Notification>(
139 &self,
140 params: T::Params,
141 ) -> anyhow::Result<()> {
142 self.listener.send_notification::<T>(params).await
143 }
144
145 pub fn on_request<T: request::Request, F, Fut>(&self, f: F) -> Subscription
149 where
150 T::Params: 'static + Send,
151 F: Send + 'static + FnMut(T::Params) -> Fut,
152 Fut: Send + 'static + Future<Output = anyhow::Result<T::Result>>,
153 {
154 self.listener.on_request::<T, F, Fut>(f)
155 }
156
157 pub fn on_notification<T: notification::Notification, F>(&self, f: F) -> Subscription
161 where
162 T::Params: 'static + Send,
163 F: Send + 'static + FnMut(T::Params),
164 {
165 self.listener.on_notification::<T, F>(f)
166 }
167
168 pub fn on_io<F>(&self, f: F) -> Subscription
172 where
173 F: Send + 'static + FnMut(IOKind, &str),
174 {
175 self.listener.on_io::<F>(f)
176 }
177
178 pub fn server_id(&self) -> i32 {
180 self.io.id()
181 }
182
183 pub fn root_path(&self) -> &PathBuf {
185 self.io.root_path()
186 }
187
188 pub fn working_dir(&self) -> &PathBuf {
190 self.io.working_dir()
191 }
192
193 pub fn capabilities(&self) -> ServerCapabilities {
195 self.capabilities.read().clone()
196 }
197
198 pub fn update_capabilities(&self, update: impl FnOnce(&mut ServerCapabilities)) {
200 update(self.capabilities.write().deref_mut())
201 }
202
203 pub fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
205 self.code_action_kind.clone()
206 }
207
208 pub fn name(&self) -> &str {
210 self.io.name()
211 }
212
213 pub fn kill(&mut self) -> anyhow::Result<()> {
215 self.io.kill()?;
216 self.listener.kill()?;
217 Ok(())
218 }
219}