Skip to content

Commit

Permalink
Extract ContextHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
maxdeviant committed Jan 21, 2025
1 parent e289fec commit b59dec9
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 245 deletions.
1 change: 1 addition & 0 deletions crates/assistant/src/assistant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub mod assistant_panel;
mod context;
mod context_editor;
mod context_history;
pub mod context_store;
mod inline_assistant;
mod patch;
Expand Down
249 changes: 4 additions & 245 deletions crates/assistant/src/assistant_panel.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::context_editor::{
ContextEditor, ContextEditorToolbarItem, ContextEditorToolbarItemEvent, DEFAULT_TAB_TITLE,
};
use crate::context_history::ContextHistory;
use crate::{
slash_command::SlashCommandCompletionProvider,
terminal_inline_assistant::TerminalInlineAssistant, Context, ContextId, ContextStore,
ContextStoreEvent, DeployHistory, DeployPromptLibrary, InlineAssistant, InsertDraggedFiles,
NewContext, RemoteContextMetadata, SavedContextMetadata, ToggleFocus, ToggleModelSelector,
NewContext, ToggleFocus, ToggleModelSelector,
};
use anyhow::Result;
use assistant_settings::{AssistantDockPosition, AssistantSettings};
Expand All @@ -26,7 +27,6 @@ use language_model::{
LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID,
};
use language_model_selector::LanguageModelSelector;
use picker::{Picker, PickerDelegate};
use project::lsp_store::LocalLspAdapterDelegate;
use project::Project;
use prompt_library::{open_prompt_library, PromptBuilder, PromptLibrary};
Expand All @@ -35,12 +35,7 @@ use settings::{update_settings_file, Settings};
use smol::stream::StreamExt;
use std::{ops::ControlFlow, path::PathBuf, sync::Arc};
use terminal_view::{terminal_panel::TerminalPanel, TerminalView};
use ui::{
prelude::*,
utils::{format_distance_from_now, DateTimeType},
Avatar, ContextMenu, ElevationIndex, ListItem, ListItemSpacing, PopoverMenu, PopoverMenuHandle,
Tooltip,
};
use ui::{prelude::*, ContextMenu, ElevationIndex, PopoverMenu, PopoverMenuHandle, Tooltip};
use util::{maybe, ResultExt};
use workspace::DraggedTab;
use workspace::{
Expand Down Expand Up @@ -106,165 +101,11 @@ pub struct AssistantPanel {
pub(crate) show_zed_ai_notice: bool,
}

#[derive(Clone)]
enum ContextMetadata {
Remote(RemoteContextMetadata),
Saved(SavedContextMetadata),
}

struct SavedContextPickerDelegate {
store: Model<ContextStore>,
project: Model<Project>,
matches: Vec<ContextMetadata>,
selected_index: usize,
}

enum SavedContextPickerEvent {
Confirmed(ContextMetadata),
}

enum InlineAssistTarget {
Editor(View<Editor>, bool),
Terminal(View<TerminalView>),
}

impl EventEmitter<SavedContextPickerEvent> for Picker<SavedContextPickerDelegate> {}

impl SavedContextPickerDelegate {
fn new(project: Model<Project>, store: Model<ContextStore>) -> Self {
Self {
project,
store,
matches: Vec::new(),
selected_index: 0,
}
}
}

impl PickerDelegate for SavedContextPickerDelegate {
type ListItem = ListItem;

fn match_count(&self) -> usize {
self.matches.len()
}

fn selected_index(&self) -> usize {
self.selected_index
}

fn set_selected_index(&mut self, ix: usize, _cx: &mut ViewContext<Picker<Self>>) {
self.selected_index = ix;
}

fn placeholder_text(&self, _cx: &mut WindowContext) -> Arc<str> {
"Search...".into()
}

fn update_matches(&mut self, query: String, cx: &mut ViewContext<Picker<Self>>) -> Task<()> {
let search = self.store.read(cx).search(query, cx);
cx.spawn(|this, mut cx| async move {
let matches = search.await;
this.update(&mut cx, |this, cx| {
let host_contexts = this.delegate.store.read(cx).host_contexts();
this.delegate.matches = host_contexts
.iter()
.cloned()
.map(ContextMetadata::Remote)
.chain(matches.into_iter().map(ContextMetadata::Saved))
.collect();
this.delegate.selected_index = 0;
cx.notify();
})
.ok();
})
}

fn confirm(&mut self, _secondary: bool, cx: &mut ViewContext<Picker<Self>>) {
if let Some(metadata) = self.matches.get(self.selected_index) {
cx.emit(SavedContextPickerEvent::Confirmed(metadata.clone()));
}
}

fn dismissed(&mut self, _cx: &mut ViewContext<Picker<Self>>) {}

fn render_match(
&self,
ix: usize,
selected: bool,
cx: &mut ViewContext<Picker<Self>>,
) -> Option<Self::ListItem> {
let context = self.matches.get(ix)?;
let item = match context {
ContextMetadata::Remote(context) => {
let host_user = self.project.read(cx).host().and_then(|collaborator| {
self.project
.read(cx)
.user_store()
.read(cx)
.get_cached_user(collaborator.user_id)
});
div()
.flex()
.w_full()
.justify_between()
.gap_2()
.child(
h_flex().flex_1().overflow_x_hidden().child(
Label::new(context.summary.clone().unwrap_or(DEFAULT_TAB_TITLE.into()))
.size(LabelSize::Small),
),
)
.child(
h_flex()
.gap_2()
.children(if let Some(host_user) = host_user {
vec![
Avatar::new(host_user.avatar_uri.clone()).into_any_element(),
Label::new(format!("Shared by @{}", host_user.github_login))
.color(Color::Muted)
.size(LabelSize::Small)
.into_any_element(),
]
} else {
vec![Label::new("Shared by host")
.color(Color::Muted)
.size(LabelSize::Small)
.into_any_element()]
}),
)
}
ContextMetadata::Saved(context) => div()
.flex()
.w_full()
.justify_between()
.gap_2()
.child(
h_flex()
.flex_1()
.child(Label::new(context.title.clone()).size(LabelSize::Small))
.overflow_x_hidden(),
)
.child(
Label::new(format_distance_from_now(
DateTimeType::Local(context.mtime),
false,
true,
true,
))
.color(Color::Muted)
.size(LabelSize::Small),
),
};
Some(
ListItem::new(ix)
.inset(true)
.spacing(ListItemSpacing::Sparse)
.toggle_state(selected)
.child(item),
)
}
}

impl AssistantPanel {
pub fn load(
workspace: WeakView<Workspace>,
Expand Down Expand Up @@ -1175,7 +1016,7 @@ impl AssistantPanel {
Some(self.active_context_editor(cx)?.read(cx).context.clone())
}

fn open_saved_context(
pub fn open_saved_context(
&mut self,
path: PathBuf,
cx: &mut ViewContext<Self>,
Expand Down Expand Up @@ -1463,66 +1304,6 @@ impl prompt_library::InlineAssistDelegate for PromptLibraryInlineAssist {
}
}

pub struct ContextHistory {
picker: View<Picker<SavedContextPickerDelegate>>,
_subscriptions: Vec<Subscription>,
assistant_panel: WeakView<AssistantPanel>,
}

impl ContextHistory {
fn new(
project: Model<Project>,
context_store: Model<ContextStore>,
assistant_panel: WeakView<AssistantPanel>,
cx: &mut ViewContext<Self>,
) -> Self {
let picker = cx.new_view(|cx| {
Picker::uniform_list(
SavedContextPickerDelegate::new(project, context_store.clone()),
cx,
)
.modal(false)
.max_height(None)
});

let _subscriptions = vec![
cx.observe(&context_store, |this, _, cx| {
this.picker.update(cx, |picker, cx| picker.refresh(cx));
}),
cx.subscribe(&picker, Self::handle_picker_event),
];

Self {
picker,
_subscriptions,
assistant_panel,
}
}

fn handle_picker_event(
&mut self,
_: View<Picker<SavedContextPickerDelegate>>,
event: &SavedContextPickerEvent,
cx: &mut ViewContext<Self>,
) {
let SavedContextPickerEvent::Confirmed(context) = event;
self.assistant_panel
.update(cx, |assistant_panel, cx| match context {
ContextMetadata::Remote(metadata) => {
assistant_panel
.open_remote_context(metadata.id.clone(), cx)
.detach_and_log_err(cx);
}
ContextMetadata::Saved(metadata) => {
assistant_panel
.open_saved_context(metadata.path.clone(), cx)
.detach_and_log_err(cx);
}
})
.ok();
}
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum WorkflowAssistStatus {
Pending,
Expand All @@ -1531,28 +1312,6 @@ pub enum WorkflowAssistStatus {
Idle,
}

impl Render for ContextHistory {
fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
div().size_full().child(self.picker.clone())
}
}

impl FocusableView for ContextHistory {
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
self.picker.focus_handle(cx)
}
}

impl EventEmitter<()> for ContextHistory {}

impl Item for ContextHistory {
type Event = ();

fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
Some("History".into())
}
}

pub struct ConfigurationView {
focus_handle: FocusHandle,
configuration_views: HashMap<LanguageModelProviderId, AnyView>,
Expand Down
Loading

0 comments on commit b59dec9

Please sign in to comment.