@@ -458,6 +458,12 @@ impl AssistantPanel {
pub(crate) fn active_context_editor(&self) -> Option<Entity<ContextEditor>> {
self.context_editor.clone()
}
+
+ pub(crate) fn delete_context(&mut self, path: PathBuf, cx: &mut Context<Self>) {
+ self.context_store
+ .update(cx, |this, cx| this.delete_local_context(path, cx))
+ .detach_and_log_err(cx);
+ }
}
impl Focusable for AssistantPanel {
@@ -134,7 +134,13 @@ impl ThreadHistory {
})
.ok();
}
- HistoryEntry::Context(_context) => {}
+ HistoryEntry::Context(context) => {
+ self.assistant_panel
+ .update(cx, |this, cx| {
+ this.delete_context(context.path.clone(), cx);
+ })
+ .ok();
+ }
}
cx.notify();
@@ -344,11 +350,30 @@ impl RenderOnce for PastContext {
.spacing(ListItemSpacing::Sparse)
.child(Label::new(summary).size(LabelSize::Small).text_ellipsis())
.end_slot(
- h_flex().gap_1p5().child(
- Label::new(context_timestamp)
- .color(Color::Muted)
- .size(LabelSize::XSmall),
- ),
+ h_flex()
+ .gap_1p5()
+ .child(
+ Label::new(context_timestamp)
+ .color(Color::Muted)
+ .size(LabelSize::XSmall),
+ )
+ .child(
+ IconButton::new("delete", IconName::TrashAlt)
+ .shape(IconButtonShape::Square)
+ .icon_size(IconSize::XSmall)
+ .tooltip(Tooltip::text("Delete Prompt Editor"))
+ .on_click({
+ let assistant_panel = self.assistant_panel.clone();
+ let path = self.context.path.clone();
+ move |_event, _window, cx| {
+ assistant_panel
+ .update(cx, |this, cx| {
+ this.delete_context(path.clone(), cx);
+ })
+ .ok();
+ }
+ }),
+ ),
)
.on_click({
let assistant_panel = self.assistant_panel.clone();
@@ -9,7 +9,7 @@ use clock::ReplicaId;
use collections::HashMap;
use context_server::manager::ContextServerManager;
use context_server::ContextServerFactoryRegistry;
-use fs::Fs;
+use fs::{Fs, RemoveOptions};
use futures::StreamExt;
use fuzzy::StringMatchCandidate;
use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
@@ -475,6 +475,38 @@ impl ContextStore {
})
}
+ pub fn delete_local_context(
+ &mut self,
+ path: PathBuf,
+ cx: &mut Context<Self>,
+ ) -> Task<Result<()>> {
+ let fs = self.fs.clone();
+
+ cx.spawn(|this, mut cx| async move {
+ fs.remove_file(
+ &path,
+ RemoveOptions {
+ recursive: false,
+ ignore_if_not_exists: true,
+ },
+ )
+ .await?;
+
+ this.update(&mut cx, |this, cx| {
+ this.contexts.retain(|context| {
+ context
+ .upgrade()
+ .and_then(|context| context.read(cx).path())
+ != Some(&path)
+ });
+ this.contexts_metadata
+ .retain(|context| context.path != path);
+ })?;
+
+ Ok(())
+ })
+ }
+
fn loaded_context_for_path(&self, path: &Path, cx: &App) -> Option<Entity<AssistantContext>> {
self.contexts.iter().find_map(|context| {
let context = context.upgrade()?;