crates/agent_ui/src/agent_ui.rs 🔗
@@ -12,7 +12,6 @@ mod context_strip;
mod inline_assistant;
mod inline_prompt_editor;
mod language_model_selector;
-mod message_editor;
mod profile_selector;
mod slash_command;
mod slash_command_picker;
Bennet Bo Fenner created
Artefact from agent1 removal
Release Notes:
- N/A
crates/agent_ui/src/agent_ui.rs | 1
crates/agent_ui/src/context_picker/completion_provider.rs | 2
crates/agent_ui/src/inline_prompt_editor.rs | 171 ++++++++
crates/agent_ui/src/message_editor.rs | 166 --------
4 files changed, 165 insertions(+), 175 deletions(-)
@@ -12,7 +12,6 @@ mod context_strip;
mod inline_assistant;
mod inline_prompt_editor;
mod language_model_selector;
-mod message_editor;
mod profile_selector;
mod slash_command;
mod slash_command_picker;
@@ -42,7 +42,7 @@ use super::{
ContextPickerAction, ContextPickerEntry, ContextPickerMode, MentionLink, RecentEntry,
available_context_picker_entries, recent_context_picker_entries_with_store, selection_ranges,
};
-use crate::message_editor::ContextCreasesAddon;
+use crate::inline_prompt_editor::ContextCreasesAddon;
pub(crate) enum Match {
File(FileMatch),
@@ -1,8 +1,8 @@
-use crate::context_store::ContextStore;
use agent::HistoryStore;
-use collections::VecDeque;
+use collections::{HashMap, VecDeque};
use editor::actions::Paste;
-use editor::display_map::EditorMargins;
+use editor::display_map::{CreaseId, EditorMargins};
+use editor::{Addon, AnchorRangeExt as _};
use editor::{
ContextMenuOptions, Editor, EditorElement, EditorEvent, EditorMode, EditorStyle, MultiBuffer,
actions::{MoveDown, MoveUp},
@@ -17,6 +17,7 @@ use parking_lot::Mutex;
use prompt_store::PromptStore;
use settings::Settings;
use std::cmp;
+use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
use theme::ThemeSettings;
@@ -27,12 +28,15 @@ use zed_actions::agent::ToggleModelSelector;
use crate::agent_model_selector::AgentModelSelector;
use crate::buffer_codegen::BufferCodegen;
-use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider};
+use crate::context::{AgentContextHandle, AgentContextKey};
+use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider, crease_for_mention};
+use crate::context_store::{ContextStore, ContextStoreEvent};
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
-use crate::message_editor::{ContextCreasesAddon, extract_message_creases, insert_message_creases};
use crate::terminal_codegen::TerminalCodegen;
-use crate::{CycleNextInlineAssist, CyclePreviousInlineAssist, ModelUsageContext};
-use crate::{RemoveAllContext, ToggleContextPicker};
+use crate::{
+ CycleNextInlineAssist, CyclePreviousInlineAssist, ModelUsageContext, RemoveAllContext,
+ ToggleContextPicker,
+};
pub struct PromptEditor<T> {
pub editor: Entity<Editor>,
@@ -1157,3 +1161,156 @@ impl GenerationMode {
}
}
}
+
+/// Stored information that can be used to resurrect a context crease when creating an editor for a past message.
+#[derive(Clone, Debug)]
+pub struct MessageCrease {
+ pub range: Range<usize>,
+ pub icon_path: SharedString,
+ pub label: SharedString,
+ /// None for a deserialized message, Some otherwise.
+ pub context: Option<AgentContextHandle>,
+}
+
+#[derive(Default)]
+pub struct ContextCreasesAddon {
+ creases: HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>>,
+ _subscription: Option<Subscription>,
+}
+
+impl Addon for ContextCreasesAddon {
+ fn to_any(&self) -> &dyn std::any::Any {
+ self
+ }
+
+ fn to_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
+ Some(self)
+ }
+}
+
+impl ContextCreasesAddon {
+ pub fn new() -> Self {
+ Self {
+ creases: HashMap::default(),
+ _subscription: None,
+ }
+ }
+
+ pub fn add_creases(
+ &mut self,
+ context_store: &Entity<ContextStore>,
+ key: AgentContextKey,
+ creases: impl IntoIterator<Item = (CreaseId, SharedString)>,
+ cx: &mut Context<Editor>,
+ ) {
+ self.creases.entry(key).or_default().extend(creases);
+ self._subscription = Some(
+ cx.subscribe(context_store, |editor, _, event, cx| match event {
+ ContextStoreEvent::ContextRemoved(key) => {
+ let Some(this) = editor.addon_mut::<Self>() else {
+ return;
+ };
+ let (crease_ids, replacement_texts): (Vec<_>, Vec<_>) = this
+ .creases
+ .remove(key)
+ .unwrap_or_default()
+ .into_iter()
+ .unzip();
+ let ranges = editor
+ .remove_creases(crease_ids, cx)
+ .into_iter()
+ .map(|(_, range)| range)
+ .collect::<Vec<_>>();
+ editor.unfold_ranges(&ranges, false, false, cx);
+ editor.edit(ranges.into_iter().zip(replacement_texts), cx);
+ cx.notify();
+ }
+ }),
+ )
+ }
+
+ pub fn into_inner(self) -> HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>> {
+ self.creases
+ }
+}
+
+pub fn extract_message_creases(
+ editor: &mut Editor,
+ cx: &mut Context<'_, Editor>,
+) -> Vec<MessageCrease> {
+ let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
+ let mut contexts_by_crease_id = editor
+ .addon_mut::<ContextCreasesAddon>()
+ .map(std::mem::take)
+ .unwrap_or_default()
+ .into_inner()
+ .into_iter()
+ .flat_map(|(key, creases)| {
+ let context = key.0;
+ creases
+ .into_iter()
+ .map(move |(id, _)| (id, context.clone()))
+ })
+ .collect::<HashMap<_, _>>();
+ // Filter the addon's list of creases based on what the editor reports,
+ // since the addon might have removed creases in it.
+
+ editor.display_map.update(cx, |display_map, cx| {
+ display_map
+ .snapshot(cx)
+ .crease_snapshot
+ .creases()
+ .filter_map(|(id, crease)| {
+ Some((
+ id,
+ (
+ crease.range().to_offset(&buffer_snapshot),
+ crease.metadata()?.clone(),
+ ),
+ ))
+ })
+ .map(|(id, (range, metadata))| {
+ let context = contexts_by_crease_id.remove(&id);
+ MessageCrease {
+ range,
+ context,
+ label: metadata.label,
+ icon_path: metadata.icon_path,
+ }
+ })
+ .collect()
+ })
+}
+
+pub fn insert_message_creases(
+ editor: &mut Editor,
+ message_creases: &[MessageCrease],
+ context_store: &Entity<ContextStore>,
+ window: &mut Window,
+ cx: &mut Context<'_, Editor>,
+) {
+ let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
+ let creases = message_creases
+ .iter()
+ .map(|crease| {
+ let start = buffer_snapshot.anchor_after(crease.range.start);
+ let end = buffer_snapshot.anchor_before(crease.range.end);
+ crease_for_mention(
+ crease.label.clone(),
+ crease.icon_path.clone(),
+ start..end,
+ cx.weak_entity(),
+ )
+ })
+ .collect::<Vec<_>>();
+ let ids = editor.insert_creases(creases.clone(), cx);
+ editor.fold_creases(creases, false, window, cx);
+ if let Some(addon) = editor.addon_mut::<ContextCreasesAddon>() {
+ for (crease, id) in message_creases.iter().zip(ids) {
+ if let Some(context) = crease.context.as_ref() {
+ let key = AgentContextKey(context.clone());
+ addon.add_creases(context_store, key, vec![(id, crease.label.clone())], cx);
+ }
+ }
+ }
+}
@@ -1,166 +0,0 @@
-use std::ops::Range;
-
-use collections::HashMap;
-use editor::display_map::CreaseId;
-use editor::{Addon, AnchorRangeExt, Editor};
-use gpui::{Entity, Subscription};
-use ui::prelude::*;
-
-use crate::{
- context::{AgentContextHandle, AgentContextKey},
- context_picker::crease_for_mention,
- context_store::{ContextStore, ContextStoreEvent},
-};
-
-/// Stored information that can be used to resurrect a context crease when creating an editor for a past message.
-#[derive(Clone, Debug)]
-pub struct MessageCrease {
- pub range: Range<usize>,
- pub icon_path: SharedString,
- pub label: SharedString,
- /// None for a deserialized message, Some otherwise.
- pub context: Option<AgentContextHandle>,
-}
-
-#[derive(Default)]
-pub struct ContextCreasesAddon {
- creases: HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>>,
- _subscription: Option<Subscription>,
-}
-
-impl Addon for ContextCreasesAddon {
- fn to_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn to_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
- Some(self)
- }
-}
-
-impl ContextCreasesAddon {
- pub fn new() -> Self {
- Self {
- creases: HashMap::default(),
- _subscription: None,
- }
- }
-
- pub fn add_creases(
- &mut self,
- context_store: &Entity<ContextStore>,
- key: AgentContextKey,
- creases: impl IntoIterator<Item = (CreaseId, SharedString)>,
- cx: &mut Context<Editor>,
- ) {
- self.creases.entry(key).or_default().extend(creases);
- self._subscription = Some(
- cx.subscribe(context_store, |editor, _, event, cx| match event {
- ContextStoreEvent::ContextRemoved(key) => {
- let Some(this) = editor.addon_mut::<Self>() else {
- return;
- };
- let (crease_ids, replacement_texts): (Vec<_>, Vec<_>) = this
- .creases
- .remove(key)
- .unwrap_or_default()
- .into_iter()
- .unzip();
- let ranges = editor
- .remove_creases(crease_ids, cx)
- .into_iter()
- .map(|(_, range)| range)
- .collect::<Vec<_>>();
- editor.unfold_ranges(&ranges, false, false, cx);
- editor.edit(ranges.into_iter().zip(replacement_texts), cx);
- cx.notify();
- }
- }),
- )
- }
-
- pub fn into_inner(self) -> HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>> {
- self.creases
- }
-}
-
-pub fn extract_message_creases(
- editor: &mut Editor,
- cx: &mut Context<'_, Editor>,
-) -> Vec<MessageCrease> {
- let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
- let mut contexts_by_crease_id = editor
- .addon_mut::<ContextCreasesAddon>()
- .map(std::mem::take)
- .unwrap_or_default()
- .into_inner()
- .into_iter()
- .flat_map(|(key, creases)| {
- let context = key.0;
- creases
- .into_iter()
- .map(move |(id, _)| (id, context.clone()))
- })
- .collect::<HashMap<_, _>>();
- // Filter the addon's list of creases based on what the editor reports,
- // since the addon might have removed creases in it.
-
- editor.display_map.update(cx, |display_map, cx| {
- display_map
- .snapshot(cx)
- .crease_snapshot
- .creases()
- .filter_map(|(id, crease)| {
- Some((
- id,
- (
- crease.range().to_offset(&buffer_snapshot),
- crease.metadata()?.clone(),
- ),
- ))
- })
- .map(|(id, (range, metadata))| {
- let context = contexts_by_crease_id.remove(&id);
- MessageCrease {
- range,
- context,
- label: metadata.label,
- icon_path: metadata.icon_path,
- }
- })
- .collect()
- })
-}
-
-pub fn insert_message_creases(
- editor: &mut Editor,
- message_creases: &[MessageCrease],
- context_store: &Entity<ContextStore>,
- window: &mut Window,
- cx: &mut Context<'_, Editor>,
-) {
- let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
- let creases = message_creases
- .iter()
- .map(|crease| {
- let start = buffer_snapshot.anchor_after(crease.range.start);
- let end = buffer_snapshot.anchor_before(crease.range.end);
- crease_for_mention(
- crease.label.clone(),
- crease.icon_path.clone(),
- start..end,
- cx.weak_entity(),
- )
- })
- .collect::<Vec<_>>();
- let ids = editor.insert_creases(creases.clone(), cx);
- editor.fold_creases(creases, false, window, cx);
- if let Some(addon) = editor.addon_mut::<ContextCreasesAddon>() {
- for (crease, id) in message_creases.iter().zip(ids) {
- if let Some(context) = crease.context.as_ref() {
- let key = AgentContextKey(context.clone());
- addon.add_creases(context_store, key, vec![(id, crease.label.clone())], cx);
- }
- }
- }
-}