Show the last in-progress task from language servers

Antonio Scandurra created

Change summary

Cargo.lock                         |  1 +
crates/project/src/project.rs      | 10 ++++++++--
crates/workspace/Cargo.toml        |  1 +
crates/workspace/src/lsp_status.rs | 15 ++++++++++-----
4 files changed, 20 insertions(+), 7 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -5852,6 +5852,7 @@ dependencies = [
  "postage",
  "project",
  "serde_json",
+ "smallvec",
  "theme",
  "util",
 ]

crates/project/src/project.rs 🔗

@@ -136,10 +136,11 @@ pub struct LanguageServerStatus {
     pending_diagnostic_updates: isize,
 }
 
-#[derive(Clone, Default)]
+#[derive(Clone, Debug)]
 pub struct LanguageServerProgress {
     pub message: Option<String>,
     pub percentage: Option<usize>,
+    pub last_update_at: Instant,
 }
 
 #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
@@ -1253,6 +1254,7 @@ impl Project {
                                                     percentage: report
                                                         .percentage
                                                         .map(|p| p as usize),
+                                                    last_update_at: Instant::now(),
                                                 },
                                             })
                                             .ok();
@@ -1494,6 +1496,7 @@ impl Project {
                 LanguageServerProgress {
                     message: None,
                     percentage: None,
+                    last_update_at: Instant::now(),
                 },
             );
             cx.notify();
@@ -1541,7 +1544,9 @@ impl Project {
         }
     }
 
-    pub fn language_server_statuses(&self) -> impl Iterator<Item = &LanguageServerStatus> {
+    pub fn language_server_statuses(
+        &self,
+    ) -> impl DoubleEndedIterator<Item = &LanguageServerStatus> {
         self.language_server_statuses.values()
     }
 
@@ -3332,6 +3337,7 @@ impl Project {
                         LanguageServerProgress {
                             message: payload.message,
                             percentage: payload.percentage.map(|p| p as usize),
+                            last_update_at: Instant::now(),
                         },
                         cx,
                     );

crates/workspace/Cargo.toml 🔗

@@ -24,6 +24,7 @@ futures = "0.3"
 log = "0.4"
 parking_lot = "0.11.1"
 postage = { version = "0.4.1", features = ["futures-traits"] }
+smallvec = { version = "1.6", features = ["union"] }
 
 [dev-dependencies]
 client = { path = "../client", features = ["test-support"] }

crates/workspace/src/lsp_status.rs 🔗

@@ -8,6 +8,8 @@ use gpui::{
 use language::{LanguageRegistry, LanguageServerBinaryStatus};
 use postage::watch;
 use project::{LanguageServerProgress, Project};
+use smallvec::SmallVec;
+use std::cmp::Reverse;
 use std::fmt::Write;
 use std::sync::Arc;
 
@@ -90,15 +92,18 @@ impl LspStatus {
         self.project
             .read(cx)
             .language_server_statuses()
+            .rev()
             .filter_map(|status| {
                 if status.pending_work.is_empty() {
                     None
                 } else {
-                    Some(
-                        status.pending_work.iter().map(|(token, progress)| {
-                            (status.name.as_str(), token.as_str(), progress)
-                        }),
-                    )
+                    let mut pending_work = status
+                        .pending_work
+                        .iter()
+                        .map(|(token, progress)| (status.name.as_str(), token.as_str(), progress))
+                        .collect::<SmallVec<[_; 4]>>();
+                    pending_work.sort_by_key(|(_, _, progress)| Reverse(progress.last_update_at));
+                    Some(pending_work)
                 }
             })
             .flatten()