Make workspace items expose their underlying models, remove file-related methods
This commit is contained in:
parent
292708573f
commit
8651320c9f
11 changed files with 198 additions and 196 deletions
|
@ -32,7 +32,9 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
use unindent::Unindent as _;
|
||||
use workspace::{item::Item, shared_screen::SharedScreen, SplitDirection, ToggleFollow, Workspace};
|
||||
use workspace::{
|
||||
item::ItemHandle as _, shared_screen::SharedScreen, SplitDirection, ToggleFollow, Workspace,
|
||||
};
|
||||
|
||||
#[ctor::ctor]
|
||||
fn init_logger() {
|
||||
|
@ -5602,7 +5604,7 @@ async fn test_following(
|
|||
});
|
||||
assert!(cx_b.read(|cx| editor_b2.is_focused(cx)));
|
||||
assert_eq!(
|
||||
editor_b2.read_with(cx_b, |editor, cx| editor.project_path(cx)),
|
||||
cx_b.read(|cx| editor_b2.project_path(cx)),
|
||||
Some((worktree_id, "2.txt").into())
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
|
@ -21,7 +21,6 @@ use language::{
|
|||
use project::{DiagnosticSummary, Project, ProjectPath};
|
||||
use serde_json::json;
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
cmp::Ordering,
|
||||
|
@ -521,12 +520,8 @@ impl Item for ProjectDiagnosticsEditor {
|
|||
)
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &AppContext) -> Option<project::ProjectPath> {
|
||||
None
|
||||
}
|
||||
|
||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[project::ProjectEntryId; 3]> {
|
||||
self.editor.project_entry_ids(cx)
|
||||
fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
|
||||
self.editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &AppContext) -> bool {
|
||||
|
|
|
@ -14,11 +14,10 @@ use gpui::{
|
|||
RenderContext, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use language::proto::serialize_anchor as serialize_text_anchor;
|
||||
use language::{Bias, Buffer, File as _, OffsetRangeExt, Point, SelectionGoal};
|
||||
use project::{File, FormatTrigger, Project, ProjectEntryId, ProjectPath};
|
||||
use language::{Bias, Buffer, OffsetRangeExt, Point, SelectionGoal};
|
||||
use project::{FormatTrigger, Item as _, Project, ProjectPath};
|
||||
use rpc::proto::{self, update_view};
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::{self, Ordering},
|
||||
|
@ -555,24 +554,10 @@ impl Item for Editor {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
||||
let buffer = self.buffer.read(cx).as_singleton()?;
|
||||
let file = buffer.read(cx).file();
|
||||
File::from_dyn(file).map(|file| ProjectPath {
|
||||
worktree_id: file.worktree_id(cx),
|
||||
path: file.path().clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]> {
|
||||
let mut result = SmallVec::new();
|
||||
self.buffer.read(cx).for_each_buffer(|buffer| {
|
||||
let buffer = buffer.read(cx);
|
||||
if let Some(file) = File::from_dyn(buffer.file()) {
|
||||
result.extend(file.project_entry_id(cx));
|
||||
}
|
||||
});
|
||||
result
|
||||
fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
|
||||
self.buffer
|
||||
.read(cx)
|
||||
.for_each_buffer(|buffer| f(buffer.id(), buffer.read(cx)));
|
||||
}
|
||||
|
||||
fn is_singleton(&self, cx: &AppContext) -> bool {
|
||||
|
@ -609,7 +594,12 @@ impl Item for Editor {
|
|||
}
|
||||
|
||||
fn can_save(&self, cx: &AppContext) -> bool {
|
||||
!self.buffer().read(cx).is_singleton() || self.project_path(cx).is_some()
|
||||
let buffer = &self.buffer().read(cx);
|
||||
if let Some(buffer) = buffer.as_singleton() {
|
||||
buffer.read(cx).project_path(cx).is_some()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn save(
|
||||
|
|
|
@ -67,8 +67,9 @@ use util::{debug_panic, defer, post_inc, ResultExt, TryFutureExt as _};
|
|||
pub use fs::*;
|
||||
pub use worktree::*;
|
||||
|
||||
pub trait Item: Entity {
|
||||
pub trait Item {
|
||||
fn entry_id(&self, cx: &AppContext) -> Option<ProjectEntryId>;
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
||||
}
|
||||
|
||||
// Language server state is stored across 3 collections:
|
||||
|
@ -6401,4 +6402,11 @@ impl Item for Buffer {
|
|||
fn entry_id(&self, cx: &AppContext) -> Option<ProjectEntryId> {
|
||||
File::from_dyn(self.file()).and_then(|file| file.project_entry_id(cx))
|
||||
}
|
||||
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
||||
File::from_dyn(self.file()).map(|file| ProjectPath {
|
||||
worktree_id: file.worktree_id(cx),
|
||||
path: file.path().clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ use gpui::{
|
|||
use menu::Confirm;
|
||||
use project::{search::SearchQuery, Project};
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
ops::Range,
|
||||
|
@ -264,12 +263,8 @@ impl Item for ProjectSearchView {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &gpui::AppContext) -> Option<project::ProjectPath> {
|
||||
None
|
||||
}
|
||||
|
||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[project::ProjectEntryId; 3]> {
|
||||
self.results_editor.project_entry_ids(cx)
|
||||
fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
|
||||
self.results_editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &AppContext) -> bool {
|
||||
|
|
|
@ -18,10 +18,9 @@ use gpui::{
|
|||
AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext, Task,
|
||||
View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use project::{LocalWorktree, Project, ProjectPath};
|
||||
use project::{LocalWorktree, Project};
|
||||
use serde::Deserialize;
|
||||
use settings::{Settings, TerminalBlink, WorkingDirectory};
|
||||
use smallvec::SmallVec;
|
||||
use smol::Timer;
|
||||
use terminal::{
|
||||
alacritty_terminal::{
|
||||
|
@ -616,13 +615,7 @@ impl Item for TerminalView {
|
|||
None
|
||||
}
|
||||
|
||||
fn project_path(&self, _cx: &gpui::AppContext) -> Option<ProjectPath> {
|
||||
None
|
||||
}
|
||||
|
||||
fn project_entry_ids(&self, _cx: &gpui::AppContext) -> SmallVec<[project::ProjectEntryId; 3]> {
|
||||
SmallVec::new()
|
||||
}
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
|
||||
|
||||
fn is_singleton(&self, _cx: &gpui::AppContext) -> bool {
|
||||
false
|
||||
|
|
|
@ -6,12 +6,11 @@ use gpui::{
|
|||
Padding, ParentElement,
|
||||
},
|
||||
fonts::TextStyle,
|
||||
Border, Element, Entity, ModelHandle, MutableAppContext, Quad, RenderContext, Task, View,
|
||||
ViewContext, ViewHandle, WeakViewHandle,
|
||||
AppContext, Border, Element, Entity, ModelHandle, MutableAppContext, Quad, RenderContext, Task,
|
||||
View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use project::{Project, ProjectEntryId, ProjectPath};
|
||||
use project::Project;
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use theme::{ColorScheme, Layer, Style, StyleSet};
|
||||
use workspace::{
|
||||
item::{Item, ItemEvent},
|
||||
|
@ -306,7 +305,7 @@ impl Item for ThemeTestbench {
|
|||
&self,
|
||||
_: Option<usize>,
|
||||
style: &theme::Tab,
|
||||
_: &gpui::AppContext,
|
||||
_: &AppContext,
|
||||
) -> gpui::ElementBox {
|
||||
Label::new("Theme Testbench".into(), style.label.clone())
|
||||
.aligned()
|
||||
|
@ -314,21 +313,15 @@ impl Item for ThemeTestbench {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &gpui::AppContext) -> Option<ProjectPath> {
|
||||
None
|
||||
}
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
|
||||
|
||||
fn project_entry_ids(&self, _: &gpui::AppContext) -> SmallVec<[ProjectEntryId; 3]> {
|
||||
SmallVec::new()
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &gpui::AppContext) -> bool {
|
||||
fn is_singleton(&self, _: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_nav_history(&mut self, _: workspace::ItemNavHistory, _: &mut ViewContext<Self>) {}
|
||||
|
||||
fn can_save(&self, _: &gpui::AppContext) -> bool {
|
||||
fn can_save(&self, _: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,7 @@ pub trait Item: View {
|
|||
}
|
||||
fn tab_content(&self, detail: Option<usize>, style: &theme::Tab, cx: &AppContext)
|
||||
-> ElementBox;
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]>;
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item));
|
||||
fn is_singleton(&self, cx: &AppContext) -> bool;
|
||||
fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext<Self>);
|
||||
fn clone_on_split(&self, _workspace_id: WorkspaceId, _: &mut ViewContext<Self>) -> Option<Self>
|
||||
|
@ -147,6 +146,8 @@ pub trait ItemHandle: 'static + fmt::Debug {
|
|||
-> ElementBox;
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]>;
|
||||
fn project_item_model_ids(&self, cx: &AppContext) -> SmallVec<[usize; 3]>;
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item));
|
||||
fn is_singleton(&self, cx: &AppContext) -> bool;
|
||||
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
||||
fn clone_on_split(
|
||||
|
@ -240,11 +241,36 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
|||
}
|
||||
|
||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
||||
self.read(cx).project_path(cx)
|
||||
let this = self.read(cx);
|
||||
let mut result = None;
|
||||
if this.is_singleton(cx) {
|
||||
this.for_each_project_item(cx, &mut |_, item| {
|
||||
result = item.project_path(cx);
|
||||
});
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]> {
|
||||
self.read(cx).project_entry_ids(cx)
|
||||
let mut result = SmallVec::new();
|
||||
self.read(cx).for_each_project_item(cx, &mut |_, item| {
|
||||
if let Some(id) = item.entry_id(cx) {
|
||||
result.push(id);
|
||||
}
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
fn project_item_model_ids(&self, cx: &AppContext) -> SmallVec<[usize; 3]> {
|
||||
let mut result = SmallVec::new();
|
||||
self.read(cx).for_each_project_item(cx, &mut |id, _| {
|
||||
result.push(id);
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
|
||||
self.read(cx).for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, cx: &AppContext) -> bool {
|
||||
|
@ -582,7 +608,7 @@ impl<T: Item> WeakItemHandle for WeakViewHandle<T> {
|
|||
}
|
||||
|
||||
pub trait ProjectItem: Item {
|
||||
type Item: project::Item;
|
||||
type Item: project::Item + gpui::Entity;
|
||||
|
||||
fn for_project_item(
|
||||
project: ModelHandle<Project>,
|
||||
|
@ -690,18 +716,18 @@ impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
|
|||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test {
|
||||
use std::{any::Any, borrow::Cow, cell::Cell};
|
||||
|
||||
use super::{Item, ItemEvent};
|
||||
use crate::{sidebar::SidebarItem, ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId};
|
||||
use gpui::{
|
||||
elements::Empty, AppContext, Element, ElementBox, Entity, ModelHandle, RenderContext, Task,
|
||||
View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
elements::Empty, AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext,
|
||||
RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use project::{Project, ProjectEntryId, ProjectPath};
|
||||
use smallvec::SmallVec;
|
||||
use std::{any::Any, borrow::Cow, cell::Cell};
|
||||
|
||||
use crate::{sidebar::SidebarItem, ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId};
|
||||
|
||||
use super::{Item, ItemEvent};
|
||||
pub struct TestProjectItem {
|
||||
pub entry_id: Option<ProjectEntryId>,
|
||||
}
|
||||
|
||||
pub struct TestItem {
|
||||
pub workspace_id: WorkspaceId,
|
||||
|
@ -713,13 +739,27 @@ pub(crate) mod test {
|
|||
pub is_dirty: bool,
|
||||
pub is_singleton: bool,
|
||||
pub has_conflict: bool,
|
||||
pub project_entry_ids: Vec<ProjectEntryId>,
|
||||
pub project_items: Vec<ModelHandle<TestProjectItem>>,
|
||||
pub project_path: Option<ProjectPath>,
|
||||
pub nav_history: Option<ItemNavHistory>,
|
||||
pub tab_descriptions: Option<Vec<&'static str>>,
|
||||
pub tab_detail: Cell<Option<usize>>,
|
||||
}
|
||||
|
||||
impl Entity for TestProjectItem {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl project::Item for TestProjectItem {
|
||||
fn entry_id(&self, _: &AppContext) -> Option<ProjectEntryId> {
|
||||
self.entry_id
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &AppContext) -> Option<ProjectPath> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TestItemEvent {
|
||||
Edit,
|
||||
}
|
||||
|
@ -735,7 +775,7 @@ pub(crate) mod test {
|
|||
is_dirty: self.is_dirty,
|
||||
is_singleton: self.is_singleton,
|
||||
has_conflict: self.has_conflict,
|
||||
project_entry_ids: self.project_entry_ids.clone(),
|
||||
project_items: self.project_items.clone(),
|
||||
project_path: self.project_path.clone(),
|
||||
nav_history: None,
|
||||
tab_descriptions: None,
|
||||
|
@ -755,7 +795,7 @@ pub(crate) mod test {
|
|||
reload_count: 0,
|
||||
is_dirty: false,
|
||||
has_conflict: false,
|
||||
project_entry_ids: Vec::new(),
|
||||
project_items: Vec::new(),
|
||||
project_path: None,
|
||||
is_singleton: true,
|
||||
nav_history: None,
|
||||
|
@ -781,13 +821,26 @@ pub(crate) mod test {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_project_entry_ids(mut self, project_entry_ids: &[u64]) -> Self {
|
||||
self.project_entry_ids.extend(
|
||||
project_entry_ids
|
||||
.iter()
|
||||
.copied()
|
||||
.map(ProjectEntryId::from_proto),
|
||||
);
|
||||
pub fn with_dirty(mut self, dirty: bool) -> Self {
|
||||
self.is_dirty = dirty;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_conflict(mut self, has_conflict: bool) -> Self {
|
||||
self.has_conflict = has_conflict;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_project_entry_ids(
|
||||
mut self,
|
||||
project_entry_ids: &[u64],
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Self {
|
||||
self.project_items
|
||||
.extend(project_entry_ids.iter().copied().map(|id| {
|
||||
let id = ProjectEntryId::from_proto(id);
|
||||
cx.add_model(|_| TestProjectItem { entry_id: Some(id) })
|
||||
}));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -830,12 +883,14 @@ pub(crate) mod test {
|
|||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &AppContext) -> Option<ProjectPath> {
|
||||
self.project_path.clone()
|
||||
}
|
||||
|
||||
fn project_entry_ids(&self, _: &AppContext) -> SmallVec<[ProjectEntryId; 3]> {
|
||||
self.project_entry_ids.iter().copied().collect()
|
||||
fn for_each_project_item(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
f: &mut dyn FnMut(usize, &dyn project::Item),
|
||||
) {
|
||||
self.project_items
|
||||
.iter()
|
||||
.for_each(|item| f(item.id(), item.read(cx)))
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &AppContext) -> bool {
|
||||
|
@ -880,7 +935,7 @@ pub(crate) mod test {
|
|||
}
|
||||
|
||||
fn can_save(&self, _: &AppContext) -> bool {
|
||||
!self.project_entry_ids.is_empty()
|
||||
!self.project_items.is_empty()
|
||||
}
|
||||
|
||||
fn save(
|
||||
|
|
|
@ -809,8 +809,8 @@ impl Pane {
|
|||
// Find the item's current index and its set of project entries. Avoid
|
||||
// storing these in advance, in case they have changed since this task
|
||||
// was started.
|
||||
let (item_ix, mut project_entry_ids) = pane.read_with(&cx, |pane, cx| {
|
||||
(pane.index_for_item(&*item), item.project_entry_ids(cx))
|
||||
let (item_ix, mut project_item_ids) = pane.read_with(&cx, |pane, cx| {
|
||||
(pane.index_for_item(&*item), item.project_item_model_ids(cx))
|
||||
});
|
||||
let item_ix = if let Some(ix) = item_ix {
|
||||
ix
|
||||
|
@ -823,25 +823,20 @@ impl Pane {
|
|||
// any project entries that are not open anywhere else in the workspace,
|
||||
// AND that the user has not already been prompted to save. If there are
|
||||
// any such project entries, prompt the user to save this item.
|
||||
let should_save = if project_entry_ids.is_empty() {
|
||||
true
|
||||
} else {
|
||||
workspace.read_with(&cx, |workspace, cx| {
|
||||
for item in workspace.items(cx) {
|
||||
if !items_to_close
|
||||
.iter()
|
||||
.any(|item_to_close| item_to_close.id() == item.id())
|
||||
{
|
||||
let other_project_entry_ids = item.project_entry_ids(cx);
|
||||
project_entry_ids
|
||||
.retain(|id| !other_project_entry_ids.contains(id));
|
||||
}
|
||||
workspace.read_with(&cx, |workspace, cx| {
|
||||
for item in workspace.items(cx) {
|
||||
if !items_to_close
|
||||
.iter()
|
||||
.any(|item_to_close| item_to_close.id() == item.id())
|
||||
{
|
||||
let other_project_item_ids = item.project_item_model_ids(cx);
|
||||
project_item_ids.retain(|id| !other_project_item_ids.contains(id));
|
||||
}
|
||||
});
|
||||
project_entry_ids
|
||||
.iter()
|
||||
.any(|id| saved_project_entry_ids.insert(*id))
|
||||
};
|
||||
}
|
||||
});
|
||||
let should_save = project_item_ids
|
||||
.iter()
|
||||
.any(|id| saved_project_entry_ids.insert(*id));
|
||||
|
||||
if should_save
|
||||
&& !Self::save_item(project.clone(), &pane, item_ix, &*item, true, &mut cx)
|
||||
|
@ -1866,7 +1861,7 @@ mod tests {
|
|||
let item = TestItem::new()
|
||||
.with_singleton(true)
|
||||
.with_label("buffer 1")
|
||||
.with_project_entry_ids(&[1]);
|
||||
.with_project_entry_ids(&[1], cx);
|
||||
|
||||
Pane::add_item(
|
||||
workspace,
|
||||
|
@ -1885,7 +1880,7 @@ mod tests {
|
|||
let item = TestItem::new()
|
||||
.with_singleton(true)
|
||||
.with_label("buffer 1")
|
||||
.with_project_entry_ids(&[1]);
|
||||
.with_project_entry_ids(&[1], cx);
|
||||
|
||||
Pane::add_item(
|
||||
workspace,
|
||||
|
@ -1904,7 +1899,7 @@ mod tests {
|
|||
let item = TestItem::new()
|
||||
.with_singleton(true)
|
||||
.with_label("buffer 2")
|
||||
.with_project_entry_ids(&[2]);
|
||||
.with_project_entry_ids(&[2], cx);
|
||||
|
||||
Pane::add_item(
|
||||
workspace,
|
||||
|
@ -1923,7 +1918,7 @@ mod tests {
|
|||
let item = TestItem::new()
|
||||
.with_singleton(false)
|
||||
.with_label("multibuffer 1")
|
||||
.with_project_entry_ids(&[1]);
|
||||
.with_project_entry_ids(&[1], cx);
|
||||
|
||||
Pane::add_item(
|
||||
workspace,
|
||||
|
@ -1942,7 +1937,7 @@ mod tests {
|
|||
let item = TestItem::new()
|
||||
.with_singleton(false)
|
||||
.with_label("multibuffer 1b")
|
||||
.with_project_entry_ids(&[1]);
|
||||
.with_project_entry_ids(&[1], cx);
|
||||
|
||||
Pane::add_item(
|
||||
workspace,
|
||||
|
|
|
@ -8,12 +8,11 @@ use futures::StreamExt;
|
|||
use gpui::{
|
||||
elements::*,
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
Entity, ModelHandle, MouseButton, RenderContext, Task, View, ViewContext, ViewHandle,
|
||||
WeakViewHandle,
|
||||
AppContext, Entity, ModelHandle, MouseButton, RenderContext, Task, View, ViewContext,
|
||||
ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use project::Project;
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
sync::{Arc, Weak},
|
||||
|
@ -106,7 +105,7 @@ impl Item for SharedScreen {
|
|||
&self,
|
||||
_: Option<usize>,
|
||||
style: &theme::Tab,
|
||||
_: &gpui::AppContext,
|
||||
_: &AppContext,
|
||||
) -> gpui::ElementBox {
|
||||
Flex::row()
|
||||
.with_child(
|
||||
|
@ -130,15 +129,9 @@ impl Item for SharedScreen {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
fn project_path(&self, _: &gpui::AppContext) -> Option<project::ProjectPath> {
|
||||
Default::default()
|
||||
}
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
|
||||
|
||||
fn project_entry_ids(&self, _: &gpui::AppContext) -> SmallVec<[project::ProjectEntryId; 3]> {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &gpui::AppContext) -> bool {
|
||||
fn is_singleton(&self, _: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
|
@ -155,7 +148,7 @@ impl Item for SharedScreen {
|
|||
Some(Self::new(&track, self.peer_id, self.user.clone(), cx))
|
||||
}
|
||||
|
||||
fn can_save(&self, _: &gpui::AppContext) -> bool {
|
||||
fn can_save(&self, _: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -2943,16 +2943,11 @@ mod tests {
|
|||
|
||||
// When there are dirty untitled items, prompt to save each one. If the user
|
||||
// cancels any prompt, then abort.
|
||||
let item2 = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item
|
||||
});
|
||||
let item3 = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(1)];
|
||||
item
|
||||
let item2 = cx.add_view(&workspace, |_| TestItem::new().with_dirty(true));
|
||||
let item3 = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_project_entry_ids(&[1], cx)
|
||||
});
|
||||
workspace.update(cx, |w, cx| {
|
||||
w.add_item(Box::new(item2.clone()), cx);
|
||||
|
@ -2977,31 +2972,24 @@ mod tests {
|
|||
Workspace::new(Default::default(), 0, project, default_item_factory, cx)
|
||||
});
|
||||
|
||||
let item1 = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(1)];
|
||||
item
|
||||
let item1 = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_project_entry_ids(&[1], cx)
|
||||
});
|
||||
let item2 = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.has_conflict = true;
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(2)];
|
||||
item
|
||||
let item2 = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_conflict(true)
|
||||
.with_project_entry_ids(&[2], cx)
|
||||
});
|
||||
let item3 = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.has_conflict = true;
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(3)];
|
||||
item
|
||||
});
|
||||
let item4 = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item
|
||||
let item3 = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_conflict(true)
|
||||
.with_project_entry_ids(&[3], cx)
|
||||
});
|
||||
let item4 = cx.add_view(&workspace, |_| TestItem::new().with_dirty(true));
|
||||
let pane = workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item1.clone()), cx);
|
||||
workspace.add_item(Box::new(item2.clone()), cx);
|
||||
|
@ -3078,29 +3066,26 @@ mod tests {
|
|||
// workspace items with multiple project entries.
|
||||
let single_entry_items = (0..=4)
|
||||
.map(|project_entry_id| {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(project_entry_id)];
|
||||
item.is_singleton = true;
|
||||
item
|
||||
cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_singleton(true)
|
||||
.with_project_entry_ids(&[project_entry_id], cx)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let item_2_3 = {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.is_singleton = false;
|
||||
item.project_entry_ids =
|
||||
vec![ProjectEntryId::from_proto(2), ProjectEntryId::from_proto(3)];
|
||||
item
|
||||
};
|
||||
let item_3_4 = {
|
||||
let mut item = TestItem::new();
|
||||
item.is_dirty = true;
|
||||
item.is_singleton = false;
|
||||
item.project_entry_ids =
|
||||
vec![ProjectEntryId::from_proto(3), ProjectEntryId::from_proto(4)];
|
||||
item
|
||||
};
|
||||
let item_2_3 = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_project_entry_ids(&[2, 3], cx)
|
||||
});
|
||||
let item_3_4 = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new()
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_project_entry_ids(&[3, 4], cx)
|
||||
});
|
||||
|
||||
// Create two panes that contain the following project entries:
|
||||
// left pane:
|
||||
|
@ -3111,9 +3096,9 @@ mod tests {
|
|||
// multi-entry items: (3, 4)
|
||||
let left_pane = workspace.update(cx, |workspace, cx| {
|
||||
let left_pane = workspace.active_pane().clone();
|
||||
workspace.add_item(Box::new(cx.add_view(|_| item_2_3.clone())), cx);
|
||||
for item in &single_entry_items {
|
||||
workspace.add_item(Box::new(cx.add_view(|_| item.clone())), cx);
|
||||
workspace.add_item(Box::new(item_2_3.clone()), cx);
|
||||
for item in single_entry_items {
|
||||
workspace.add_item(Box::new(item), cx);
|
||||
}
|
||||
left_pane.update(cx, |pane, cx| {
|
||||
pane.activate_item(2, true, true, cx);
|
||||
|
@ -3128,7 +3113,7 @@ mod tests {
|
|||
|
||||
//Need to cause an effect flush in order to respect new focus
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(cx.add_view(|_| item_3_4.clone())), cx);
|
||||
workspace.add_item(Box::new(item_3_4.clone()), cx);
|
||||
cx.focus(left_pane.clone());
|
||||
});
|
||||
|
||||
|
@ -3177,10 +3162,8 @@ mod tests {
|
|||
Workspace::new(Default::default(), 0, project, default_item_factory, cx)
|
||||
});
|
||||
|
||||
let item = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(1)];
|
||||
item
|
||||
let item = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new().with_project_entry_ids(&[1], cx)
|
||||
});
|
||||
let item_id = item.id();
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
@ -3265,7 +3248,9 @@ mod tests {
|
|||
workspace.add_item(Box::new(item.clone()), cx);
|
||||
});
|
||||
item.update(cx, |item, cx| {
|
||||
item.project_entry_ids = Default::default();
|
||||
item.project_items[0].update(cx, |item, _| {
|
||||
item.entry_id = None;
|
||||
});
|
||||
item.is_dirty = true;
|
||||
cx.blur();
|
||||
});
|
||||
|
@ -3296,10 +3281,8 @@ mod tests {
|
|||
Workspace::new(Default::default(), 0, project, default_item_factory, cx)
|
||||
});
|
||||
|
||||
let item = cx.add_view(&workspace, |_| {
|
||||
let mut item = TestItem::new();
|
||||
item.project_entry_ids = vec![ProjectEntryId::from_proto(1)];
|
||||
item
|
||||
let item = cx.add_view(&workspace, |cx| {
|
||||
TestItem::new().with_project_entry_ids(&[1], cx)
|
||||
});
|
||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||
let toolbar = pane.read_with(cx, |pane, _| pane.toolbar().clone());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue