mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
parent
8334374398
commit
05de47195c
7 changed files with 7 additions and 320 deletions
|
|
@ -74,8 +74,8 @@ use terminal::terminal_settings::TerminalSettings;
|
|||
use terminal_view::{TerminalView, terminal_panel::TerminalPanel};
|
||||
use theme_settings::ThemeSettings;
|
||||
use ui::{
|
||||
Button, Callout, ContextMenu, ContextMenuEntry, IconButton, PopoverMenu, PopoverMenuHandle,
|
||||
Tab, Tooltip, prelude::*, utils::WithRemSize,
|
||||
Button, ContextMenu, ContextMenuEntry, IconButton, PopoverMenu, PopoverMenuHandle, Tab,
|
||||
Tooltip, prelude::*, utils::WithRemSize,
|
||||
};
|
||||
use util::ResultExt as _;
|
||||
use workspace::{
|
||||
|
|
@ -705,7 +705,6 @@ pub struct AgentPanel {
|
|||
selected_agent: Agent,
|
||||
_thread_view_subscription: Option<Subscription>,
|
||||
_active_thread_focus_subscription: Option<Subscription>,
|
||||
show_trust_workspace_message: bool,
|
||||
_base_view_observation: Option<Subscription>,
|
||||
_draft_editor_observation: Option<Subscription>,
|
||||
_thread_metadata_store_subscription: Subscription,
|
||||
|
|
@ -1063,7 +1062,6 @@ impl AgentPanel {
|
|||
selected_agent: Agent::default(),
|
||||
_thread_view_subscription: None,
|
||||
_active_thread_focus_subscription: None,
|
||||
show_trust_workspace_message: false,
|
||||
new_user_onboarding_upsell_dismissed: AtomicBool::new(OnboardingUpsell::dismissed(cx)),
|
||||
_base_view_observation: None,
|
||||
_draft_editor_observation: None,
|
||||
|
|
@ -1288,20 +1286,6 @@ impl AgentPanel {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_thread(
|
||||
&mut self,
|
||||
source: &'static str,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> ThreadId {
|
||||
let agent = self.selected_agent(cx);
|
||||
let thread = self.create_agent_thread(agent, None, None, None, None, source, window, cx);
|
||||
let thread_id = thread.conversation_view.read(cx).thread_id;
|
||||
self.retained_threads
|
||||
.insert(thread_id, thread.conversation_view);
|
||||
thread_id
|
||||
}
|
||||
|
||||
pub fn activate_retained_thread(
|
||||
&mut self,
|
||||
id: ThreadId,
|
||||
|
|
@ -1320,30 +1304,6 @@ impl AgentPanel {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn remove_thread(&mut self, id: ThreadId, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.retained_threads.remove(&id);
|
||||
ThreadMetadataStore::global(cx).update(cx, |store, cx| {
|
||||
store.delete(id, cx);
|
||||
});
|
||||
|
||||
if self
|
||||
.draft_thread
|
||||
.as_ref()
|
||||
.is_some_and(|d| d.read(cx).thread_id == id)
|
||||
{
|
||||
self.draft_thread = None;
|
||||
self._draft_editor_observation = None;
|
||||
}
|
||||
|
||||
if self.active_thread_id(cx) == Some(id) {
|
||||
self.clear_overlay_state();
|
||||
self.activate_draft(false, "agent_panel", window, cx);
|
||||
self.serialize(cx);
|
||||
cx.emit(AgentPanelEvent::ActiveViewChanged);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn active_thread_id(&self, cx: &App) -> Option<ThreadId> {
|
||||
match &self.base_view {
|
||||
BaseView::AgentThread { conversation_view } => {
|
||||
|
|
@ -1374,28 +1334,6 @@ impl AgentPanel {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn clear_editor(&self, id: ThreadId, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let cv = self
|
||||
.retained_threads
|
||||
.get(&id)
|
||||
.or_else(|| match &self.base_view {
|
||||
BaseView::AgentThread { conversation_view }
|
||||
if conversation_view.read(cx).thread_id == id =>
|
||||
{
|
||||
Some(conversation_view)
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
let Some(cv) = cv else { return };
|
||||
let Some(tv) = cv.read(cx).root_thread_view() else {
|
||||
return;
|
||||
};
|
||||
let editor = tv.read(cx).message_editor.clone();
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.clear(window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
fn new_native_agent_thread_from_summary(
|
||||
&mut self,
|
||||
action: &NewNativeAgentThreadFromSummary,
|
||||
|
|
@ -2003,26 +1941,6 @@ impl AgentPanel {
|
|||
false
|
||||
}
|
||||
|
||||
/// active thread plus any background threads that are still running or
|
||||
/// completed but unseen.
|
||||
pub fn parent_threads(&self, cx: &App) -> Vec<Entity<ThreadView>> {
|
||||
let mut views = Vec::new();
|
||||
|
||||
if let Some(server_view) = self.active_conversation_view() {
|
||||
if let Some(thread_view) = server_view.read(cx).root_thread_view() {
|
||||
views.push(thread_view);
|
||||
}
|
||||
}
|
||||
|
||||
for server_view in self.retained_threads.values() {
|
||||
if let Some(thread_view) = server_view.read(cx).root_thread_view() {
|
||||
views.push(thread_view);
|
||||
}
|
||||
}
|
||||
|
||||
views
|
||||
}
|
||||
|
||||
fn update_thread_work_dirs(&self, cx: &mut Context<Self>) {
|
||||
let new_work_dirs = self.project.read(cx).default_path_list(cx);
|
||||
let new_worktree_paths = self.project.read(cx).worktree_paths(cx);
|
||||
|
|
@ -3594,38 +3512,6 @@ impl AgentPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_workspace_trust_message(&self, cx: &Context<Self>) -> Option<impl IntoElement> {
|
||||
if !self.show_trust_workspace_message {
|
||||
return None;
|
||||
}
|
||||
|
||||
let description = "To protect your system, third-party code—like MCP servers—won't run until you mark this workspace as safe.";
|
||||
|
||||
Some(
|
||||
Callout::new()
|
||||
.icon(IconName::Warning)
|
||||
.severity(Severity::Warning)
|
||||
.border_position(ui::BorderPosition::Bottom)
|
||||
.title("You're in Restricted Mode")
|
||||
.description(description)
|
||||
.actions_slot(
|
||||
Button::new("open-trust-modal", "Configure Project Trust")
|
||||
.label_size(LabelSize::Small)
|
||||
.style(ButtonStyle::Outlined)
|
||||
.on_click({
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
this.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
workspace
|
||||
.show_worktree_trust_security_modal(true, window, cx)
|
||||
})
|
||||
.log_err();
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn key_context(&self) -> KeyContext {
|
||||
let mut key_context = KeyContext::new_with_defaults();
|
||||
key_context.add("AgentPanel");
|
||||
|
|
@ -3675,7 +3561,6 @@ impl Render for AgentPanel {
|
|||
}
|
||||
}))
|
||||
.child(self.render_toolbar(window, cx))
|
||||
.children(self.render_workspace_trust_message(cx))
|
||||
.children(self.render_new_user_onboarding(window, cx))
|
||||
.map(|parent| match self.visible_surface() {
|
||||
VisibleSurface::Uninitialized => parent,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use acp_thread::{
|
||||
AcpThread, AcpThreadEvent, AgentSessionInfo, AgentThreadEntry, AssistantMessage,
|
||||
AssistantMessageChunk, AuthRequired, LoadError, MaxOutputTokensError, MentionUri,
|
||||
PermissionOptionChoice, PermissionOptions, PermissionPattern, RetryStatus,
|
||||
SelectedPermissionOutcome, ThreadStatus, ToolCall, ToolCallContent, ToolCallStatus,
|
||||
UserMessageId,
|
||||
AcpThread, AcpThreadEvent, AgentThreadEntry, AssistantMessage, AssistantMessageChunk,
|
||||
AuthRequired, LoadError, MaxOutputTokensError, MentionUri, PermissionOptionChoice,
|
||||
PermissionOptions, PermissionPattern, RetryStatus, SelectedPermissionOutcome, ThreadStatus,
|
||||
ToolCall, ToolCallContent, ToolCallStatus, UserMessageId,
|
||||
};
|
||||
use acp_thread::{AgentConnection, Plan};
|
||||
use action_log::{ActionLog, ActionLogTelemetry, DiffStats};
|
||||
|
|
@ -1335,10 +1334,6 @@ impl ConversationView {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn workspace(&self) -> &WeakEntity<Workspace> {
|
||||
&self.workspace
|
||||
}
|
||||
|
||||
pub fn agent_key(&self) -> &Agent {
|
||||
&self.connection_key
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,7 +312,6 @@ pub struct ThreadView {
|
|||
pub new_server_version_available: Option<SharedString>,
|
||||
pub resumed_without_history: bool,
|
||||
pub(crate) permission_selections: HashMap<acp::ToolCallId, PermissionSelection>,
|
||||
pub resume_thread_metadata: Option<AgentSessionInfo>,
|
||||
pub _cancel_task: Option<Task<()>>,
|
||||
_save_task: Option<Task<()>>,
|
||||
_draft_resolve_task: Option<Task<()>>,
|
||||
|
|
@ -538,7 +537,6 @@ impl ThreadView {
|
|||
is_loading_contents: false,
|
||||
new_server_version_available: None,
|
||||
permission_selections: HashMap::default(),
|
||||
resume_thread_metadata: None,
|
||||
_cancel_task: None,
|
||||
_save_task: None,
|
||||
_draft_resolve_task: None,
|
||||
|
|
@ -623,10 +621,6 @@ impl ThreadView {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_draft(&self, cx: &App) -> bool {
|
||||
self.thread.read(cx).entries().is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn as_native_connection(
|
||||
&self,
|
||||
cx: &App,
|
||||
|
|
@ -2164,43 +2158,6 @@ impl ThreadView {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn handle_open_rules(
|
||||
&mut self,
|
||||
_: &ClickEvent,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(thread) = self.as_native_thread(cx) else {
|
||||
return;
|
||||
};
|
||||
let project_context = thread.read(cx).project_context().read(cx);
|
||||
|
||||
let project_entry_ids = project_context
|
||||
.worktrees
|
||||
.iter()
|
||||
.flat_map(|worktree| worktree.rules_file.as_ref())
|
||||
.map(|rules_file| ProjectEntryId::from_usize(rules_file.project_entry_id))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.workspace
|
||||
.update(cx, move |workspace, cx| {
|
||||
// TODO: Open a multibuffer instead? In some cases this doesn't make the set of rules
|
||||
// files clear. For example, if rules file 1 is already open but rules file 2 is not,
|
||||
// this would open and focus rules file 2 in a tab that is not next to rules file 1.
|
||||
let project = workspace.project().read(cx);
|
||||
let project_paths = project_entry_ids
|
||||
.into_iter()
|
||||
.flat_map(|entry_id| project.path_for_entry(entry_id, cx))
|
||||
.collect::<Vec<_>>();
|
||||
for project_path in project_paths {
|
||||
workspace
|
||||
.open_path(project_path, None, true, window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn activity_bar_bg(&self, cx: &Context<Self>) -> Hsla {
|
||||
let editor_bg_color = cx.theme().colors().editor_background;
|
||||
let active_color = cx.theme().colors().element_selected;
|
||||
|
|
|
|||
|
|
@ -608,51 +608,6 @@ impl InlineAssistant {
|
|||
assist_to_focus
|
||||
}
|
||||
|
||||
pub fn suggest_assist(
|
||||
&mut self,
|
||||
editor: &Entity<Editor>,
|
||||
mut range: Range<Anchor>,
|
||||
initial_prompt: String,
|
||||
initial_transaction_id: Option<TransactionId>,
|
||||
focus: bool,
|
||||
workspace: Entity<Workspace>,
|
||||
thread_store: Entity<ThreadStore>,
|
||||
prompt_store: Option<Entity<PromptStore>>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> InlineAssistId {
|
||||
let buffer = editor.read(cx).buffer().clone();
|
||||
{
|
||||
let snapshot = buffer.read(cx).read(cx);
|
||||
range.start = range.start.bias_left(&snapshot);
|
||||
range.end = range.end.bias_right(&snapshot);
|
||||
}
|
||||
|
||||
let project = workspace.read(cx).project().downgrade();
|
||||
|
||||
let assist_id = self
|
||||
.batch_assist(
|
||||
editor,
|
||||
workspace.downgrade(),
|
||||
project,
|
||||
thread_store,
|
||||
prompt_store,
|
||||
Some(initial_prompt),
|
||||
window,
|
||||
&[range],
|
||||
None,
|
||||
initial_transaction_id,
|
||||
cx,
|
||||
)
|
||||
.expect("batch_assist returns an id if there's only one range");
|
||||
|
||||
if focus {
|
||||
self.focus_assist(assist_id, window, cx);
|
||||
}
|
||||
|
||||
assist_id
|
||||
}
|
||||
|
||||
fn insert_assist_blocks(
|
||||
&self,
|
||||
editor: &Entity<Editor>,
|
||||
|
|
|
|||
|
|
@ -1541,26 +1541,6 @@ pub enum CodegenStatus {
|
|||
Error(anyhow::Error),
|
||||
}
|
||||
|
||||
/// This is just CodegenStatus without the anyhow::Error, which causes a lifetime issue for rendering the Cancel button.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum CancelButtonState {
|
||||
Idle,
|
||||
Pending,
|
||||
Done,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl Into<CancelButtonState> for &CodegenStatus {
|
||||
fn into(self) -> CancelButtonState {
|
||||
match self {
|
||||
CodegenStatus::Idle => CancelButtonState::Idle,
|
||||
CodegenStatus::Pending => CancelButtonState::Pending,
|
||||
CodegenStatus::Done => CancelButtonState::Done,
|
||||
CodegenStatus::Error(_) => CancelButtonState::Error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum GenerationMode {
|
||||
Generate,
|
||||
|
|
|
|||
|
|
@ -186,11 +186,6 @@ impl MentionSet {
|
|||
self.mentions.drain()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn has_thread_store(&self) -> bool {
|
||||
self.thread_store.is_some()
|
||||
}
|
||||
|
||||
pub fn confirm_mention_completion(
|
||||
&mut self,
|
||||
crease_text: SharedString,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use rope::Point;
|
|||
use settings::Settings;
|
||||
use std::{fmt::Write, ops::Range, rc::Rc, sync::Arc};
|
||||
use theme_settings::ThemeSettings;
|
||||
use ui::{ContextMenu, Disclosure, ElevationIndex, prelude::*};
|
||||
use ui::{ContextMenu, prelude::*};
|
||||
use util::paths::PathStyle;
|
||||
use util::{ResultExt, debug_panic};
|
||||
use workspace::{CollaboratorId, Workspace};
|
||||
|
|
@ -1295,22 +1295,6 @@ impl MessageEditor {
|
|||
.detach();
|
||||
}
|
||||
|
||||
/// Inserts code snippets as creases into the editor.
|
||||
/// Each tuple contains (code_text, crease_title).
|
||||
pub fn insert_code_creases(
|
||||
&mut self,
|
||||
creases: Vec<(String, String)>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.insert("\n", window, cx);
|
||||
});
|
||||
for (text, crease_title) in creases {
|
||||
self.insert_crease_impl(text, crease_title, IconName::TextSnippet, true, window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_branch_diff_crease(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
|
|
@ -1391,70 +1375,6 @@ impl MessageEditor {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn insert_crease_impl(
|
||||
&mut self,
|
||||
text: String,
|
||||
title: String,
|
||||
icon: IconName,
|
||||
add_trailing_newline: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
use editor::display_map::{Crease, FoldPlaceholder};
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use rope::Point;
|
||||
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
let point = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
let start_row = MultiBufferRow(point.row);
|
||||
|
||||
editor.insert(&text, window, cx);
|
||||
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let anchor_before = snapshot.anchor_after(point);
|
||||
let anchor_after = editor
|
||||
.selections
|
||||
.newest_anchor()
|
||||
.head()
|
||||
.bias_left(&snapshot);
|
||||
|
||||
if add_trailing_newline {
|
||||
editor.insert("\n", window, cx);
|
||||
}
|
||||
|
||||
let fold_placeholder = FoldPlaceholder {
|
||||
render: Arc::new({
|
||||
let title = title.clone();
|
||||
move |_fold_id, _fold_range, _cx| {
|
||||
Button::new("crease", title.clone())
|
||||
.layer(ElevationIndex::ElevatedSurface)
|
||||
.start_icon(Icon::new(icon))
|
||||
.into_any_element()
|
||||
}
|
||||
}),
|
||||
merge_adjacent: false,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let crease = Crease::inline(
|
||||
anchor_before..anchor_after,
|
||||
fold_placeholder,
|
||||
|row, is_folded, fold, _window, _cx| {
|
||||
Disclosure::new(("crease-toggle", row.0 as u64), !is_folded)
|
||||
.toggle_state(is_folded)
|
||||
.on_click(move |_e, window, cx| fold(!is_folded, window, cx))
|
||||
.into_any_element()
|
||||
},
|
||||
|_, _, _, _| gpui::Empty.into_any(),
|
||||
);
|
||||
editor.insert_creases(vec![crease], cx);
|
||||
editor.fold_at(start_row, window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn insert_selections(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let editor = self.editor.read(cx);
|
||||
let editor_buffer = editor.buffer().read(cx);
|
||||
|
|
|
|||
Loading…
Reference in a new issue