@@ -82,7 +82,10 @@ fn view_release_notes_locally(
.update_in(cx, |workspace, window, cx| {
let project = workspace.project().clone();
let buffer = project.update(cx, |project, cx| {
- project.create_local_buffer("", markdown, cx)
+ let buffer = project.create_local_buffer("", markdown, cx);
+ project
+ .mark_buffer_as_non_searchable(buffer.read(cx).remote_id(), cx);
+ buffer
});
buffer.update(cx, |buffer, cx| {
buffer.edit([(0..0, body.release_notes)], None, cx)
@@ -39,6 +39,7 @@ pub struct BufferStore {
path_to_buffer_id: HashMap<ProjectPath, BufferId>,
downstream_client: Option<(AnyProtoClient, u64)>,
shared_buffers: HashMap<proto::PeerId, HashMap<BufferId, SharedBuffer>>,
+ non_searchable_buffers: HashSet<BufferId>,
}
#[derive(Hash, Eq, PartialEq, Clone)]
@@ -726,6 +727,7 @@ impl BufferStore {
path_to_buffer_id: Default::default(),
shared_buffers: Default::default(),
loading_buffers: Default::default(),
+ non_searchable_buffers: Default::default(),
worktree_store,
}
}
@@ -750,6 +752,7 @@ impl BufferStore {
path_to_buffer_id: Default::default(),
loading_buffers: Default::default(),
shared_buffers: Default::default(),
+ non_searchable_buffers: Default::default(),
worktree_store,
}
}
@@ -1059,7 +1062,9 @@ impl BufferStore {
let mut unnamed_buffers = Vec::new();
for handle in self.buffers() {
let buffer = handle.read(cx);
- if let Some(entry_id) = buffer.entry_id(cx) {
+ if self.non_searchable_buffers.contains(&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);
@@ -1665,6 +1670,10 @@ impl BufferStore {
}
serialized_transaction
}
+
+ pub(crate) fn mark_buffer_as_non_searchable(&mut self, buffer_id: BufferId) {
+ self.non_searchable_buffers.insert(buffer_id);
+ }
}
impl OpenBuffer {
@@ -5336,6 +5336,132 @@ async fn test_search_with_exclusions(cx: &mut gpui::TestAppContext) {
);
}
+#[gpui::test]
+async fn test_search_with_buffer_exclusions(cx: &mut gpui::TestAppContext) {
+ init_test(cx);
+
+ let search_query = "file";
+
+ let fs = FakeFs::new(cx.executor());
+ fs.insert_tree(
+ path!("/dir"),
+ json!({
+ "one.rs": r#"// Rust file one"#,
+ "one.ts": r#"// TypeScript file one"#,
+ "two.rs": r#"// Rust file two"#,
+ "two.ts": r#"// TypeScript file two"#,
+ }),
+ )
+ .await;
+
+ let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
+ let _buffer = project.update(cx, |project, cx| {
+ let buffer = project.create_local_buffer("file", None, cx);
+ project.mark_buffer_as_non_searchable(buffer.read(cx).remote_id(), cx);
+ buffer
+ });
+
+ assert_eq!(
+ search(
+ &project,
+ SearchQuery::text(
+ search_query,
+ false,
+ true,
+ false,
+ Default::default(),
+ PathMatcher::new(&["*.odd".to_owned()]).unwrap(),
+ false,
+ None,
+ )
+ .unwrap(),
+ cx
+ )
+ .await
+ .unwrap(),
+ HashMap::from_iter([
+ (path!("dir/one.rs").to_string(), vec![8..12]),
+ (path!("dir/one.ts").to_string(), vec![14..18]),
+ (path!("dir/two.rs").to_string(), vec![8..12]),
+ (path!("dir/two.ts").to_string(), vec![14..18]),
+ ]),
+ "If no exclusions match, all files should be returned"
+ );
+
+ assert_eq!(
+ search(
+ &project,
+ SearchQuery::text(
+ search_query,
+ false,
+ true,
+ false,
+ Default::default(),
+ PathMatcher::new(&["*.rs".to_owned()]).unwrap(),
+ false,
+ None,
+ )
+ .unwrap(),
+ cx
+ )
+ .await
+ .unwrap(),
+ HashMap::from_iter([
+ (path!("dir/one.ts").to_string(), vec![14..18]),
+ (path!("dir/two.ts").to_string(), vec![14..18]),
+ ]),
+ "Rust exclusion search should give only TypeScript files"
+ );
+
+ assert_eq!(
+ search(
+ &project,
+ SearchQuery::text(
+ search_query,
+ false,
+ true,
+ false,
+ Default::default(),
+ PathMatcher::new(&["*.ts".to_owned(), "*.odd".to_owned()]).unwrap(),
+ false,
+ None,
+ )
+ .unwrap(),
+ cx
+ )
+ .await
+ .unwrap(),
+ HashMap::from_iter([
+ (path!("dir/one.rs").to_string(), vec![8..12]),
+ (path!("dir/two.rs").to_string(), vec![8..12]),
+ ]),
+ "TypeScript exclusion search should give only Rust files, even if other exclusions don't match anything"
+ );
+
+ assert!(
+ search(
+ &project,
+ SearchQuery::text(
+ search_query,
+ false,
+ true,
+ false,
+ Default::default(),
+ PathMatcher::new(&["*.rs".to_owned(), "*.ts".to_owned(), "*.odd".to_owned()])
+ .unwrap(),
+ false,
+ None,
+ )
+ .unwrap(),
+ cx
+ )
+ .await
+ .unwrap()
+ .is_empty(),
+ "Rust and typescript exclusion should give no files, even if other exclusions don't match anything"
+ );
+}
+
#[gpui::test]
async fn test_search_with_exclusions_and_inclusions(cx: &mut gpui::TestAppContext) {
init_test(cx);