diff --git a/crates/agent_ui/src/acp/completion_provider.rs b/crates/agent_ui/src/acp/completion_provider.rs index 781f8b5868..ce1787dd35 100644 --- a/crates/agent_ui/src/acp/completion_provider.rs +++ b/crates/agent_ui/src/acp/completion_provider.rs @@ -6,7 +6,7 @@ use std::sync::atomic::AtomicBool; use acp_thread::MentionUri; use agent::context_store::ContextStore; use anyhow::{Context as _, Result}; -use collections::HashMap; +use collections::{HashMap, HashSet}; use editor::display_map::CreaseId; use editor::{CompletionProvider, Editor, ExcerptId}; use file_icons::FileIcons; @@ -309,7 +309,6 @@ pub struct ContextPickerCompletionProvider { thread_store: Option>, text_thread_store: Option>, editor: WeakEntity, - excluded_buffer: Option>, } impl ContextPickerCompletionProvider { @@ -319,7 +318,6 @@ impl ContextPickerCompletionProvider { thread_store: Option>, text_thread_store: Option>, editor: WeakEntity, - exclude_buffer: Option>, ) -> Self { Self { mention_set, @@ -327,7 +325,6 @@ impl ContextPickerCompletionProvider { thread_store, text_thread_store, editor, - excluded_buffer: exclude_buffer, } } @@ -772,21 +769,35 @@ impl CompletionProvider for ContextPickerCompletionProvider { let MentionCompletion { mode, argument, .. } = state; let query = argument.unwrap_or_else(|| "".to_string()); - let excluded_path = self - .excluded_buffer - .as_ref() - .and_then(WeakEntity::upgrade) - .and_then(|b| b.read(cx).file()) - .map(|file| ProjectPath::from_file(file.as_ref(), cx)); + let (exclude_paths, exclude_threads) = { + let mention_set = self.mention_set.lock(); - // let recent_entries = recent_context_picker_entries( - // context_store.clone(), - // thread_store.clone(), - // text_thread_store.clone(), - // workspace.clone(), - // excluded_path.clone(), - // cx, - // ); + let mut excluded_paths = HashSet::default(); + let mut excluded_threads = HashSet::default(); + + for uri in mention_set.uri_by_crease_id.values() { + match uri { + MentionUri::File(path) => { + excluded_paths.insert(path.clone()); + } + MentionUri::Thread(thread) => { + excluded_threads.insert(thread.0.as_ref().into()); + } + _ => {} + } + } + + (excluded_paths, excluded_threads) + }; + + let recent_entries = recent_context_picker_entries( + thread_store.clone(), + text_thread_store.clone(), + workspace.clone(), + &exclude_paths, + &exclude_threads, + cx, + ); let prompt_store = thread_store.as_ref().and_then(|thread_store| { thread_store @@ -799,9 +810,7 @@ impl CompletionProvider for ContextPickerCompletionProvider { mode, query, Arc::::default(), - // todo! - // recent_entries, - vec![], + recent_entries, prompt_store, thread_store.clone(), text_thread_store.clone(), @@ -827,10 +836,6 @@ impl CompletionProvider for ContextPickerCompletionProvider { path: mat.path.clone(), }; - if excluded_path.as_ref() == Some(&project_path) { - return None; - } - Self::completion_for_path( project_path, &mat.path_prefix, diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index ab4d4bdbfe..c72f29343b 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -145,7 +145,7 @@ impl AcpThreadView { None, None, cx.weak_entity(), - None, + // None, )))); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, diff --git a/crates/agent_ui/src/context_picker.rs b/crates/agent_ui/src/context_picker.rs index cbf669de03..e53b43b306 100644 --- a/crates/agent_ui/src/context_picker.rs +++ b/crates/agent_ui/src/context_picker.rs @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use anyhow::{Result, anyhow}; +use collections::HashSet; pub use completion_provider::ContextPickerCompletionProvider; use editor::display_map::{Crease, CreaseId, CreaseMetadata, FoldId}; use editor::{Anchor, AnchorRangeExt as _, Editor, ExcerptId, FoldPlaceholder, ToOffset}; @@ -531,7 +532,7 @@ impl ContextPicker { return vec![]; }; - recent_context_picker_entries( + recent_context_picker_entries_with_store( context_store, self.thread_store.clone(), self.text_thread_store.clone(), @@ -631,24 +632,56 @@ pub(crate) fn available_context_picker_entries( entries } -pub(crate) fn recent_context_picker_entries( +fn recent_context_picker_entries_with_store( context_store: Entity, thread_store: Option>, text_thread_store: Option>, workspace: Entity, exclude_path: Option, cx: &App, +) -> Vec { + let project = workspace.read(cx).project(); + + let mut exclude_paths = context_store.read(cx).file_paths(cx); + exclude_paths.extend(exclude_path); + + let exclude_paths = exclude_paths + .into_iter() + .filter_map(|project_path| project.read(cx).absolute_path(&project_path, cx)) + .collect(); + + let exclude_threads = context_store.read(cx).thread_ids(); + + recent_context_picker_entries( + thread_store, + text_thread_store, + workspace, + &exclude_paths, + exclude_threads, + cx, + ) +} + +pub(crate) fn recent_context_picker_entries( + thread_store: Option>, + text_thread_store: Option>, + workspace: Entity, + exclude_paths: &HashSet, + exclude_threads: &HashSet, + cx: &App, ) -> Vec { let mut recent = Vec::with_capacity(6); - let mut current_files = context_store.read(cx).file_paths(cx); - current_files.extend(exclude_path); let workspace = workspace.read(cx); let project = workspace.project().read(cx); recent.extend( workspace .recent_navigation_history_iter(cx) - .filter(|(path, _)| !current_files.contains(path)) + .filter(|(_, abs_path)| { + abs_path + .as_ref() + .map_or(true, |path| !exclude_paths.contains(path.as_path())) + }) .take(4) .filter_map(|(project_path, _)| { project @@ -660,8 +693,6 @@ pub(crate) fn recent_context_picker_entries( }), ); - let current_threads = context_store.read(cx).thread_ids(); - let active_thread_id = workspace .panel::(cx) .and_then(|panel| Some(panel.read(cx).active_thread(cx)?.read(cx).id())); @@ -673,7 +704,7 @@ pub(crate) fn recent_context_picker_entries( let mut threads = unordered_thread_entries(thread_store, text_thread_store, cx) .filter(|(_, thread)| match thread { ThreadContextEntry::Thread { id, .. } => { - Some(id) != active_thread_id && !current_threads.contains(id) + Some(id) != active_thread_id && !exclude_threads.contains(id) } ThreadContextEntry::Context { .. } => true, }) diff --git a/crates/agent_ui/src/context_picker/completion_provider.rs b/crates/agent_ui/src/context_picker/completion_provider.rs index 8123b3437d..962c0df03d 100644 --- a/crates/agent_ui/src/context_picker/completion_provider.rs +++ b/crates/agent_ui/src/context_picker/completion_provider.rs @@ -35,7 +35,7 @@ use super::symbol_context_picker::search_symbols; use super::thread_context_picker::{ThreadContextEntry, ThreadMatch, search_threads}; use super::{ ContextPickerAction, ContextPickerEntry, ContextPickerMode, MentionLink, RecentEntry, - available_context_picker_entries, recent_context_picker_entries, selection_ranges, + available_context_picker_entries, recent_context_picker_entries_with_store, selection_ranges, }; use crate::message_editor::ContextCreasesAddon; @@ -787,7 +787,7 @@ impl CompletionProvider for ContextPickerCompletionProvider { .and_then(|b| b.read(cx).file()) .map(|file| ProjectPath::from_file(file.as_ref(), cx)); - let recent_entries = recent_context_picker_entries( + let recent_entries = recent_context_picker_entries_with_store( context_store.clone(), thread_store.clone(), text_thread_store.clone(),