@@ -181,6 +181,30 @@ pub mod util {
184+#[derive(Debug, PartialEq, Clone)]
185+pub enum MethodCall {
186+ WorkDoneProgressCreate(lsp::WorkDoneProgressCreateParams),
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
196+ .expect("Failed to parse WorkDoneCreate params");
197+ Self::WorkDoneProgressCreate(params)
200+ log::warn!("unhandled lsp request: {}", method);
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 {
303+pub enum ProgressStatus {
305+ Started(lsp::WorkDoneProgress),
308+impl ProgressStatus {
309+ pub fn progress(&self) -> Option<&lsp::WorkDoneProgress> {
311+ ProgressStatus::Created => None,
312+ ProgressStatus::Started(progress) => Some(&progress),
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>>);
323+impl LspProgressMap {
324+ pub fn new() -> Self {
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>> {
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))
338+ /// Checks if progress `token` for server with `id` is created.
339+ pub fn is_created(&mut self, id: usize, token: &lsp::ProgressToken) -> bool {
342+ .map(|values| values.get(token).is_some())
343+ .unwrap_or_default()
346+ pub fn create(&mut self, id: usize, token: lsp::ProgressToken) {
350+ .insert(token, ProgressStatus::Created);
353+ /// Ends the progress by removing the `token` from server with `id`, if removed returns the value.
354+ pub fn end_progress(
357+ token: &lsp::ProgressToken,
358+ ) -> Option<ProgressStatus> {
359+ self.0.get_mut(&id).and_then(|vals| vals.remove(token))
362+ /// Updates the progess of `token` for server with `id` to `status`, returns the value replaced or `None`.
366+ token: lsp::ProgressToken,
367+ status: lsp::WorkDoneProgress,
368+ ) -> Option<ProgressStatus> {
372+ .insert(token, ProgressStatus::Started(status))
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