on master help sign in
Add `MethodCall`, `ProgressStatus`, `LspProgressMap`
52fb90bwojciechkepka
helix-lsp/src/lib.rs+98
@@ -181,6 +181,30 @@ pub mod util {
181 }
181 }
182}
182}
183
183
184+#[derive(Debug, PartialEq, Clone)]
185+pub enum MethodCall {
186+ WorkDoneProgressCreate(lsp::WorkDoneProgressCreateParams),
187+}
188+
189+impl MethodCall {
190+ pub fn parse(method: &str, params: jsonrpc::Params) -> Option<MethodCall> {
191+ use lsp::request::Request;
192+ let request = match method {
193+ lsp::request::WorkDoneProgressCreate::METHOD => {
194+ let params: lsp::WorkDoneProgressCreateParams = params
195+ .parse()
196+ .expect("Failed to parse WorkDoneCreate params");
197+ Self::WorkDoneProgressCreate(params)
198+ }
199+ _ => {
200+ log::warn!("unhandled lsp request: {}", method);
201+ return None;
202+ }
203+ };
204+ Some(request)
205+ }
206+}
207+
184#[derive(Debug, PartialEq, Clone)]
208#[derive(Debug, PartialEq, Clone)]
185pub enum Notification {
209pub enum Notification {
186 PublishDiagnostics(lsp::PublishDiagnosticsParams),
210 PublishDiagnostics(lsp::PublishDiagnosticsParams),
@@ -275,6 +299,80 @@ impl Registry {
275 }
299 }
276}
300}
277
301
302+#[derive(Debug)]
303+pub enum ProgressStatus {
304+ Created,
305+ Started(lsp::WorkDoneProgress),
306+}
307+
308+impl ProgressStatus {
309+ pub fn progress(&self) -> Option<&lsp::WorkDoneProgress> {
310+ match &self {
311+ ProgressStatus::Created => None,
312+ ProgressStatus::Started(progress) => Some(&progress),
313+ }
314+ }
315+}
316+
317+#[derive(Default, Debug)]
318+/// Acts as a container for progress reported by language servers. Each server
319+/// has a unique id assigned at creation through [`Registry`]. This id is then used
320+/// to store the progress in this map.
321+pub struct LspProgressMap(HashMap<usize, HashMap<lsp::ProgressToken, ProgressStatus>>);
322+
323+impl LspProgressMap {
324+ pub fn new() -> Self {
325+ Self::default()
326+ }
327+
328+ /// Returns a map of all tokens coresponding to the lanaguage server with `id`.
329+ pub fn progress_map(&self, id: usize) -> Option<&HashMap<lsp::ProgressToken, ProgressStatus>> {
330+ self.0.get(&id)
331+ }
332+
333+ /// Returns last progress status for a given server with `id` and `token`.
334+ pub fn progress(&self, id: usize, token: &lsp::ProgressToken) -> Option<&ProgressStatus> {
335+ self.0.get(&id).and_then(|values| values.get(token))
336+ }
337+
338+ /// Checks if progress `token` for server with `id` is created.
339+ pub fn is_created(&mut self, id: usize, token: &lsp::ProgressToken) -> bool {
340+ self.0
341+ .get(&id)
342+ .map(|values| values.get(token).is_some())
343+ .unwrap_or_default()
344+ }
345+
346+ pub fn create(&mut self, id: usize, token: lsp::ProgressToken) {
347+ self.0
348+ .entry(id)
349+ .or_default()
350+ .insert(token, ProgressStatus::Created);
351+ }
352+
353+ /// Ends the progress by removing the `token` from server with `id`, if removed returns the value.
354+ pub fn end_progress(
355+ &mut self,
356+ id: usize,
357+ token: &lsp::ProgressToken,
358+ ) -> Option<ProgressStatus> {
359+ self.0.get_mut(&id).and_then(|vals| vals.remove(token))
360+ }
361+
362+ /// Updates the progess of `token` for server with `id` to `status`, returns the value replaced or `None`.
363+ pub fn update(
364+ &mut self,
365+ id: usize,
366+ token: lsp::ProgressToken,
367+ status: lsp::WorkDoneProgress,
368+ ) -> Option<ProgressStatus> {
369+ self.0
370+ .entry(id)
371+ .or_default()
372+ .insert(token, ProgressStatus::Started(status))
373+ }
374+}
375+
278// REGISTRY = HashMap<LanguageId, Lazy/OnceCell<Arc<RwLock<Client>>>
376// REGISTRY = HashMap<LanguageId, Lazy/OnceCell<Arc<RwLock<Client>>>
279// spawn one server per language type, need to spawn one per workspace if server doesn't support
377// spawn one server per language type, need to spawn one per workspace if server doesn't support
280// workspaces
378// workspaces