Serialize and deserialize TerminalPanel
This commit is contained in:
parent
e49281699c
commit
5ff49bde31
3 changed files with 245 additions and 112 deletions
|
@ -1,15 +1,20 @@
|
||||||
use crate::TerminalView;
|
use crate::TerminalView;
|
||||||
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, anyhow, elements::*, AppContext, Entity, Subscription, View, ViewContext, ViewHandle,
|
actions, anyhow::Result, elements::*, serde_json, AppContext, AsyncAppContext, Entity,
|
||||||
WeakViewHandle, WindowContext,
|
Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::{settings_file::SettingsFile, Settings, TerminalDockPosition, WorkingDirectory};
|
use settings::{settings_file::SettingsFile, Settings, TerminalDockPosition, WorkingDirectory};
|
||||||
use util::ResultExt;
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel},
|
dock::{DockPosition, Panel},
|
||||||
|
item::Item,
|
||||||
pane, DraggedItem, Pane, Workspace,
|
pane, DraggedItem, Pane, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
|
||||||
|
|
||||||
actions!(terminal_panel, [ToggleFocus]);
|
actions!(terminal_panel, [ToggleFocus]);
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
|
@ -27,6 +32,7 @@ pub enum Event {
|
||||||
pub struct TerminalPanel {
|
pub struct TerminalPanel {
|
||||||
pane: ViewHandle<Pane>,
|
pane: ViewHandle<Pane>,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
pending_serialization: Task<Option<()>>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,10 +92,79 @@ impl TerminalPanel {
|
||||||
Self {
|
Self {
|
||||||
pane,
|
pane,
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
|
pending_serialization: Task::ready(None),
|
||||||
_subscriptions: subscriptions,
|
_subscriptions: subscriptions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load(
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
cx: AsyncAppContext,
|
||||||
|
) -> Task<Result<ViewHandle<Self>>> {
|
||||||
|
cx.spawn(|mut cx| async move {
|
||||||
|
let serialized_panel = if let Some(panel) = cx
|
||||||
|
.background()
|
||||||
|
.spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
Some(serde_json::from_str::<SerializedTerminalPanel>(&panel)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| {
|
||||||
|
let panel = cx.add_view(|cx| TerminalPanel::new(workspace, cx));
|
||||||
|
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
|
||||||
|
panel.update(cx, |panel, cx| {
|
||||||
|
panel.pane.update(cx, |_, cx| {
|
||||||
|
serialized_panel
|
||||||
|
.items
|
||||||
|
.iter()
|
||||||
|
.map(|item_id| {
|
||||||
|
TerminalView::deserialize(
|
||||||
|
workspace.project().clone(),
|
||||||
|
workspace.weak_handle(),
|
||||||
|
workspace.database_id(),
|
||||||
|
*item_id,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
};
|
||||||
|
let pane = panel.read(cx).pane.clone();
|
||||||
|
(panel, pane, items)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let items = futures::future::join_all(items).await;
|
||||||
|
workspace.update(&mut cx, |workspace, cx| {
|
||||||
|
let active_item_id = serialized_panel
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|panel| panel.active_item_id);
|
||||||
|
let mut active_ix = None;
|
||||||
|
for item in items {
|
||||||
|
if let Some(item) = item.log_err() {
|
||||||
|
let item_id = item.id();
|
||||||
|
Pane::add_item(workspace, &pane, Box::new(item), false, false, None, cx);
|
||||||
|
if Some(item_id) == active_item_id {
|
||||||
|
active_ix = Some(pane.read(cx).items_len() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(active_ix) = active_ix {
|
||||||
|
pane.update(cx, |pane, cx| {
|
||||||
|
pane.activate_item(active_ix, false, false, cx)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(panel)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_pane_event(
|
fn handle_pane_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_pane: ViewHandle<Pane>,
|
_pane: ViewHandle<Pane>,
|
||||||
|
@ -97,6 +172,8 @@ impl TerminalPanel {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
match event {
|
match event {
|
||||||
|
pane::Event::ActivateItem { .. } => self.serialize(cx),
|
||||||
|
pane::Event::RemoveItem { .. } => self.serialize(cx),
|
||||||
pane::Event::Remove => cx.emit(Event::Close),
|
pane::Event::Remove => cx.emit(Event::Close),
|
||||||
pane::Event::ZoomIn => cx.emit(Event::ZoomIn),
|
pane::Event::ZoomIn => cx.emit(Event::ZoomIn),
|
||||||
pane::Event::ZoomOut => cx.emit(Event::ZoomOut),
|
pane::Event::ZoomOut => cx.emit(Event::ZoomOut),
|
||||||
|
@ -131,10 +208,36 @@ impl TerminalPanel {
|
||||||
Pane::add_item(workspace, &pane, terminal, true, true, None, cx);
|
Pane::add_item(workspace, &pane, terminal, true, true, None, cx);
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
this.update(&mut cx, |this, cx| this.serialize(cx))?;
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
let items = self
|
||||||
|
.pane
|
||||||
|
.read(cx)
|
||||||
|
.items()
|
||||||
|
.map(|item| item.id())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let active_item_id = self.pane.read(cx).active_item().map(|item| item.id());
|
||||||
|
self.pending_serialization = cx.background().spawn(
|
||||||
|
async move {
|
||||||
|
KEY_VALUE_STORE
|
||||||
|
.write_kvp(
|
||||||
|
TERMINAL_PANEL_KEY.into(),
|
||||||
|
serde_json::to_string(&SerializedTerminalPanel {
|
||||||
|
items,
|
||||||
|
active_item_id,
|
||||||
|
})?,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
anyhow::Ok(())
|
||||||
|
}
|
||||||
|
.log_err(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for TerminalPanel {
|
impl Entity for TerminalPanel {
|
||||||
|
@ -255,3 +358,9 @@ impl Panel for TerminalPanel {
|
||||||
matches!(event, Event::Focus)
|
matches!(event, Event::Focus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct SerializedTerminalPanel {
|
||||||
|
items: Vec<usize>,
|
||||||
|
active_item_id: Option<usize>,
|
||||||
|
}
|
||||||
|
|
|
@ -361,7 +361,8 @@ pub struct AppState {
|
||||||
pub fs: Arc<dyn fs::Fs>,
|
pub fs: Arc<dyn fs::Fs>,
|
||||||
pub build_window_options:
|
pub build_window_options:
|
||||||
fn(Option<WindowBounds>, Option<uuid::Uuid>, &dyn Platform) -> WindowOptions<'static>,
|
fn(Option<WindowBounds>, Option<uuid::Uuid>, &dyn Platform) -> WindowOptions<'static>,
|
||||||
pub initialize_workspace: fn(&mut Workspace, bool, &Arc<AppState>, &mut ViewContext<Workspace>),
|
pub initialize_workspace:
|
||||||
|
fn(WeakViewHandle<Workspace>, bool, Arc<AppState>, AsyncAppContext) -> Task<Result<()>>,
|
||||||
pub background_actions: BackgroundActions,
|
pub background_actions: BackgroundActions,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +384,7 @@ impl AppState {
|
||||||
fs,
|
fs,
|
||||||
languages,
|
languages,
|
||||||
user_store,
|
user_store,
|
||||||
initialize_workspace: |_, _, _, _| {},
|
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||||
build_window_options: |_, _, _| Default::default(),
|
build_window_options: |_, _, _| Default::default(),
|
||||||
background_actions: || &[],
|
background_actions: || &[],
|
||||||
})
|
})
|
||||||
|
@ -730,31 +731,19 @@ impl Workspace {
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
|
||||||
let build_workspace =
|
let was_deserialized = serialized_workspace.is_some();
|
||||||
|cx: &mut ViewContext<Workspace>,
|
|
||||||
serialized_workspace: Option<SerializedWorkspace>| {
|
|
||||||
let was_deserialized = serialized_workspace.is_some();
|
|
||||||
let mut workspace = Workspace::new(
|
|
||||||
serialized_workspace,
|
|
||||||
workspace_id,
|
|
||||||
project_handle.clone(),
|
|
||||||
app_state.clone(),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
(app_state.initialize_workspace)(
|
|
||||||
&mut workspace,
|
|
||||||
was_deserialized,
|
|
||||||
&app_state,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
workspace
|
|
||||||
};
|
|
||||||
|
|
||||||
let workspace = requesting_window_id
|
let workspace = requesting_window_id
|
||||||
.and_then(|window_id| {
|
.and_then(|window_id| {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
cx.replace_root_view(window_id, |cx| {
|
cx.replace_root_view(window_id, |cx| {
|
||||||
build_workspace(cx, serialized_workspace.take())
|
Workspace::new(
|
||||||
|
serialized_workspace.take(),
|
||||||
|
workspace_id,
|
||||||
|
project_handle.clone(),
|
||||||
|
app_state.clone(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -794,11 +783,28 @@ impl Workspace {
|
||||||
// Use the serialized workspace to construct the new window
|
// Use the serialized workspace to construct the new window
|
||||||
cx.add_window(
|
cx.add_window(
|
||||||
(app_state.build_window_options)(bounds, display, cx.platform().as_ref()),
|
(app_state.build_window_options)(bounds, display, cx.platform().as_ref()),
|
||||||
|cx| build_workspace(cx, serialized_workspace),
|
|cx| {
|
||||||
|
Workspace::new(
|
||||||
|
serialized_workspace,
|
||||||
|
workspace_id,
|
||||||
|
project_handle.clone(),
|
||||||
|
app_state.clone(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.1
|
.1
|
||||||
});
|
});
|
||||||
|
|
||||||
|
(app_state.initialize_workspace)(
|
||||||
|
workspace.downgrade(),
|
||||||
|
was_deserialized,
|
||||||
|
app_state.clone(),
|
||||||
|
cx.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.log_err();
|
||||||
|
|
||||||
let workspace = workspace.downgrade();
|
let workspace = workspace.downgrade();
|
||||||
notify_if_database_failed(&workspace, &mut cx);
|
notify_if_database_failed(&workspace, &mut cx);
|
||||||
|
|
||||||
|
@ -2740,7 +2746,7 @@ impl Workspace {
|
||||||
user_store: project.read(cx).user_store(),
|
user_store: project.read(cx).user_store(),
|
||||||
fs: project.read(cx).fs().clone(),
|
fs: project.read(cx).fs().clone(),
|
||||||
build_window_options: |_, _, _| Default::default(),
|
build_window_options: |_, _, _| Default::default(),
|
||||||
initialize_workspace: |_, _, _, _| {},
|
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||||
background_actions: || &[],
|
background_actions: || &[],
|
||||||
});
|
});
|
||||||
Self::new(None, 0, project, app_state, cx)
|
Self::new(None, 0, project, app_state, cx)
|
||||||
|
@ -3097,12 +3103,17 @@ pub fn join_remote_project(
|
||||||
|
|
||||||
let (_, workspace) = cx.add_window(
|
let (_, workspace) = cx.add_window(
|
||||||
(app_state.build_window_options)(None, None, cx.platform().as_ref()),
|
(app_state.build_window_options)(None, None, cx.platform().as_ref()),
|
||||||
|cx| {
|
|cx| Workspace::new(None, 0, project, app_state.clone(), cx),
|
||||||
let mut workspace = Workspace::new(None, 0, project, app_state.clone(), cx);
|
|
||||||
(app_state.initialize_workspace)(&mut workspace, false, &app_state, cx);
|
|
||||||
workspace
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
(app_state.initialize_workspace)(
|
||||||
|
workspace.downgrade(),
|
||||||
|
false,
|
||||||
|
app_state.clone(),
|
||||||
|
cx.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.log_err();
|
||||||
|
|
||||||
workspace.downgrade()
|
workspace.downgrade()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,11 @@ use feedback::{
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
|
anyhow::{self, Result},
|
||||||
geometry::vector::vec2f,
|
geometry::vector::vec2f,
|
||||||
impl_actions,
|
impl_actions,
|
||||||
platform::{Platform, PromptLevel, TitlebarOptions, WindowBounds, WindowKind, WindowOptions},
|
platform::{Platform, PromptLevel, TitlebarOptions, WindowBounds, WindowKind, WindowOptions},
|
||||||
AppContext, ViewContext,
|
AppContext, AsyncAppContext, Task, ViewContext, WeakViewHandle,
|
||||||
};
|
};
|
||||||
pub use lsp;
|
pub use lsp;
|
||||||
pub use project;
|
pub use project;
|
||||||
|
@ -281,93 +282,105 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize_workspace(
|
pub fn initialize_workspace(
|
||||||
workspace: &mut Workspace,
|
workspace_handle: WeakViewHandle<Workspace>,
|
||||||
was_deserialized: bool,
|
was_deserialized: bool,
|
||||||
app_state: &Arc<AppState>,
|
app_state: Arc<AppState>,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: AsyncAppContext,
|
||||||
) {
|
) -> Task<Result<()>> {
|
||||||
let workspace_handle = cx.handle();
|
cx.spawn(|mut cx| async move {
|
||||||
cx.subscribe(&workspace_handle, {
|
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||||
move |workspace, _, event, cx| {
|
let workspace_handle = cx.handle();
|
||||||
if let workspace::Event::PaneAdded(pane) = event {
|
cx.subscribe(&workspace_handle, {
|
||||||
pane.update(cx, |pane, cx| {
|
move |workspace, _, event, cx| {
|
||||||
pane.toolbar().update(cx, |toolbar, cx| {
|
if let workspace::Event::PaneAdded(pane) = event {
|
||||||
let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
|
pane.update(cx, |pane, cx| {
|
||||||
toolbar.add_item(breadcrumbs, cx);
|
pane.toolbar().update(cx, |toolbar, cx| {
|
||||||
let buffer_search_bar = cx.add_view(BufferSearchBar::new);
|
let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
|
||||||
toolbar.add_item(buffer_search_bar, cx);
|
toolbar.add_item(breadcrumbs, cx);
|
||||||
let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
|
let buffer_search_bar = cx.add_view(BufferSearchBar::new);
|
||||||
toolbar.add_item(project_search_bar, cx);
|
toolbar.add_item(buffer_search_bar, cx);
|
||||||
let submit_feedback_button = cx.add_view(|_| SubmitFeedbackButton::new());
|
let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
|
||||||
toolbar.add_item(submit_feedback_button, cx);
|
toolbar.add_item(project_search_bar, cx);
|
||||||
let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
|
let submit_feedback_button =
|
||||||
toolbar.add_item(feedback_info_text, cx);
|
cx.add_view(|_| SubmitFeedbackButton::new());
|
||||||
let lsp_log_item = cx.add_view(|_| {
|
toolbar.add_item(submit_feedback_button, cx);
|
||||||
lsp_log::LspLogToolbarItemView::new(workspace.project().clone())
|
let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
|
||||||
|
toolbar.add_item(feedback_info_text, cx);
|
||||||
|
let lsp_log_item = cx.add_view(|_| {
|
||||||
|
lsp_log::LspLogToolbarItemView::new(workspace.project().clone())
|
||||||
|
});
|
||||||
|
toolbar.add_item(lsp_log_item, cx);
|
||||||
|
})
|
||||||
});
|
});
|
||||||
toolbar.add_item(lsp_log_item, cx);
|
}
|
||||||
})
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
|
|
||||||
cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
|
|
||||||
|
|
||||||
let collab_titlebar_item =
|
|
||||||
cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
|
|
||||||
workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
|
|
||||||
|
|
||||||
let project_panel = ProjectPanel::new(workspace, cx);
|
|
||||||
let project_panel_position = project_panel.position(cx);
|
|
||||||
workspace.add_panel(project_panel, cx);
|
|
||||||
if !was_deserialized
|
|
||||||
&& workspace
|
|
||||||
.project()
|
|
||||||
.read(cx)
|
|
||||||
.visible_worktrees(cx)
|
|
||||||
.any(|tree| {
|
|
||||||
tree.read(cx)
|
|
||||||
.root_entry()
|
|
||||||
.map_or(false, |entry| entry.is_dir())
|
|
||||||
})
|
})
|
||||||
{
|
.detach();
|
||||||
workspace.toggle_dock(project_panel_position, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
let terminal_panel = cx.add_view(|cx| TerminalPanel::new(workspace, cx));
|
cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
|
||||||
workspace.add_panel(terminal_panel, cx);
|
|
||||||
|
|
||||||
let copilot = cx.add_view(|cx| copilot_button::CopilotButton::new(cx));
|
let collab_titlebar_item =
|
||||||
let diagnostic_summary =
|
cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
|
||||||
cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
|
workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
|
||||||
let activity_indicator =
|
|
||||||
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
|
|
||||||
let active_buffer_language =
|
|
||||||
cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
|
||||||
let feedback_button =
|
|
||||||
cx.add_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace));
|
|
||||||
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
|
||||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
|
||||||
status_bar.add_left_item(diagnostic_summary, cx);
|
|
||||||
status_bar.add_left_item(activity_indicator, cx);
|
|
||||||
status_bar.add_right_item(feedback_button, cx);
|
|
||||||
status_bar.add_right_item(copilot, cx);
|
|
||||||
status_bar.add_right_item(active_buffer_language, cx);
|
|
||||||
status_bar.add_right_item(cursor_position, cx);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
|
let copilot = cx.add_view(|cx| copilot_button::CopilotButton::new(cx));
|
||||||
|
let diagnostic_summary =
|
||||||
|
cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
|
||||||
|
let activity_indicator = activity_indicator::ActivityIndicator::new(
|
||||||
|
workspace,
|
||||||
|
app_state.languages.clone(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
let active_buffer_language =
|
||||||
|
cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
||||||
|
let feedback_button = cx.add_view(|_| {
|
||||||
|
feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
|
||||||
|
});
|
||||||
|
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
||||||
|
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||||
|
status_bar.add_left_item(diagnostic_summary, cx);
|
||||||
|
status_bar.add_left_item(activity_indicator, cx);
|
||||||
|
status_bar.add_right_item(feedback_button, cx);
|
||||||
|
status_bar.add_right_item(copilot, cx);
|
||||||
|
status_bar.add_right_item(active_buffer_language, cx);
|
||||||
|
status_bar.add_right_item(cursor_position, cx);
|
||||||
|
});
|
||||||
|
|
||||||
vim::observe_keystrokes(cx);
|
auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
|
||||||
|
|
||||||
cx.on_window_should_close(|workspace, cx| {
|
vim::observe_keystrokes(cx);
|
||||||
if let Some(task) = workspace.close(&Default::default(), cx) {
|
|
||||||
task.detach_and_log_err(cx);
|
cx.on_window_should_close(|workspace, cx| {
|
||||||
}
|
if let Some(task) = workspace.close(&Default::default(), cx) {
|
||||||
false
|
task.detach_and_log_err(cx);
|
||||||
});
|
}
|
||||||
|
false
|
||||||
|
});
|
||||||
|
|
||||||
|
let project_panel = ProjectPanel::new(workspace, cx);
|
||||||
|
let project_panel_position = project_panel.position(cx);
|
||||||
|
workspace.add_panel(project_panel, cx);
|
||||||
|
if !was_deserialized
|
||||||
|
&& workspace
|
||||||
|
.project()
|
||||||
|
.read(cx)
|
||||||
|
.visible_worktrees(cx)
|
||||||
|
.any(|tree| {
|
||||||
|
tree.read(cx)
|
||||||
|
.root_entry()
|
||||||
|
.map_or(false, |entry| entry.is_dir())
|
||||||
|
})
|
||||||
|
{
|
||||||
|
workspace.toggle_dock(project_panel_position, cx);
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone()).await?;
|
||||||
|
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||||
|
workspace.add_panel(terminal_panel, cx)
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_window_options(
|
pub fn build_window_options(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue