Introduce ProjectPath and ProjectEntry structs

These replace tuples of (usize, Arc<Path>) and (usize, usize) respectively.
This commit is contained in:
Nathan Sobo
2021-10-02 19:39:04 -06:00
parent f00045544f
commit 6239b5ec60
9 changed files with 163 additions and 121 deletions
+3 -3
View File
@@ -47,7 +47,7 @@ pub struct PathMatchCandidate<'a> {
pub struct PathMatch {
pub score: f64,
pub positions: Vec<usize>,
pub tree_id: usize,
pub worktree_id: usize,
pub path: Arc<Path>,
pub path_prefix: Arc<str>,
}
@@ -147,7 +147,7 @@ impl Ord for PathMatch {
self.score
.partial_cmp(&other.score)
.unwrap_or(Ordering::Equal)
.then_with(|| self.tree_id.cmp(&other.tree_id))
.then_with(|| self.worktree_id.cmp(&other.worktree_id))
.then_with(|| Arc::as_ptr(&self.path).cmp(&Arc::as_ptr(&other.path)))
}
}
@@ -215,7 +215,7 @@ impl<'a> Matcher<'a> {
cancel_flag,
|candidate, score| PathMatch {
score,
tree_id,
worktree_id: tree_id,
positions: Vec::new(),
path: candidate.path.clone(),
path_prefix: path_prefix.clone(),
+9 -2
View File
@@ -980,6 +980,7 @@ mod tests {
fs::{FakeFs, Fs as _},
language::LanguageRegistry,
people_panel::JoinWorktree,
project::ProjectPath,
rpc::{self, Client, Credentials, EstablishConnectionError},
settings,
test::FakeHttpClient,
@@ -1166,8 +1167,14 @@ mod tests {
workspace.worktrees(cx).first().unwrap().id()
});
workspace_b
.update(&mut cx_b, |worktree, cx| {
worktree.open_entry((local_worktree_id_b, Path::new("a.txt").into()), cx)
.update(&mut cx_b, |workspace, cx| {
workspace.open_entry(
ProjectPath {
worktree_id: local_worktree_id_b,
path: Path::new("a.txt").into(),
},
cx,
)
})
.unwrap()
.await;
+11 -7
View File
@@ -5,6 +5,7 @@ pub mod movement;
use crate::{
language::Language,
project::ProjectPath,
settings::Settings,
theme::Theme,
time::ReplicaId,
@@ -2589,8 +2590,11 @@ impl workspace::Item for Buffer {
)
}
fn worktree_id_and_path(&self) -> Option<(usize, Arc<Path>)> {
self.file().map(|f| (f.worktree_id(), f.path().clone()))
fn project_path(&self) -> Option<ProjectPath> {
self.file().map(|f| ProjectPath {
worktree_id: f.worktree_id(),
path: f.path().clone(),
})
}
}
@@ -2623,11 +2627,11 @@ impl workspace::ItemView for Editor {
}
}
fn worktree_id_and_path(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)> {
self.buffer
.read(cx)
.file()
.map(|file| (file.worktree_id(), file.path().clone()))
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
self.buffer.read(cx).file().map(|file| ProjectPath {
worktree_id: file.worktree_id(),
path: file.path().clone(),
})
}
fn clone_on_split(&self, cx: &mut ViewContext<Self>) -> Option<Self>
+16 -19
View File
@@ -1,7 +1,7 @@
use crate::{
editor::{self, Editor},
fuzzy::PathMatch,
project::Project,
project::{Project, ProjectPath},
settings::Settings,
util,
workspace::Workspace,
@@ -44,13 +44,7 @@ pub struct FileFinder {
action!(Toggle);
action!(Confirm);
action!(Select, Entry);
#[derive(Clone)]
pub struct Entry {
worktree_id: usize,
path: Arc<Path>,
}
action!(Select, ProjectPath);
pub fn init(cx: &mut MutableAppContext) {
cx.add_action(FileFinder::toggle);
@@ -67,7 +61,7 @@ pub fn init(cx: &mut MutableAppContext) {
}
pub enum Event {
Selected(usize, Arc<Path>),
Selected(ProjectPath),
Dismissed,
}
@@ -203,8 +197,8 @@ impl FileFinder {
)
.with_style(style.container);
let action = Select(Entry {
worktree_id: path_match.tree_id,
let action = Select(ProjectPath {
worktree_id: path_match.worktree_id,
path: path_match.path.clone(),
});
EventHandler::new(container.boxed())
@@ -256,9 +250,9 @@ impl FileFinder {
cx: &mut ViewContext<Workspace>,
) {
match event {
Event::Selected(tree_id, path) => {
Event::Selected(project_path) => {
workspace
.open_entry((*tree_id, path.clone()), cx)
.open_entry(project_path.clone(), cx)
.map(|d| d.detach());
workspace.dismiss_modal(cx);
}
@@ -338,7 +332,7 @@ impl FileFinder {
fn selected_index(&self) -> usize {
if let Some(selected) = self.selected.as_ref() {
for (ix, path_match) in self.matches.iter().enumerate() {
if (path_match.tree_id, path_match.path.as_ref())
if (path_match.worktree_id, path_match.path.as_ref())
== (selected.0, selected.1.as_ref())
{
return ix;
@@ -353,7 +347,7 @@ impl FileFinder {
if selected_index > 0 {
selected_index -= 1;
let mat = &self.matches[selected_index];
self.selected = Some((mat.tree_id, mat.path.clone()));
self.selected = Some((mat.worktree_id, mat.path.clone()));
}
self.list_state.scroll_to(selected_index);
cx.notify();
@@ -364,7 +358,7 @@ impl FileFinder {
if selected_index + 1 < self.matches.len() {
selected_index += 1;
let mat = &self.matches[selected_index];
self.selected = Some((mat.tree_id, mat.path.clone()));
self.selected = Some((mat.worktree_id, mat.path.clone()));
}
self.list_state.scroll_to(selected_index);
cx.notify();
@@ -372,12 +366,15 @@ impl FileFinder {
fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
if let Some(m) = self.matches.get(self.selected_index()) {
cx.emit(Event::Selected(m.tree_id, m.path.clone()));
cx.emit(Event::Selected(ProjectPath {
worktree_id: m.worktree_id,
path: m.path.clone(),
}));
}
}
fn select(&mut self, Select(entry): &Select, cx: &mut ViewContext<Self>) {
cx.emit(Event::Selected(entry.worktree_id, entry.path.clone()));
fn select(&mut self, Select(project_path): &Select, cx: &mut ViewContext<Self>) {
cx.emit(Event::Selected(project_path.clone()));
}
#[must_use]
+23 -12
View File
@@ -17,17 +17,29 @@ use std::{
pub struct Project {
worktrees: Vec<ModelHandle<Worktree>>,
active_entry: Option<(usize, usize)>,
active_entry: Option<ProjectEntry>,
languages: Arc<LanguageRegistry>,
rpc: Arc<Client>,
fs: Arc<dyn Fs>,
}
pub enum Event {
ActiveEntryChanged(Option<(usize, usize)>),
ActiveEntryChanged(Option<ProjectEntry>),
WorktreeRemoved(usize),
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct ProjectPath {
pub worktree_id: usize,
pub path: Arc<Path>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ProjectEntry {
pub worktree_id: usize,
pub entry_id: usize,
}
impl Project {
pub fn new(app_state: &AppState) -> Self {
Self {
@@ -99,15 +111,14 @@ impl Project {
cx.notify();
}
pub fn set_active_entry(
&mut self,
entry: Option<(usize, Arc<Path>)>,
cx: &mut ModelContext<Self>,
) {
let new_active_entry = entry.and_then(|(worktree_id, path)| {
let worktree = self.worktree_for_id(worktree_id)?;
let entry = worktree.read(cx).entry_for_path(path)?;
Some((worktree_id, entry.id))
pub fn set_active_path(&mut self, entry: Option<ProjectPath>, cx: &mut ModelContext<Self>) {
let new_active_entry = entry.and_then(|project_path| {
let worktree = self.worktree_for_id(project_path.worktree_id)?;
let entry = worktree.read(cx).entry_for_path(project_path.path)?;
Some(ProjectEntry {
worktree_id: project_path.worktree_id,
entry_id: entry.id,
})
});
if new_active_entry != self.active_entry {
self.active_entry = new_active_entry;
@@ -115,7 +126,7 @@ impl Project {
}
}
pub fn active_entry(&self) -> Option<(usize, usize)> {
pub fn active_entry(&self) -> Option<ProjectEntry> {
self.active_entry
}
+12 -9
View File
@@ -1,5 +1,5 @@
use crate::{
project::{self, Project},
project::{self, Project, ProjectEntry, ProjectPath},
theme,
workspace::Workspace,
worktree::{self, Worktree},
@@ -53,12 +53,6 @@ struct EntryDetails {
is_selected: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ProjectEntry {
pub worktree_id: usize,
pub entry_id: usize,
}
action!(ExpandSelectedEntry);
action!(CollapseSelectedEntry);
action!(ToggleExpanded, ProjectEntry);
@@ -94,7 +88,10 @@ impl ProjectPanel {
})
.detach();
cx.subscribe(&project, |this, _, event, cx| match event {
project::Event::ActiveEntryChanged(Some((worktree_id, entry_id))) => {
project::Event::ActiveEntryChanged(Some(ProjectEntry {
worktree_id,
entry_id,
})) => {
this.expand_entry(*worktree_id, *entry_id, cx);
this.update_visible_entries(Some((*worktree_id, *entry_id)), cx);
this.autoscroll();
@@ -129,7 +126,13 @@ impl ProjectPanel {
if let Some(worktree) = project.read(cx).worktree_for_id(*worktree_id) {
if let Some(entry) = worktree.read(cx).entry_for_id(*entry_id) {
workspace
.open_entry((worktree.id(), entry.path.clone()), cx)
.open_entry(
ProjectPath {
worktree_id: worktree.id(),
path: entry.path.clone(),
},
cx,
)
.map(|t| t.detach());
}
}
+70 -54
View File
@@ -7,7 +7,7 @@ use crate::{
editor::Buffer,
fs::Fs,
people_panel::{JoinWorktree, LeaveWorktree, PeoplePanel, ShareWorktree, UnshareWorktree},
project::Project,
project::{Project, ProjectPath},
project_panel::ProjectPanel,
rpc,
settings::Settings,
@@ -164,12 +164,12 @@ pub trait Item: Entity + Sized {
cx: &mut ViewContext<Self::View>,
) -> Self::View;
fn worktree_id_and_path(&self) -> Option<(usize, Arc<Path>)>;
fn project_path(&self) -> Option<ProjectPath>;
}
pub trait ItemView: View {
fn title(&self, cx: &AppContext) -> String;
fn worktree_id_and_path(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)>;
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
fn clone_on_split(&self, _: &mut ViewContext<Self>) -> Option<Self>
where
Self: Sized,
@@ -213,12 +213,12 @@ pub trait WeakItemHandle {
cx: &mut MutableAppContext,
) -> Option<Box<dyn ItemViewHandle>>;
fn alive(&self, cx: &AppContext) -> bool;
fn worktree_id_and_path(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)>;
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
}
pub trait ItemViewHandle {
fn title(&self, cx: &AppContext) -> String;
fn entry_id(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)>;
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
fn boxed_clone(&self) -> Box<dyn ItemViewHandle>;
fn clone_on_split(&self, cx: &mut MutableAppContext) -> Option<Box<dyn ItemViewHandle>>;
fn set_parent_pane(&self, pane: &ViewHandle<Pane>, cx: &mut MutableAppContext);
@@ -265,9 +265,8 @@ impl<T: Item> WeakItemHandle for WeakModelHandle<T> {
self.upgrade(cx).is_some()
}
fn worktree_id_and_path(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)> {
self.upgrade(cx)
.and_then(|h| h.read(cx).worktree_id_and_path())
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
self.upgrade(cx).and_then(|h| h.read(cx).project_path())
}
}
@@ -276,8 +275,8 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
self.read(cx).title(cx)
}
fn entry_id(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)> {
self.read(cx).worktree_id_and_path(cx)
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
self.read(cx).project_path(cx)
}
fn boxed_clone(&self) -> Box<dyn ItemViewHandle> {
@@ -368,7 +367,7 @@ pub struct Workspace {
project: ModelHandle<Project>,
items: Vec<Box<dyn WeakItemHandle>>,
loading_items: HashMap<
(usize, Arc<Path>),
ProjectPath,
postage::watch::Receiver<Option<Result<Box<dyn ItemHandle>, Arc<anyhow::Error>>>>,
>,
_observe_current_user: Task<()>,
@@ -382,9 +381,9 @@ impl Workspace {
let pane = cx.add_view(|_| Pane::new(app_state.settings.clone()));
let pane_id = pane.id();
cx.observe(&pane, move |me, _, cx| {
let active_entry = me.active_entry(cx);
let active_entry = me.active_project_path(cx);
me.project
.update(cx, |project, cx| project.set_active_entry(active_entry, cx));
.update(cx, |project, cx| project.set_active_path(active_entry, cx));
})
.detach();
cx.subscribe(&pane, move |me, _, event, cx| {
@@ -495,7 +494,7 @@ impl Workspace {
let entries = abs_paths
.iter()
.cloned()
.map(|path| self.entry_id_for_path(&path, cx))
.map(|path| self.project_path_for_path(&path, cx))
.collect::<Vec<_>>();
let fs = self.fs.clone();
@@ -562,15 +561,18 @@ impl Workspace {
})
}
fn entry_id_for_path(
fn project_path_for_path(
&self,
abs_path: &Path,
cx: &mut ViewContext<Self>,
) -> Task<Result<(usize, Arc<Path>)>> {
) -> Task<Result<ProjectPath>> {
let entry = self.worktree_for_abs_path(abs_path, cx);
cx.spawn(|_, _| async move {
let (worktree, path) = entry.await?;
Ok((worktree.id(), path.into()))
Ok(ProjectPath {
worktree_id: worktree.id(),
path: path.into(),
})
})
}
@@ -623,33 +625,38 @@ impl Workspace {
#[must_use]
pub fn open_entry(
&mut self,
entry: (usize, Arc<Path>),
project_path: ProjectPath,
cx: &mut ViewContext<Self>,
) -> Option<Task<()>> {
let pane = self.active_pane().clone();
if self.activate_or_open_existing_entry(entry.clone(), &pane, cx) {
if self.activate_or_open_existing_entry(project_path.clone(), &pane, cx) {
return None;
}
let (worktree_id, path) = entry.clone();
// let (worktree_id, path) = project_path.clone();
let worktree = match self.project.read(cx).worktree_for_id(worktree_id) {
let worktree = match self
.project
.read(cx)
.worktree_for_id(project_path.worktree_id)
{
Some(worktree) => worktree,
None => {
log::error!("worktree {} does not exist", worktree_id);
log::error!("worktree {} does not exist", project_path.worktree_id);
return None;
}
};
if let Entry::Vacant(entry) = self.loading_items.entry(entry.clone()) {
if let Entry::Vacant(entry) = self.loading_items.entry(project_path.clone()) {
let (mut tx, rx) = postage::watch::channel();
entry.insert(rx);
let project_path = project_path.clone();
cx.as_mut()
.spawn(|mut cx| async move {
let buffer = worktree
.update(&mut cx, |worktree, cx| {
worktree.open_buffer(path.as_ref(), cx)
worktree.open_buffer(project_path.path.as_ref(), cx)
})
.await;
*tx.borrow_mut() = Some(
@@ -663,7 +670,7 @@ impl Workspace {
let pane = pane.downgrade();
let settings = self.settings.clone();
let mut watch = self.loading_items.get(&entry).unwrap().clone();
let mut watch = self.loading_items.get(&project_path).unwrap().clone();
Some(cx.spawn(|this, mut cx| async move {
let load_result = loop {
@@ -674,14 +681,14 @@ impl Workspace {
};
this.update(&mut cx, |this, cx| {
this.loading_items.remove(&entry);
this.loading_items.remove(&project_path);
if let Some(pane) = pane.upgrade(&cx) {
match load_result {
Ok(item) => {
// By the time loading finishes, the entry could have been already added
// to the pane. If it was, we activate it, otherwise we'll store the
// item and add a new view for it.
if !this.activate_or_open_existing_entry(entry, &pane, cx) {
if !this.activate_or_open_existing_entry(project_path, &pane, cx) {
let weak_item = item.downgrade();
let view = weak_item
.add_view(cx.window_id(), settings, cx.as_mut())
@@ -701,13 +708,13 @@ impl Workspace {
fn activate_or_open_existing_entry(
&mut self,
entry: (usize, Arc<Path>),
project_path: ProjectPath,
pane: &ViewHandle<Pane>,
cx: &mut ViewContext<Self>,
) -> bool {
// If the pane contains a view for this file, then activate
// that item view.
if pane.update(cx, |pane, cx| pane.activate_entry(entry.clone(), cx)) {
if pane.update(cx, |pane, cx| pane.activate_entry(project_path.clone(), cx)) {
return true;
}
@@ -718,7 +725,9 @@ impl Workspace {
self.items.retain(|item| {
if item.alive(cx.as_ref()) {
if view_for_existing_item.is_none()
&& item.worktree_id_and_path(cx).map_or(false, |e| e == entry)
&& item
.project_path(cx)
.map_or(false, |item_project_path| item_project_path == project_path)
{
view_for_existing_item = Some(
item.add_view(cx.window_id(), settings.clone(), cx.as_mut())
@@ -742,14 +751,14 @@ impl Workspace {
self.active_pane().read(cx).active_item()
}
fn active_entry(&self, cx: &ViewContext<Self>) -> Option<(usize, Arc<Path>)> {
self.active_item(cx).and_then(|item| item.entry_id(cx))
fn active_project_path(&self, cx: &ViewContext<Self>) -> Option<ProjectPath> {
self.active_item(cx).and_then(|item| item.project_path(cx))
}
pub fn save_active_item(&mut self, _: &Save, cx: &mut ViewContext<Self>) {
if let Some(item) = self.active_item(cx) {
let handle = cx.handle();
if item.entry_id(cx.as_ref()).is_none() {
if item.project_path(cx.as_ref()).is_none() {
let worktree = self.worktrees(cx).first();
let start_abs_path = worktree
.and_then(|w| w.read(cx).as_local())
@@ -885,9 +894,9 @@ impl Workspace {
let pane = cx.add_view(|_| Pane::new(self.settings.clone()));
let pane_id = pane.id();
cx.observe(&pane, move |me, _, cx| {
let active_entry = me.active_entry(cx);
let active_entry = me.active_project_path(cx);
me.project
.update(cx, |project, cx| project.set_active_entry(active_entry, cx));
.update(cx, |project, cx| project.set_active_path(active_entry, cx));
})
.detach();
cx.subscribe(&pane, move |me, _, event, cx| {
@@ -1124,20 +1133,21 @@ impl View for Workspace {
#[cfg(test)]
pub trait WorkspaceHandle {
fn file_entries(&self, cx: &AppContext) -> Vec<(usize, Arc<Path>)>;
fn file_project_paths(&self, cx: &AppContext) -> Vec<ProjectPath>;
}
#[cfg(test)]
impl WorkspaceHandle for ViewHandle<Workspace> {
fn file_entries(&self, cx: &AppContext) -> Vec<(usize, Arc<Path>)> {
fn file_project_paths(&self, cx: &AppContext) -> Vec<ProjectPath> {
self.read(cx)
.worktrees(cx)
.iter()
.flat_map(|tree| {
let tree_id = tree.id();
tree.read(cx)
.files(true, 0)
.map(move |f| (tree_id, f.path.clone()))
.flat_map(|worktree| {
let worktree_id = worktree.id();
worktree.read(cx).files(true, 0).map(move |f| ProjectPath {
worktree_id,
path: f.path.clone(),
})
})
.collect::<Vec<_>>()
}
@@ -1247,7 +1257,7 @@ mod tests {
cx.read(|cx| workspace.read(cx).worktree_scans_complete(cx))
.await;
let entries = cx.read(|cx| workspace.file_entries(cx));
let entries = cx.read(|cx| workspace.file_project_paths(cx));
let file1 = entries[0].clone();
let file2 = entries[1].clone();
let file3 = entries[2].clone();
@@ -1260,7 +1270,7 @@ mod tests {
cx.read(|cx| {
let pane = workspace.read(cx).active_pane().read(cx);
assert_eq!(
pane.active_item().unwrap().entry_id(cx),
pane.active_item().unwrap().project_path(cx),
Some(file1.clone())
);
assert_eq!(pane.items().len(), 1);
@@ -1274,7 +1284,7 @@ mod tests {
cx.read(|cx| {
let pane = workspace.read(cx).active_pane().read(cx);
assert_eq!(
pane.active_item().unwrap().entry_id(cx),
pane.active_item().unwrap().project_path(cx),
Some(file2.clone())
);
assert_eq!(pane.items().len(), 2);
@@ -1287,7 +1297,7 @@ mod tests {
cx.read(|cx| {
let pane = workspace.read(cx).active_pane().read(cx);
assert_eq!(
pane.active_item().unwrap().entry_id(cx),
pane.active_item().unwrap().project_path(cx),
Some(file1.clone())
);
assert_eq!(pane.items().len(), 2);
@@ -1302,7 +1312,7 @@ mod tests {
.read(cx)
.active_item()
.unwrap()
.entry_id(cx.as_ref()),
.project_path(cx.as_ref()),
Some(file2.clone())
);
});
@@ -1319,13 +1329,13 @@ mod tests {
cx.read(|cx| {
let pane = workspace.read(cx).active_pane().read(cx);
assert_eq!(
pane.active_item().unwrap().entry_id(cx),
pane.active_item().unwrap().project_path(cx),
Some(file3.clone())
);
let pane_entries = pane
.items()
.iter()
.map(|i| i.entry_id(cx).unwrap())
.map(|i| i.project_path(cx).unwrap())
.collect::<Vec<_>>();
assert_eq!(pane_entries, &[file1, file2, file3]);
});
@@ -1468,7 +1478,7 @@ mod tests {
})
.await
.unwrap();
let tree = cx.read(|cx| {
let worktree = cx.read(|cx| {
workspace
.read(cx)
.worktrees(cx)
@@ -1543,7 +1553,13 @@ mod tests {
workspace.open_new_file(&OpenNew(app_state.clone()), cx);
workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx);
assert!(workspace
.open_entry((tree.id(), Path::new("the-new-name.rs").into()), cx)
.open_entry(
ProjectPath {
worktree_id: worktree.id(),
path: Path::new("the-new-name.rs").into()
},
cx
)
.is_none());
});
let editor2 = workspace.update(&mut cx, |workspace, cx| {
@@ -1664,7 +1680,7 @@ mod tests {
.unwrap();
cx.read(|cx| workspace.read(cx).worktree_scans_complete(cx))
.await;
let entries = cx.read(|cx| workspace.file_entries(cx));
let entries = cx.read(|cx| workspace.file_project_paths(cx));
let file1 = entries[0].clone();
let pane_1 = cx.read(|cx| workspace.read(cx).active_pane().clone());
@@ -1675,7 +1691,7 @@ mod tests {
.await;
cx.read(|cx| {
assert_eq!(
pane_1.read(cx).active_item().unwrap().entry_id(cx),
pane_1.read(cx).active_item().unwrap().project_path(cx),
Some(file1.clone())
);
});
@@ -1690,7 +1706,7 @@ mod tests {
assert_ne!(pane_1, pane_2);
let pane2_item = pane_2.read(cx).active_item().unwrap();
assert_eq!(pane2_item.entry_id(cx.as_ref()), Some(file1.clone()));
assert_eq!(pane2_item.project_path(cx.as_ref()), Some(file1.clone()));
cx.dispatch_action(window_id, vec![pane_2.id()], &CloseActiveItem);
let workspace = workspace.read(cx);
+5 -5
View File
@@ -1,5 +1,5 @@
use super::{ItemViewHandle, SplitDirection};
use crate::settings::Settings;
use crate::{project::ProjectPath, settings::Settings};
use gpui::{
action,
elements::*,
@@ -9,7 +9,7 @@ use gpui::{
Entity, MutableAppContext, Quad, RenderContext, View, ViewContext, ViewHandle,
};
use postage::watch;
use std::{cmp, path::Path, sync::Arc};
use std::cmp;
action!(Split, SplitDirection);
action!(ActivateItem, usize);
@@ -105,12 +105,12 @@ impl Pane {
pub fn activate_entry(
&mut self,
entry_id: (usize, Arc<Path>),
project_path: ProjectPath,
cx: &mut ViewContext<Self>,
) -> bool {
if let Some(index) = self.items.iter().position(|item| {
item.entry_id(cx.as_ref())
.map_or(false, |id| id == entry_id)
item.project_path(cx.as_ref())
.map_or(false, |item_path| item_path == project_path)
}) {
self.activate_item(index, cx);
true
+14 -10
View File
@@ -25,10 +25,22 @@ use postage::{
};
use serde::Deserialize;
use smol::channel::{self, Sender};
use std::{any::Any, cmp::{self, Ordering}, collections::HashMap, convert::{TryFrom, TryInto}, ffi::{OsStr, OsString}, fmt, future::Future, ops::Deref, path::{Path, PathBuf}, sync::{
use std::{
any::Any,
cmp::{self, Ordering},
collections::HashMap,
convert::{TryFrom, TryInto},
ffi::{OsStr, OsString},
fmt,
future::Future,
ops::Deref,
path::{Path, PathBuf},
sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc,
}, time::{Duration, SystemTime}};
},
time::{Duration, SystemTime},
};
use sum_tree::{self, Edit, SeekTarget, SumTree};
use zrpc::{PeerId, TypedEnvelope};
@@ -1779,14 +1791,6 @@ impl File {
mtime,
}
}
// pub fn exists(&self) -> bool {
// !self.is_deleted()
// }
pub fn worktree_id_and_path(&self) -> (usize, Arc<Path>) {
(self.worktree.id(), self.path.clone())
}
}
impl buffer::File for File {