Add the ability to follow the agent as it makes edits (#29839)
Nathan here: I also tacked on a bunch of UI refinement. Release Notes: - Introduced the ability to follow the agent around as it reads and edits files. --------- Co-authored-by: Nathan Sobo <nathan@zed.dev> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
425f32e068
commit
545ae27079
37 changed files with 1255 additions and 567 deletions
|
@ -68,9 +68,9 @@ use gpui::{
|
|||
};
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
Buffer, BufferEvent, Capability, CodeLabel, Language, LanguageName, LanguageRegistry,
|
||||
PointUtf16, ToOffset, ToPointUtf16, Toolchain, ToolchainList, Transaction, Unclipped,
|
||||
language_settings::InlayHintKind, proto::split_operations,
|
||||
Buffer, BufferEvent, Capability, CodeLabel, CursorShape, Language, LanguageName,
|
||||
LanguageRegistry, PointUtf16, ToOffset, ToPointUtf16, Toolchain, ToolchainList, Transaction,
|
||||
Unclipped, language_settings::InlayHintKind, proto::split_operations,
|
||||
};
|
||||
use lsp::{
|
||||
CodeActionKind, CompletionContext, CompletionItemKind, DocumentHighlightKind, InsertTextMode,
|
||||
|
@ -138,7 +138,7 @@ const MAX_PROJECT_SEARCH_HISTORY_SIZE: usize = 500;
|
|||
const MAX_SEARCH_RESULT_FILES: usize = 5_000;
|
||||
const MAX_SEARCH_RESULT_RANGES: usize = 10_000;
|
||||
|
||||
pub trait ProjectItem {
|
||||
pub trait ProjectItem: 'static {
|
||||
fn try_open(
|
||||
project: &Entity<Project>,
|
||||
path: &ProjectPath,
|
||||
|
@ -197,6 +197,13 @@ pub struct Project {
|
|||
environment: Entity<ProjectEnvironment>,
|
||||
settings_observer: Entity<SettingsObserver>,
|
||||
toolchain_store: Option<Entity<ToolchainStore>>,
|
||||
agent_location: Option<AgentLocation>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct AgentLocation {
|
||||
pub buffer: WeakEntity<Buffer>,
|
||||
pub position: Anchor,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -304,8 +311,11 @@ pub enum Event {
|
|||
RevealInProjectPanel(ProjectEntryId),
|
||||
SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>),
|
||||
ExpandedAllForEntry(WorktreeId, ProjectEntryId),
|
||||
AgentLocationChanged,
|
||||
}
|
||||
|
||||
pub struct AgentLocationChanged;
|
||||
|
||||
pub enum DebugAdapterClientState {
|
||||
Starting(Task<Option<Arc<DebugAdapterClient>>>),
|
||||
Running(Arc<DebugAdapterClient>),
|
||||
|
@ -986,6 +996,8 @@ impl Project {
|
|||
search_excluded_history: Self::new_search_history(),
|
||||
|
||||
toolchain_store: Some(toolchain_store),
|
||||
|
||||
agent_location: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1142,6 +1154,7 @@ impl Project {
|
|||
search_excluded_history: Self::new_search_history(),
|
||||
|
||||
toolchain_store: Some(toolchain_store),
|
||||
agent_location: None,
|
||||
};
|
||||
|
||||
// ssh -> local machine handlers
|
||||
|
@ -1381,6 +1394,7 @@ impl Project {
|
|||
environment,
|
||||
remotely_created_models: Arc::new(Mutex::new(RemotelyCreatedModels::default())),
|
||||
toolchain_store: None,
|
||||
agent_location: None,
|
||||
};
|
||||
this.set_role(role, cx);
|
||||
for worktree in worktrees {
|
||||
|
@ -4875,6 +4889,46 @@ impl Project {
|
|||
pub fn status_for_buffer_id(&self, buffer_id: BufferId, cx: &App) -> Option<FileStatus> {
|
||||
self.git_store.read(cx).status_for_buffer_id(buffer_id, cx)
|
||||
}
|
||||
|
||||
pub fn set_agent_location(
|
||||
&mut self,
|
||||
new_location: Option<AgentLocation>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(old_location) = self.agent_location.as_ref() {
|
||||
old_location
|
||||
.buffer
|
||||
.update(cx, |buffer, cx| buffer.remove_agent_selections(cx))
|
||||
.ok();
|
||||
}
|
||||
|
||||
if let Some(location) = new_location.as_ref() {
|
||||
location
|
||||
.buffer
|
||||
.update(cx, |buffer, cx| {
|
||||
buffer.set_agent_selections(
|
||||
Arc::from([language::Selection {
|
||||
id: 0,
|
||||
start: location.position,
|
||||
end: location.position,
|
||||
reversed: false,
|
||||
goal: language::SelectionGoal::None,
|
||||
}]),
|
||||
false,
|
||||
CursorShape::Hollow,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
self.agent_location = new_location;
|
||||
cx.emit(Event::AgentLocationChanged);
|
||||
}
|
||||
|
||||
pub fn agent_location(&self) -> Option<AgentLocation> {
|
||||
self.agent_location.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PathMatchCandidateSet {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue