Eagerly index project on workspace creation if it was indexed before

Antonio Scandurra and Kyle Caverly created

Co-Authored-By: Kyle Caverly <kyle@zed.dev>

Change summary

crates/search/src/project_search.rs         |  2 
crates/semantic_index/src/db.rs             |  7 ----
crates/semantic_index/src/semantic_index.rs | 32 ++++++++++++++++++++++
3 files changed, 33 insertions(+), 8 deletions(-)

Detailed changes

crates/search/src/project_search.rs 🔗

@@ -867,7 +867,7 @@ impl ProjectSearchView {
         SemanticIndex::global(cx)
             .map(|semantic| {
                 let project = self.model.read(cx).project.clone();
-                semantic.update(cx, |this, cx| this.project_previously_indexed(project, cx))
+                semantic.update(cx, |this, cx| this.project_previously_indexed(&project, cx))
             })
             .unwrap_or(Task::ready(Ok(false)))
     }

crates/semantic_index/src/db.rs 🔗

@@ -18,7 +18,7 @@ use std::{
     path::{Path, PathBuf},
     rc::Rc,
     sync::Arc,
-    time::{Instant, SystemTime},
+    time::SystemTime,
 };
 use util::TryFutureExt;
 
@@ -232,7 +232,6 @@ impl VectorDatabase {
 
             let file_id = db.last_insert_rowid();
 
-            let t0 = Instant::now();
             let mut query = db.prepare(
                 "
                 INSERT INTO spans
@@ -240,10 +239,6 @@ impl VectorDatabase {
                 VALUES (?1, ?2, ?3, ?4, ?5, ?6)
                 ",
             )?;
-            log::trace!(
-                "Preparing Query Took: {:?} milliseconds",
-                t0.elapsed().as_millis()
-            );
 
             for span in spans {
                 query.execute(params![

crates/semantic_index/src/semantic_index.rs 🔗

@@ -35,6 +35,7 @@ use util::{
     paths::EMBEDDINGS_DIR,
     ResultExt,
 };
+use workspace::WorkspaceCreated;
 
 const SEMANTIC_INDEX_VERSION: usize = 10;
 const BACKGROUND_INDEXING_DELAY: Duration = Duration::from_secs(5 * 60);
@@ -57,6 +58,35 @@ pub fn init(
         return;
     }
 
+    cx.subscribe_global::<WorkspaceCreated, _>({
+        move |event, cx| {
+            let Some(semantic_index) = SemanticIndex::global(cx) else {
+                return;
+            };
+            let workspace = &event.0;
+            if let Some(workspace) = workspace.upgrade(cx) {
+                let project = workspace.read(cx).project().clone();
+                if project.read(cx).is_local() {
+                    cx.spawn(|mut cx| async move {
+                        let previously_indexed = semantic_index
+                            .update(&mut cx, |index, cx| {
+                                index.project_previously_indexed(&project, cx)
+                            })
+                            .await?;
+                        if previously_indexed {
+                            semantic_index
+                                .update(&mut cx, |index, cx| index.index_project(project, cx))
+                                .await?;
+                        }
+                        anyhow::Ok(())
+                    })
+                    .detach_and_log_err(cx);
+                }
+            }
+        }
+    })
+    .detach();
+
     cx.spawn(move |mut cx| async move {
         let semantic_index = SemanticIndex::new(
             fs,
@@ -356,7 +386,7 @@ impl SemanticIndex {
 
     pub fn project_previously_indexed(
         &mut self,
-        project: ModelHandle<Project>,
+        project: &ModelHandle<Project>,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<bool>> {
         let worktrees_indexed_previously = project