diff --git a/crates/project/src/buffer_store.rs b/crates/project/src/buffer_store.rs index 442cd35dc1b171a1510439f5314d3f543293350f..892d2d289cb6cdcca9b9d5ba7f0f4d804a1e7898 100644 --- a/crates/project/src/buffer_store.rs +++ b/crates/project/src/buffer_store.rs @@ -975,6 +975,10 @@ impl BufferStore { .filter_map(|buffer| buffer.upgrade()) } + pub(crate) fn is_searchable(&self, id: &BufferId) -> bool { + !self.non_searchable_buffers.contains(&id) + } + pub fn loading_buffers( &self, ) -> impl Iterator>>)> { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 053c922ba7ceac5bb79aad8eb66e8d0018c4b982..405cf8ced425257bd73ca5c507ecd64abf050792 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -4011,9 +4011,10 @@ impl Project { Some((tree.snapshot(), tree.as_local()?.settings())) }) .collect::>(); + let searcher = ProjectSearcher { fs: self.fs.clone(), - buffer_store: self.buffer_store.downgrade(), + buffer_store: self.buffer_store.clone(), snapshots, open_buffers: Default::default(), }; diff --git a/crates/project/src/project_search.rs b/crates/project/src/project_search.rs index 3de727349d2eb7cb7872f9f763048d39d2bed0c1..e759fd198e5e3b50bbc49b78bdd5adf74ed1466a 100644 --- a/crates/project/src/project_search.rs +++ b/crates/project/src/project_search.rs @@ -11,7 +11,7 @@ use std::{ use collections::HashSet; use fs::Fs; use futures::{SinkExt, StreamExt, select_biased}; -use gpui::{App, AsyncApp, Entity, WeakEntity}; +use gpui::{App, AsyncApp, Entity}; use language::{Buffer, BufferSnapshot}; use postage::oneshot; use smol::channel::{Receiver, Sender, bounded, unbounded}; @@ -20,14 +20,14 @@ use util::{ResultExt, maybe}; use worktree::{Entry, ProjectEntryId, Snapshot, WorktreeSettings}; use crate::{ - ProjectPath, + ProjectItem, ProjectPath, buffer_store::BufferStore, search::{SearchQuery, SearchResult}, }; pub(crate) struct ProjectSearcher { pub(crate) fs: Arc, - pub(crate) buffer_store: WeakEntity, + pub(crate) buffer_store: Entity, pub(crate) snapshots: Vec<(Snapshot, WorktreeSettings)>, pub(crate) open_buffers: HashSet, } @@ -37,6 +37,21 @@ const MAX_SEARCH_RESULT_RANGES: usize = 10_000; impl ProjectSearcher { pub(crate) fn run(self, query: SearchQuery, cx: &mut App) -> Receiver { + let mut open_buffers = HashSet::default(); + let mut unnamed_buffers = Vec::new(); + + let buffers = self.buffer_store.read(cx); + for handle in buffers.buffers() { + let buffer = handle.read(cx); + if !buffers.is_searchable(&buffer.remote_id()) { + continue; + } else if let Some(entry_id) = buffer.entry_id(cx) { + open_buffers.insert(entry_id); + } else { + // limit = limit.saturating_sub(1); todo!() + unnamed_buffers.push(handle) + }; + } let executor = cx.background_executor().clone(); let (tx, rx) = unbounded(); cx.spawn(async move |cx| { @@ -202,23 +217,33 @@ impl Worker<'_> { get_buffer_for_full_scan_tx: &self.get_buffer_for_full_scan_tx, publish_matches: &self.publish_matches, }; + loop { select_biased! { find_all_matches = find_all_matches.next() => { - let result = handler.handle_find_all_matches(find_all_matches).await; + let Some(matches) = find_all_matches else { + self.publish_matches.close(); + continue; + }; + let result = handler.handle_find_all_matches(matches).await; if let Some(_should_bail) = result { - return; + self.publish_matches.close(); + break; } }, find_first_match = find_first_match.next() => { if let Some(buffer_with_at_least_one_match) = find_first_match { handler.handle_find_first_match(buffer_with_at_least_one_match).await; + } else { + self.get_buffer_for_full_scan_tx.close(); } }, scan_path = scan_path.next() => { if let Some(path_to_scan) = scan_path { handler.handle_scan_path(path_to_scan).await; + } else { + self.confirm_contents_will_match_tx.close(); } } @@ -245,11 +270,8 @@ struct LimitReached; impl RequestHandler<'_> { async fn handle_find_all_matches( &self, - req: Option<(Entity, BufferSnapshot)>, + (buffer, snapshot): (Entity, BufferSnapshot), ) -> Option { - let Some((buffer, snapshot)) = req else { - unreachable!() - }; let ranges = self .query .search(&snapshot, None)