Compare commits
3 Commits
git-clone
...
debug-proj
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d41e6aa35 | ||
|
|
5d0bf9904e | ||
|
|
1ca4cfe2f8 |
@@ -341,7 +341,7 @@ impl AssistantPanel {
|
|||||||
let pane = cx.new_view(|cx| {
|
let pane = cx.new_view(|cx| {
|
||||||
let mut pane = Pane::new(
|
let mut pane = Pane::new(
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
workspace.project().clone(),
|
workspace.project().downgrade(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
None,
|
None,
|
||||||
NewContext.boxed_clone(),
|
NewContext.boxed_clone(),
|
||||||
|
|||||||
@@ -134,8 +134,11 @@ impl InlineAssistant {
|
|||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
let workspace = workspace.clone();
|
let workspace = workspace.downgrade();
|
||||||
cx.observe_global::<SettingsStore>(move |cx| {
|
cx.observe_global::<SettingsStore>(move |cx| {
|
||||||
|
let Some(workspace) = workspace.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let Some(terminal_panel) = workspace.read(cx).panel::<TerminalPanel>(cx) else {
|
let Some(terminal_panel) = workspace.read(cx).panel::<TerminalPanel>(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1054,12 +1054,28 @@ impl SerializableItem for Editor {
|
|||||||
let buffer = buffer_task.await?;
|
let buffer = buffer_task.await?;
|
||||||
|
|
||||||
pane.update(&mut cx, |_, cx| {
|
pane.update(&mut cx, |_, cx| {
|
||||||
cx.new_view(|cx| {
|
let editor = cx.new_view(|cx| {
|
||||||
let mut editor = Editor::for_buffer(buffer, Some(project), cx);
|
let mut editor = Editor::for_buffer(buffer, Some(project), cx);
|
||||||
|
|
||||||
editor.read_scroll_position_from_db(item_id, workspace_id, cx);
|
editor.read_scroll_position_from_db(item_id, workspace_id, cx);
|
||||||
editor
|
editor
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// let weak = editor.model.downgrade();
|
||||||
|
// cx.spawn(|_, cx| async move {
|
||||||
|
// for i in 0..5 {
|
||||||
|
// println!("{i}/5: going to sleep for 5 seconds");
|
||||||
|
// cx.background_executor()
|
||||||
|
// .timer(std::time::Duration::from_secs(5))
|
||||||
|
// .await;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// println!("done sleeping");
|
||||||
|
// weak.assert_released();
|
||||||
|
// })
|
||||||
|
// .detach();
|
||||||
|
|
||||||
|
editor
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ workspace = true
|
|||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
test-support = [
|
test-support = [
|
||||||
"backtrace",
|
|
||||||
"collections/test-support",
|
"collections/test-support",
|
||||||
"rand",
|
"rand",
|
||||||
"util/test-support",
|
"util/test-support",
|
||||||
@@ -29,7 +28,7 @@ doctest = false
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
async-task = "4.7"
|
async-task = "4.7"
|
||||||
backtrace = { version = "0.3", optional = true }
|
backtrace = { version = "0.3" }
|
||||||
blade-graphics = { workspace = true, optional = true }
|
blade-graphics = { workspace = true, optional = true }
|
||||||
blade-macros = { workspace = true, optional = true }
|
blade-macros = { workspace = true, optional = true }
|
||||||
blade-util = { workspace = true, optional = true }
|
blade-util = { workspace = true, optional = true }
|
||||||
|
|||||||
@@ -362,6 +362,7 @@ impl AppContext {
|
|||||||
let result = update(self);
|
let result = update(self);
|
||||||
if !self.flushing_effects && self.pending_updates == 1 {
|
if !self.flushing_effects && self.pending_updates == 1 {
|
||||||
self.flushing_effects = true;
|
self.flushing_effects = true;
|
||||||
|
println!("flushing effects");
|
||||||
self.flush_effects();
|
self.flush_effects();
|
||||||
self.flushing_effects = false;
|
self.flushing_effects = false;
|
||||||
}
|
}
|
||||||
@@ -706,6 +707,7 @@ impl AppContext {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.pending_effects.push_back(effect);
|
self.pending_effects.push_back(effect);
|
||||||
|
// If we're not in an update call; schedule one (somehow)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called at the end of [`AppContext::update`] to complete any side effects
|
/// Called at the end of [`AppContext::update`] to complete any side effects
|
||||||
@@ -765,6 +767,7 @@ impl AppContext {
|
|||||||
/// reference count has become zero. We invoke any release observers before dropping
|
/// reference count has become zero. We invoke any release observers before dropping
|
||||||
/// each entity.
|
/// each entity.
|
||||||
fn release_dropped_entities(&mut self) {
|
fn release_dropped_entities(&mut self) {
|
||||||
|
// println!("releasing dropped entities");
|
||||||
loop {
|
loop {
|
||||||
let dropped = self.entities.take_dropped();
|
let dropped = self.entities.take_dropped();
|
||||||
if dropped.is_empty() {
|
if dropped.is_empty() {
|
||||||
@@ -1398,6 +1401,7 @@ impl Context for AppContext {
|
|||||||
if window.removed {
|
if window.removed {
|
||||||
cx.window_handles.remove(&handle.id);
|
cx.window_handles.remove(&handle.id);
|
||||||
cx.windows.remove(handle.id);
|
cx.windows.remove(handle.id);
|
||||||
|
cx.flush_effects();
|
||||||
} else {
|
} else {
|
||||||
cx.windows
|
cx.windows
|
||||||
.get_mut(handle.id)
|
.get_mut(handle.id)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use std::{
|
|||||||
thread::panicking,
|
thread::panicking,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
|
||||||
slotmap::new_key_type! {
|
slotmap::new_key_type! {
|
||||||
@@ -57,7 +57,7 @@ pub(crate) struct EntityMap {
|
|||||||
struct EntityRefCounts {
|
struct EntityRefCounts {
|
||||||
counts: SlotMap<EntityId, AtomicUsize>,
|
counts: SlotMap<EntityId, AtomicUsize>,
|
||||||
dropped_entity_ids: Vec<EntityId>,
|
dropped_entity_ids: Vec<EntityId>,
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
leak_detector: LeakDetector,
|
leak_detector: LeakDetector,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ impl EntityMap {
|
|||||||
ref_counts: Arc::new(RwLock::new(EntityRefCounts {
|
ref_counts: Arc::new(RwLock::new(EntityRefCounts {
|
||||||
counts: SlotMap::with_key(),
|
counts: SlotMap::with_key(),
|
||||||
dropped_entity_ids: Vec::new(),
|
dropped_entity_ids: Vec::new(),
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
leak_detector: LeakDetector {
|
leak_detector: LeakDetector {
|
||||||
next_handle_id: 0,
|
next_handle_id: 0,
|
||||||
entity_handles: HashMap::default(),
|
entity_handles: HashMap::default(),
|
||||||
@@ -193,7 +193,7 @@ pub struct AnyModel {
|
|||||||
pub(crate) entity_id: EntityId,
|
pub(crate) entity_id: EntityId,
|
||||||
pub(crate) entity_type: TypeId,
|
pub(crate) entity_type: TypeId,
|
||||||
entity_map: Weak<RwLock<EntityRefCounts>>,
|
entity_map: Weak<RwLock<EntityRefCounts>>,
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
handle_id: HandleId,
|
handle_id: HandleId,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ impl AnyModel {
|
|||||||
entity_id: id,
|
entity_id: id,
|
||||||
entity_type,
|
entity_type,
|
||||||
entity_map: entity_map.clone(),
|
entity_map: entity_map.clone(),
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
handle_id: entity_map
|
handle_id: entity_map
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -262,7 +262,7 @@ impl Clone for AnyModel {
|
|||||||
entity_id: self.entity_id,
|
entity_id: self.entity_id,
|
||||||
entity_type: self.entity_type,
|
entity_type: self.entity_type,
|
||||||
entity_map: self.entity_map.clone(),
|
entity_map: self.entity_map.clone(),
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
handle_id: self
|
handle_id: self
|
||||||
.entity_map
|
.entity_map
|
||||||
.upgrade()
|
.upgrade()
|
||||||
@@ -291,8 +291,9 @@ impl Drop for AnyModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
if let Some(entity_map) = self.entity_map.upgrade() {
|
if let Some(entity_map) = self.entity_map.upgrade() {
|
||||||
|
// println!("dropped model");
|
||||||
entity_map
|
entity_map
|
||||||
.write()
|
.write()
|
||||||
.leak_detector
|
.leak_detector
|
||||||
@@ -504,7 +505,7 @@ impl AnyWeakModel {
|
|||||||
entity_id: self.entity_id,
|
entity_id: self.entity_id,
|
||||||
entity_type: self.entity_type,
|
entity_type: self.entity_type,
|
||||||
entity_map: self.entity_ref_counts.clone(),
|
entity_map: self.entity_ref_counts.clone(),
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
handle_id: self
|
handle_id: self
|
||||||
.entity_ref_counts
|
.entity_ref_counts
|
||||||
.upgrade()
|
.upgrade()
|
||||||
@@ -516,7 +517,7 @@ impl AnyWeakModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Assert that model referenced by this weak handle has been released.
|
/// Assert that model referenced by this weak handle has been released.
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
pub fn assert_released(&self) {
|
pub fn assert_released(&self) {
|
||||||
self.entity_ref_counts
|
self.entity_ref_counts
|
||||||
.upgrade()
|
.upgrade()
|
||||||
@@ -641,23 +642,23 @@ impl<T> PartialEq<Model<T>> for WeakModel<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
static LEAK_BACKTRACE: std::sync::LazyLock<bool> =
|
static LEAK_BACKTRACE: std::sync::LazyLock<bool> =
|
||||||
std::sync::LazyLock::new(|| std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty()));
|
std::sync::LazyLock::new(|| std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty()));
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
|
||||||
pub(crate) struct HandleId {
|
pub(crate) struct HandleId {
|
||||||
id: u64, // id of the handle itself, not the pointed at object
|
id: u64, // id of the handle itself, not the pointed at object
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
pub(crate) struct LeakDetector {
|
pub(crate) struct LeakDetector {
|
||||||
next_handle_id: u64,
|
next_handle_id: u64,
|
||||||
entity_handles: HashMap<EntityId, HashMap<HandleId, Option<backtrace::Backtrace>>>,
|
entity_handles: HashMap<EntityId, HashMap<HandleId, Option<backtrace::Backtrace>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
impl LeakDetector {
|
impl LeakDetector {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn handle_created(&mut self, entity_id: EntityId) -> HandleId {
|
pub fn handle_created(&mut self, entity_id: EntityId) -> HandleId {
|
||||||
@@ -666,7 +667,7 @@ impl LeakDetector {
|
|||||||
let handles = self.entity_handles.entry(entity_id).or_default();
|
let handles = self.entity_handles.entry(entity_id).or_default();
|
||||||
handles.insert(
|
handles.insert(
|
||||||
handle_id,
|
handle_id,
|
||||||
LEAK_BACKTRACE.then(backtrace::Backtrace::new_unresolved),
|
LEAK_BACKTRACE.then(|| backtrace::Backtrace::new_unresolved()),
|
||||||
);
|
);
|
||||||
handle_id
|
handle_id
|
||||||
}
|
}
|
||||||
@@ -679,7 +680,7 @@ impl LeakDetector {
|
|||||||
pub fn assert_released(&mut self, entity_id: EntityId) {
|
pub fn assert_released(&mut self, entity_id: EntityId) {
|
||||||
let handles = self.entity_handles.entry(entity_id).or_default();
|
let handles = self.entity_handles.entry(entity_id).or_default();
|
||||||
if !handles.is_empty() {
|
if !handles.is_empty() {
|
||||||
for backtrace in handles.values_mut() {
|
for (_, backtrace) in handles {
|
||||||
if let Some(mut backtrace) = backtrace.take() {
|
if let Some(mut backtrace) = backtrace.take() {
|
||||||
backtrace.resolve();
|
backtrace.resolve();
|
||||||
eprintln!("Leaked handle: {:#?}", backtrace);
|
eprintln!("Leaked handle: {:#?}", backtrace);
|
||||||
|
|||||||
@@ -926,7 +926,15 @@ impl<'a> WindowContext<'a> {
|
|||||||
|
|
||||||
/// Close this window.
|
/// Close this window.
|
||||||
pub fn remove_window(&mut self) {
|
pub fn remove_window(&mut self) {
|
||||||
|
println!("remove window!");
|
||||||
self.window.removed = true;
|
self.window.removed = true;
|
||||||
|
|
||||||
|
// self.spawn(|cx| {
|
||||||
|
// for _ in 0..10 {
|
||||||
|
// cx.background_executor().timer(Duration::from_secs(1)).await;
|
||||||
|
// AsyncAppContext::update(&mut cx, |cx| cx.update(|cx| {})).ok();
|
||||||
|
// })
|
||||||
|
// .detach()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus
|
/// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ pub struct OutlinePanel {
|
|||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
width: Option<Pixels>,
|
width: Option<Pixels>,
|
||||||
project: Model<Project>,
|
project: Model<Project>,
|
||||||
workspace: View<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
active: bool,
|
active: bool,
|
||||||
pinned: bool,
|
pinned: bool,
|
||||||
scroll_handle: UniformListScrollHandle,
|
scroll_handle: UniformListScrollHandle,
|
||||||
@@ -607,7 +607,7 @@ impl OutlinePanel {
|
|||||||
|
|
||||||
fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
|
fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
|
||||||
let project = workspace.project().clone();
|
let project = workspace.project().clone();
|
||||||
let workspace_handle = cx.view().clone();
|
let workspace_handle = cx.view().downgrade();
|
||||||
let outline_panel = cx.new_view(|cx| {
|
let outline_panel = cx.new_view(|cx| {
|
||||||
let filter_editor = cx.new_view(|cx| {
|
let filter_editor = cx.new_view(|cx| {
|
||||||
let mut editor = Editor::single_line(cx);
|
let mut editor = Editor::single_line(cx);
|
||||||
@@ -865,7 +865,8 @@ impl OutlinePanel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some((offset, anchor)) = scroll_target {
|
if let Some((offset, anchor)) = scroll_target {
|
||||||
self.workspace
|
let activate = self
|
||||||
|
.workspace
|
||||||
.update(cx, |workspace, cx| match self.active_item() {
|
.update(cx, |workspace, cx| match self.active_item() {
|
||||||
Some(active_item) => {
|
Some(active_item) => {
|
||||||
workspace.activate_item(active_item.as_ref(), true, change_selection, cx)
|
workspace.activate_item(active_item.as_ref(), true, change_selection, cx)
|
||||||
@@ -873,21 +874,23 @@ impl OutlinePanel {
|
|||||||
None => workspace.activate_item(&active_editor, true, change_selection, cx),
|
None => workspace.activate_item(&active_editor, true, change_selection, cx),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.select_entry(entry.clone(), true, cx);
|
if activate.is_ok() {
|
||||||
if change_selection {
|
self.select_entry(entry.clone(), true, cx);
|
||||||
active_editor.update(cx, |editor, cx| {
|
if change_selection {
|
||||||
editor.change_selections(
|
active_editor.update(cx, |editor, cx| {
|
||||||
Some(Autoscroll::Strategy(AutoscrollStrategy::Top)),
|
editor.change_selections(
|
||||||
cx,
|
Some(Autoscroll::Strategy(AutoscrollStrategy::Top)),
|
||||||
|s| s.select_ranges(Some(anchor..anchor)),
|
cx,
|
||||||
);
|
|s| s.select_ranges(Some(anchor..anchor)),
|
||||||
});
|
);
|
||||||
active_editor.focus_handle(cx).focus(cx);
|
});
|
||||||
} else {
|
active_editor.focus_handle(cx).focus(cx);
|
||||||
active_editor.update(cx, |editor, cx| {
|
} else {
|
||||||
editor.set_scroll_anchor(ScrollAnchor { offset, anchor }, cx);
|
active_editor.update(cx, |editor, cx| {
|
||||||
});
|
editor.set_scroll_anchor(ScrollAnchor { offset, anchor }, cx);
|
||||||
self.focus_handle.focus(cx);
|
});
|
||||||
|
self.focus_handle.focus(cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3316,7 +3319,11 @@ impl OutlinePanel {
|
|||||||
let buffer_search = self
|
let buffer_search = self
|
||||||
.active_item()
|
.active_item()
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.and_then(|active_item| self.workspace.read(cx).pane_for(active_item))
|
.and_then(|active_item| {
|
||||||
|
self.workspace
|
||||||
|
.upgrade()
|
||||||
|
.and_then(|workspace| workspace.read(cx).pane_for(active_item))
|
||||||
|
})
|
||||||
.and_then(|pane| {
|
.and_then(|pane| {
|
||||||
pane.read(cx)
|
pane.read(cx)
|
||||||
.toolbar()
|
.toolbar()
|
||||||
@@ -3567,8 +3574,10 @@ impl OutlinePanel {
|
|||||||
) {
|
) {
|
||||||
self.pinned = !self.pinned;
|
self.pinned = !self.pinned;
|
||||||
if !self.pinned {
|
if !self.pinned {
|
||||||
if let Some((active_item, active_editor)) =
|
if let Some((active_item, active_editor)) = self
|
||||||
workspace_active_editor(self.workspace.read(cx), cx)
|
.workspace
|
||||||
|
.upgrade()
|
||||||
|
.and_then(|workspace| workspace_active_editor(workspace.read(cx), cx))
|
||||||
{
|
{
|
||||||
if self.should_replace_active_item(active_item.as_ref()) {
|
if self.should_replace_active_item(active_item.as_ref()) {
|
||||||
self.replace_active_editor(active_item, active_editor, cx);
|
self.replace_active_editor(active_item, active_editor, cx);
|
||||||
@@ -3833,8 +3842,10 @@ impl Panel for OutlinePanel {
|
|||||||
let old_active = outline_panel.active;
|
let old_active = outline_panel.active;
|
||||||
outline_panel.active = active;
|
outline_panel.active = active;
|
||||||
if active && old_active != active {
|
if active && old_active != active {
|
||||||
if let Some((active_item, active_editor)) =
|
if let Some((active_item, active_editor)) = outline_panel
|
||||||
workspace_active_editor(outline_panel.workspace.read(cx), cx)
|
.workspace
|
||||||
|
.upgrade()
|
||||||
|
.and_then(|workspace| workspace_active_editor(workspace.read(cx), cx))
|
||||||
{
|
{
|
||||||
if outline_panel.should_replace_active_item(active_item.as_ref()) {
|
if outline_panel.should_replace_active_item(active_item.as_ref()) {
|
||||||
outline_panel.replace_active_editor(active_item, active_editor, cx);
|
outline_panel.replace_active_editor(active_item, active_editor, cx);
|
||||||
|
|||||||
@@ -254,7 +254,12 @@ impl LspStore {
|
|||||||
yarn,
|
yarn,
|
||||||
_maintain_workspace_config: Self::maintain_workspace_config(cx),
|
_maintain_workspace_config: Self::maintain_workspace_config(cx),
|
||||||
_maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
|
_maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
|
||||||
_subscription: cx.on_app_quit(Self::shutdown_language_servers),
|
_subscription: cx.on_release(|this, cx| {
|
||||||
|
println!("lsp store released");
|
||||||
|
cx.background_executor()
|
||||||
|
.spawn(this.shutdown_language_servers())
|
||||||
|
.detach();
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,10 +499,8 @@ impl LspStore {
|
|||||||
self.active_entry = active_entry;
|
self.active_entry = active_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown_language_servers(
|
fn shutdown_language_servers(&mut self) -> impl Future<Output = ()> {
|
||||||
&mut self,
|
println!("shutdown language servers");
|
||||||
_cx: &mut ModelContext<Self>,
|
|
||||||
) -> impl Future<Output = ()> {
|
|
||||||
let shutdown_futures = self
|
let shutdown_futures = self
|
||||||
.language_servers
|
.language_servers
|
||||||
.drain()
|
.drain()
|
||||||
@@ -511,7 +514,9 @@ impl LspStore {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
|
let count = shutdown_futures.len();
|
||||||
futures::future::join_all(shutdown_futures).await;
|
futures::future::join_all(shutdown_futures).await;
|
||||||
|
println!("done shutting down {} servers", count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -658,6 +658,11 @@ impl Project {
|
|||||||
});
|
});
|
||||||
cx.subscribe(&lsp_store, Self::on_lsp_store_event).detach();
|
cx.subscribe(&lsp_store, Self::on_lsp_store_event).detach();
|
||||||
|
|
||||||
|
cx.on_release(|_, _| {
|
||||||
|
println!("project. on release");
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
buffer_ordered_messages_tx: tx,
|
buffer_ordered_messages_tx: tx,
|
||||||
collaborators: Default::default(),
|
collaborators: Default::default(),
|
||||||
@@ -1717,6 +1722,7 @@ impl Project {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&mut self, cx: &mut ModelContext<Self>) {
|
pub fn close(&mut self, cx: &mut ModelContext<Self>) {
|
||||||
|
println!("Closing the project");
|
||||||
cx.emit(Event::Closed);
|
cx.emit(Event::Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,15 +68,15 @@ impl AppSession {
|
|||||||
let _subscriptions = vec![cx.on_app_quit(Self::app_will_quit)];
|
let _subscriptions = vec![cx.on_app_quit(Self::app_will_quit)];
|
||||||
|
|
||||||
let _serialization_task = Some(cx.spawn(|_, cx| async move {
|
let _serialization_task = Some(cx.spawn(|_, cx| async move {
|
||||||
loop {
|
// loop {
|
||||||
if let Some(windows) = cx.update(|cx| cx.window_stack()).ok().flatten() {
|
// if let Some(windows) = cx.update(|cx| cx.window_stack()).ok().flatten() {
|
||||||
store_window_stack(windows).await;
|
// store_window_stack(windows).await;
|
||||||
}
|
// }
|
||||||
|
|
||||||
cx.background_executor()
|
// cx.background_executor()
|
||||||
.timer(Duration::from_millis(100))
|
// .timer(Duration::from_millis(100))
|
||||||
.await;
|
// .await;
|
||||||
}
|
// }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ impl TerminalPanel {
|
|||||||
let pane = cx.new_view(|cx| {
|
let pane = cx.new_view(|cx| {
|
||||||
let mut pane = Pane::new(
|
let mut pane = Pane::new(
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
workspace.project().clone(),
|
workspace.project().downgrade(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
None,
|
None,
|
||||||
NewTerminal.boxed_clone(),
|
NewTerminal.boxed_clone(),
|
||||||
|
|||||||
@@ -368,9 +368,13 @@ impl Dock {
|
|||||||
cx.observe(&panel, |_, _, cx| cx.notify()),
|
cx.observe(&panel, |_, _, cx| cx.notify()),
|
||||||
cx.observe_global::<SettingsStore>({
|
cx.observe_global::<SettingsStore>({
|
||||||
let workspace = workspace.clone();
|
let workspace = workspace.clone();
|
||||||
let panel = panel.clone();
|
let panel = panel.downgrade();
|
||||||
|
|
||||||
move |this, cx| {
|
move |this, cx| {
|
||||||
|
let Some(panel) = panel.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let new_position = panel.read(cx).position(cx);
|
let new_position = panel.read(cx).position(cx);
|
||||||
if new_position == this.position {
|
if new_position == this.position {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ use gpui::{
|
|||||||
AppContext, AsyncWindowContext, ClickEvent, ClipboardItem, Div, DragMoveEvent, EntityId,
|
AppContext, AsyncWindowContext, ClickEvent, ClipboardItem, Div, DragMoveEvent, EntityId,
|
||||||
EventEmitter, ExternalPaths, FocusHandle, FocusOutEvent, FocusableView, KeyContext, Model,
|
EventEmitter, ExternalPaths, FocusHandle, FocusOutEvent, FocusableView, KeyContext, Model,
|
||||||
MouseButton, MouseDownEvent, NavigationDirection, Pixels, Point, PromptLevel, Render,
|
MouseButton, MouseDownEvent, NavigationDirection, Pixels, Point, PromptLevel, Render,
|
||||||
ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakFocusHandle, WeakView,
|
ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakFocusHandle, WeakModel,
|
||||||
WindowContext,
|
WeakView, WindowContext,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
@@ -255,7 +255,7 @@ pub struct Pane {
|
|||||||
nav_history: NavHistory,
|
nav_history: NavHistory,
|
||||||
toolbar: View<Toolbar>,
|
toolbar: View<Toolbar>,
|
||||||
pub(crate) workspace: WeakView<Workspace>,
|
pub(crate) workspace: WeakView<Workspace>,
|
||||||
project: Model<Project>,
|
project: WeakModel<Project>,
|
||||||
drag_split_direction: Option<SplitDirection>,
|
drag_split_direction: Option<SplitDirection>,
|
||||||
can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool>>,
|
can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool>>,
|
||||||
custom_drop_handle:
|
custom_drop_handle:
|
||||||
@@ -337,7 +337,7 @@ impl EventEmitter<Event> for Pane {}
|
|||||||
impl Pane {
|
impl Pane {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
workspace: WeakView<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
project: Model<Project>,
|
project: WeakModel<Project>,
|
||||||
next_timestamp: Arc<AtomicUsize>,
|
next_timestamp: Arc<AtomicUsize>,
|
||||||
can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool + 'static>>,
|
can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool + 'static>>,
|
||||||
double_click_dispatch_action: Box<dyn Action>,
|
double_click_dispatch_action: Box<dyn Action>,
|
||||||
@@ -802,14 +802,15 @@ impl Pane {
|
|||||||
) {
|
) {
|
||||||
if item.is_singleton(cx) {
|
if item.is_singleton(cx) {
|
||||||
if let Some(&entry_id) = item.project_entry_ids(cx).first() {
|
if let Some(&entry_id) = item.project_entry_ids(cx).first() {
|
||||||
let project = self.project.read(cx);
|
if let Some(project) = self.project.upgrade().map(|project| project.read(cx)) {
|
||||||
if let Some(project_path) = project.path_for_entry(entry_id, cx) {
|
if let Some(project_path) = project.path_for_entry(entry_id, cx) {
|
||||||
let abs_path = project.absolute_path(&project_path, cx);
|
let abs_path = project.absolute_path(&project_path, cx);
|
||||||
self.nav_history
|
self.nav_history
|
||||||
.0
|
.0
|
||||||
.lock()
|
.lock()
|
||||||
.paths_by_item
|
.paths_by_item
|
||||||
.insert(item.item_id(), (project_path, abs_path));
|
.insert(item.item_id(), (project_path, abs_path));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1811,7 +1812,7 @@ impl Pane {
|
|||||||
let icon_color = if ItemSettings::get_global(cx).git_status {
|
let icon_color = if ItemSettings::get_global(cx).git_status {
|
||||||
project_path
|
project_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|path| self.project.read(cx).entry_for_path(path, cx))
|
.and_then(|path| self.project.upgrade()?.read(cx).entry_for_path(path, cx))
|
||||||
.map(|entry| {
|
.map(|entry| {
|
||||||
Self::git_aware_icon_color(entry.git_status, entry.is_ignored, is_active)
|
Self::git_aware_icon_color(entry.git_status, entry.is_ignored, is_active)
|
||||||
})
|
})
|
||||||
@@ -2057,11 +2058,13 @@ impl Pane {
|
|||||||
entry_id: Some(entry_id),
|
entry_id: Some(entry_id),
|
||||||
})),
|
})),
|
||||||
cx.handler_for(&pane, move |pane, cx| {
|
cx.handler_for(&pane, move |pane, cx| {
|
||||||
pane.project.update(cx, |_, cx| {
|
pane.project
|
||||||
cx.emit(project::Event::RevealInProjectPanel(
|
.update(cx, |_, cx| {
|
||||||
ProjectEntryId::from_proto(entry_id),
|
cx.emit(project::Event::RevealInProjectPanel(
|
||||||
))
|
ProjectEntryId::from_proto(entry_id),
|
||||||
});
|
))
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.when_some(parent_abs_path, |menu, parent_abs_path| {
|
.when_some(parent_abs_path, |menu, parent_abs_path| {
|
||||||
@@ -2605,9 +2608,11 @@ impl Render for Pane {
|
|||||||
.map(ProjectEntryId::from_proto)
|
.map(ProjectEntryId::from_proto)
|
||||||
.or_else(|| pane.active_item()?.project_entry_ids(cx).first().copied());
|
.or_else(|| pane.active_item()?.project_entry_ids(cx).first().copied());
|
||||||
if let Some(entry_id) = entry_id {
|
if let Some(entry_id) = entry_id {
|
||||||
pane.project.update(cx, |_, cx| {
|
pane.project
|
||||||
cx.emit(project::Event::RevealInProjectPanel(entry_id))
|
.update(cx, |_, cx| {
|
||||||
});
|
cx.emit(project::Event::RevealInProjectPanel(entry_id))
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -2615,7 +2620,11 @@ impl Render for Pane {
|
|||||||
pane.child(self.render_tab_bar(cx))
|
pane.child(self.render_tab_bar(cx))
|
||||||
})
|
})
|
||||||
.child({
|
.child({
|
||||||
let has_worktrees = self.project.read(cx).worktrees(cx).next().is_some();
|
let has_worktrees = self
|
||||||
|
.project
|
||||||
|
.upgrade()
|
||||||
|
.and_then(|project| project.read(cx).worktrees(cx).next())
|
||||||
|
.is_some();
|
||||||
// main content
|
// main content
|
||||||
div()
|
div()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
|
|||||||
@@ -873,7 +873,7 @@ impl Workspace {
|
|||||||
let center_pane = cx.new_view(|cx| {
|
let center_pane = cx.new_view(|cx| {
|
||||||
Pane::new(
|
Pane::new(
|
||||||
weak_handle.clone(),
|
weak_handle.clone(),
|
||||||
project.clone(),
|
project.downgrade(),
|
||||||
pane_history_timestamp.clone(),
|
pane_history_timestamp.clone(),
|
||||||
None,
|
None,
|
||||||
NewFile.boxed_clone(),
|
NewFile.boxed_clone(),
|
||||||
@@ -1004,6 +1004,7 @@ impl Workspace {
|
|||||||
cx.on_release(|this, window, cx| {
|
cx.on_release(|this, window, cx| {
|
||||||
this.app_state.workspace_store.update(cx, |store, _| {
|
this.app_state.workspace_store.update(cx, |store, _| {
|
||||||
let window = window.downcast::<Self>().unwrap();
|
let window = window.downcast::<Self>().unwrap();
|
||||||
|
println!("workspace released!");
|
||||||
store.workspaces.remove(&window);
|
store.workspaces.remove(&window);
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
@@ -1634,17 +1635,39 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_window(&mut self, _: &CloseWindow, cx: &mut ViewContext<Self>) {
|
pub fn close_window(&mut self, _: &CloseWindow, cx: &mut ViewContext<Self>) {
|
||||||
|
let project = self.project.downgrade();
|
||||||
|
// let handle = cx.model();
|
||||||
|
// let weak = self.weak_handle();
|
||||||
|
|
||||||
let prepare = self.prepare_to_close(CloseIntent::CloseWindow, cx);
|
let prepare = self.prepare_to_close(CloseIntent::CloseWindow, cx);
|
||||||
let window = cx.window_handle();
|
let window = cx.window_handle();
|
||||||
cx.spawn(|_, mut cx| async move {
|
cx.spawn(|_, mut cx| async move {
|
||||||
if prepare.await? {
|
if prepare.await? {
|
||||||
window.update(&mut cx, |_, cx| {
|
window.update(&mut cx, |_, cx| {
|
||||||
|
println!("remove window");
|
||||||
cx.remove_window();
|
cx.remove_window();
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
cx.spawn(|cx| async move {
|
||||||
|
println!("going to sleep for 8 sec");
|
||||||
|
cx.background_executor().timer(Duration::from_secs(8)).await;
|
||||||
|
println!("slept for 8 sec");
|
||||||
|
println!("asserting the project weak handle is released");
|
||||||
|
project.assert_released();
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
// for _ in 0..10 {
|
||||||
|
// cx.background_executor().timer(Duration::from_secs(1)).await;
|
||||||
|
// dbg!("refreshing");
|
||||||
|
// AsyncAppContext::update(&mut cx, |cx| cx.new_model(|cx| ())).ok();
|
||||||
|
// }
|
||||||
|
|
||||||
|
println!("loop done");
|
||||||
}
|
}
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx)
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_to_close(
|
pub fn prepare_to_close(
|
||||||
@@ -2408,7 +2431,7 @@ impl Workspace {
|
|||||||
let pane = cx.new_view(|cx| {
|
let pane = cx.new_view(|cx| {
|
||||||
Pane::new(
|
Pane::new(
|
||||||
self.weak_handle(),
|
self.weak_handle(),
|
||||||
self.project.clone(),
|
self.project.downgrade(),
|
||||||
self.pane_history_timestamp.clone(),
|
self.pane_history_timestamp.clone(),
|
||||||
None,
|
None,
|
||||||
NewFile.boxed_clone(),
|
NewFile.boxed_clone(),
|
||||||
@@ -4020,6 +4043,7 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_workspace_internal(&self, cx: &mut WindowContext) -> Task<()> {
|
fn serialize_workspace_internal(&self, cx: &mut WindowContext) -> Task<()> {
|
||||||
|
println!("--- serialize workspace internal start ---");
|
||||||
let Some(database_id) = self.database_id() else {
|
let Some(database_id) = self.database_id() else {
|
||||||
return Task::ready(());
|
return Task::ready(());
|
||||||
};
|
};
|
||||||
@@ -4161,7 +4185,10 @@ impl Workspace {
|
|||||||
session_id: self.session_id.clone(),
|
session_id: self.session_id.clone(),
|
||||||
window_id: Some(cx.window_handle().window_id().as_u64()),
|
window_id: Some(cx.window_handle().window_id().as_u64()),
|
||||||
};
|
};
|
||||||
return cx.spawn(|_| persistence::DB.save_workspace(serialized_workspace));
|
return cx.spawn(|_| async move {
|
||||||
|
persistence::DB.save_workspace(serialized_workspace).await;
|
||||||
|
println!("--- serialize workspace internal END ---")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Task::ready(())
|
Task::ready(())
|
||||||
}
|
}
|
||||||
@@ -4177,6 +4204,7 @@ impl Workspace {
|
|||||||
let mut serializable_items = items_rx.ready_chunks(CHUNK_SIZE);
|
let mut serializable_items = items_rx.ready_chunks(CHUNK_SIZE);
|
||||||
|
|
||||||
while let Some(items_received) = serializable_items.next().await {
|
while let Some(items_received) = serializable_items.next().await {
|
||||||
|
println!("serializing item!");
|
||||||
let unique_items =
|
let unique_items =
|
||||||
items_received
|
items_received
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -4199,6 +4227,7 @@ impl Workspace {
|
|||||||
|
|
||||||
cx.background_executor().timer(THROTTLE_TIME).await;
|
cx.background_executor().timer(THROTTLE_TIME).await;
|
||||||
}
|
}
|
||||||
|
println!("done serializing items");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,47 +251,47 @@ pub fn initialize_workspace(
|
|||||||
|
|
||||||
let prompt_builder = prompt_builder.clone();
|
let prompt_builder = prompt_builder.clone();
|
||||||
cx.spawn(|workspace_handle, mut cx| async move {
|
cx.spawn(|workspace_handle, mut cx| async move {
|
||||||
let assistant_panel =
|
// // let assistant_panel =
|
||||||
assistant::AssistantPanel::load(workspace_handle.clone(), prompt_builder, cx.clone());
|
// // assistant::AssistantPanel::load(workspace_handle.clone(), prompt_builder, cx.clone());
|
||||||
|
|
||||||
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
|
// // let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
|
||||||
let outline_panel = OutlinePanel::load(workspace_handle.clone(), cx.clone());
|
let outline_panel = OutlinePanel::load(workspace_handle.clone(), cx.clone());
|
||||||
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
|
// let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
|
||||||
let channels_panel =
|
// // let channels_panel =
|
||||||
collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
|
// // collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
|
||||||
let chat_panel =
|
// // let chat_panel =
|
||||||
collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
|
// // collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
|
||||||
let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
|
// let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
|
||||||
workspace_handle.clone(),
|
// workspace_handle.clone(),
|
||||||
cx.clone(),
|
// cx.clone(),
|
||||||
);
|
// );
|
||||||
|
|
||||||
let (
|
let (
|
||||||
project_panel,
|
// project_panel,
|
||||||
outline_panel,
|
outline_panel,
|
||||||
terminal_panel,
|
// terminal_panel,
|
||||||
assistant_panel,
|
// assistant_panel,
|
||||||
channels_panel,
|
// channels_panel,
|
||||||
chat_panel,
|
// chat_panel,
|
||||||
notification_panel,
|
// notification_panel,
|
||||||
) = futures::try_join!(
|
) = futures::try_join!(
|
||||||
project_panel,
|
// project_panel,
|
||||||
outline_panel,
|
outline_panel,
|
||||||
terminal_panel,
|
// terminal_panel,
|
||||||
assistant_panel,
|
// assistant_panel,
|
||||||
channels_panel,
|
// channels_panel,
|
||||||
chat_panel,
|
// chat_panel,
|
||||||
notification_panel,
|
// notification_panel,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
workspace_handle.update(&mut cx, |workspace, cx| {
|
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||||
workspace.add_panel(assistant_panel, cx);
|
// workspace.add_panel(assistant_panel, cx);
|
||||||
workspace.add_panel(project_panel, cx);
|
// workspace.add_panel(project_panel, cx);
|
||||||
workspace.add_panel(outline_panel, cx);
|
workspace.add_panel(outline_panel, cx);
|
||||||
workspace.add_panel(terminal_panel, cx);
|
// workspace.add_panel(terminal_panel, cx);
|
||||||
workspace.add_panel(channels_panel, cx);
|
// workspace.add_panel(channels_panel, cx);
|
||||||
workspace.add_panel(chat_panel, cx);
|
// workspace.add_panel(chat_panel, cx);
|
||||||
workspace.add_panel(notification_panel, cx);
|
// workspace.add_panel(notification_panel, cx);
|
||||||
cx.focus_self();
|
cx.focus_self();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user