Fix panic when rendering multiple worktrees in project panel

This commit is contained in:
Antonio Scandurra
2021-09-30 10:39:15 +02:00
parent 5cd2c56f95
commit 7a1cdc9ad1
+96 -10
View File
@@ -12,6 +12,7 @@ use gpui::{
use postage::watch;
use std::{
collections::{hash_map, HashMap},
ffi::OsStr,
ops::Range,
};
@@ -209,19 +210,18 @@ impl ProjectPanel {
.map(Vec::as_slice)
.unwrap_or(&[]);
let snapshot = worktree.read(cx).snapshot();
let root_name = OsStr::new(snapshot.root_name());
let mut cursor = snapshot.entries(false);
for ix in visible_worktree_entries[(range.start - ix)..(end_ix - ix)]
for ix in visible_worktree_entries[range.start.saturating_sub(ix)..end_ix - ix]
.iter()
.copied()
{
cursor.advance_to_offset(ix);
if let Some(entry) = cursor.entry() {
let filename = entry.path.file_name().unwrap_or(root_name);
let details = EntryDetails {
filename: entry.path.file_name().map_or_else(
|| snapshot.root_name().to_string(),
|name| name.to_string_lossy().to_string(),
),
filename: filename.to_string_lossy().to_string(),
depth: entry.path.components().count(),
is_dir: entry.is_dir(),
is_expanded: expanded_entry_ids.binary_search(&entry.id).is_ok(),
@@ -293,11 +293,9 @@ impl View for ProjectPanel {
let theme = &settings.borrow().theme.project_panel;
let this = handle.upgrade(cx).unwrap();
this.update(cx.app, |this, cx| {
let prev_len = items.len();
this.for_each_visible_entry(range.clone(), cx, |entry, details, cx| {
items.push(Self::render_entry(entry, details, theme, cx));
});
let count = items.len() - prev_len;
})
},
)
@@ -350,15 +348,34 @@ mod tests {
}),
)
.await;
fs.insert_tree(
"/root2",
json!({
"d": {
"9": ""
},
"e": {}
}),
)
.await;
let project = cx.add_model(|_| Project::new(&app_state));
let worktree = project
let root1 = project
.update(&mut cx, |project, cx| {
project.add_local_worktree("/root1".as_ref(), cx)
})
.await
.unwrap();
worktree
root1
.read_with(&cx, |t, _| t.as_local().unwrap().scan_complete())
.await;
let root2 = project
.update(&mut cx, |project, cx| {
project.add_local_worktree("/root2".as_ref(), cx)
})
.await
.unwrap();
root2
.read_with(&cx, |t, _| t.as_local().unwrap().scan_complete())
.await;
@@ -401,7 +418,28 @@ mod tests {
is_expanded: false,
is_active: false,
},
]
EntryDetails {
filename: "root2".to_string(),
depth: 0,
is_dir: true,
is_expanded: true,
is_active: false
},
EntryDetails {
filename: "d".to_string(),
depth: 1,
is_dir: true,
is_expanded: false,
is_active: false
},
EntryDetails {
filename: "e".to_string(),
depth: 1,
is_dir: true,
is_expanded: false,
is_active: false
}
],
);
toggle_expand_dir(&panel, "root1/b", &mut cx);
@@ -457,6 +495,54 @@ mod tests {
is_expanded: false,
is_active: false,
},
EntryDetails {
filename: "root2".to_string(),
depth: 0,
is_dir: true,
is_expanded: true,
is_active: false
},
EntryDetails {
filename: "d".to_string(),
depth: 1,
is_dir: true,
is_expanded: false,
is_active: false
},
EntryDetails {
filename: "e".to_string(),
depth: 1,
is_dir: true,
is_expanded: false,
is_active: false
}
]
);
assert_eq!(
visible_entry_details(&panel, 5..8, &mut cx),
[
EntryDetails {
filename: "4".to_string(),
depth: 2,
is_dir: true,
is_expanded: false,
is_active: false
},
EntryDetails {
filename: "c".to_string(),
depth: 1,
is_dir: true,
is_expanded: false,
is_active: false
},
EntryDetails {
filename: "root2".to_string(),
depth: 0,
is_dir: true,
is_expanded: true,
is_active: false
}
]
);