mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-15 06:40:17 +00:00
Start work on ProjectPanel
This commit is contained in:
parent
d561f50ab1
commit
7eda614c4a
8 changed files with 293 additions and 133 deletions
|
@ -159,6 +159,10 @@ extends = "$people_panel.shared_worktree"
|
|||
background = "$state.hover"
|
||||
corner_radius = 6
|
||||
|
||||
[project_panel]
|
||||
extends = "$panel"
|
||||
entry = "$text.0"
|
||||
|
||||
[selector]
|
||||
background = "$surface.0"
|
||||
padding = 8
|
||||
|
|
|
@ -10,7 +10,7 @@ pub mod language;
|
|||
pub mod menus;
|
||||
pub mod people_panel;
|
||||
pub mod project;
|
||||
pub mod project_browser;
|
||||
pub mod project_panel;
|
||||
pub mod rpc;
|
||||
pub mod settings;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
use super::worktree::Worktree;
|
||||
use crate::{
|
||||
fs::Fs,
|
||||
language::LanguageRegistry,
|
||||
rpc::Client,
|
||||
util::TryFutureExt as _,
|
||||
worktree::{self, Worktree},
|
||||
AppState,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use gpui::{Entity, ModelContext, ModelHandle, Task};
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
pub struct Project {
|
||||
worktrees: Vec<ModelHandle<Worktree>>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
rpc: Arc<Client>,
|
||||
fs: Arc<dyn Fs>,
|
||||
}
|
||||
|
||||
pub enum Event {}
|
||||
|
||||
impl Project {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(app_state: &AppState) -> Self {
|
||||
Self {
|
||||
worktrees: Default::default(),
|
||||
languages: app_state.languages.clone(),
|
||||
rpc: app_state.rpc.clone(),
|
||||
fs: app_state.fs.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,30 +40,88 @@ impl Project {
|
|||
.cloned()
|
||||
}
|
||||
|
||||
pub fn add_worktree(&mut self, worktree: ModelHandle<Worktree>) {
|
||||
self.worktrees.push(worktree);
|
||||
pub fn add_local_worktree(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<ModelHandle<Worktree>>> {
|
||||
let fs = self.fs.clone();
|
||||
let rpc = self.rpc.clone();
|
||||
let languages = self.languages.clone();
|
||||
let path = Arc::from(path);
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let worktree = Worktree::open_local(rpc, path, fs, languages, &mut cx).await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.add_worktree(worktree.clone(), cx);
|
||||
});
|
||||
Ok(worktree)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn share_worktree(
|
||||
&self,
|
||||
pub fn add_remote_worktree(
|
||||
&mut self,
|
||||
remote_id: u64,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Option<Task<Result<u64>>> {
|
||||
for worktree in &self.worktrees {
|
||||
let task = worktree.update(cx, |worktree, cx| {
|
||||
worktree.as_local_mut().and_then(|worktree| {
|
||||
if worktree.remote_id() == Some(remote_id) {
|
||||
Some(worktree.share(cx))
|
||||
} else {
|
||||
None
|
||||
) -> Task<Result<ModelHandle<Worktree>>> {
|
||||
let rpc = self.rpc.clone();
|
||||
let languages = self.languages.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
let worktree =
|
||||
Worktree::open_remote(rpc.clone(), remote_id, languages, &mut cx).await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
cx.subscribe(&worktree, move |this, _, event, cx| match event {
|
||||
worktree::Event::Closed => {
|
||||
this.close_remote_worktree(remote_id, cx);
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
this.add_worktree(worktree.clone(), cx);
|
||||
});
|
||||
if task.is_some() {
|
||||
return task;
|
||||
Ok(worktree)
|
||||
})
|
||||
}
|
||||
|
||||
fn add_worktree(&mut self, worktree: ModelHandle<Worktree>, cx: &mut ModelContext<Self>) {
|
||||
cx.observe(&worktree, |_, _, cx| cx.notify()).detach();
|
||||
self.worktrees.push(worktree);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn share_worktree(&self, remote_id: u64, cx: &mut ModelContext<Self>) {
|
||||
let rpc = self.rpc.clone();
|
||||
cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
|
||||
let task = this.update(&mut cx, |this, cx| {
|
||||
for worktree in &this.worktrees {
|
||||
let task = worktree.update(cx, |worktree, cx| {
|
||||
worktree.as_local_mut().and_then(|worktree| {
|
||||
if worktree.remote_id() == Some(remote_id) {
|
||||
Some(worktree.share(cx))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
});
|
||||
if task.is_some() {
|
||||
return task;
|
||||
}
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
if let Some(task) = task {
|
||||
task.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
None
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn unshare_worktree(&mut self, remote_id: u64, cx: &mut ModelContext<Self>) {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
use gpui::{elements::Empty, Element, Entity, View};
|
||||
|
||||
pub struct ProjectBrowser;
|
||||
|
||||
pub enum Event {}
|
||||
|
||||
impl Entity for ProjectBrowser {
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
impl View for ProjectBrowser {
|
||||
fn ui_name() -> &'static str {
|
||||
"ProjectBrowser"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
118
zed/src/project_panel.rs
Normal file
118
zed/src/project_panel.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use crate::{
|
||||
project::Project,
|
||||
theme::Theme,
|
||||
worktree::{self, Worktree},
|
||||
Settings,
|
||||
};
|
||||
use gpui::{
|
||||
elements::{Empty, Label, List, ListState, Orientation},
|
||||
AppContext, Element, ElementBox, Entity, ModelHandle, View, ViewContext,
|
||||
};
|
||||
use postage::watch;
|
||||
|
||||
pub struct ProjectPanel {
|
||||
project: ModelHandle<Project>,
|
||||
list: ListState,
|
||||
settings: watch::Receiver<Settings>,
|
||||
}
|
||||
|
||||
pub enum Event {}
|
||||
|
||||
impl ProjectPanel {
|
||||
pub fn new(
|
||||
project: ModelHandle<Project>,
|
||||
settings: watch::Receiver<Settings>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
cx.observe(&project, |this, project, cx| {
|
||||
let project = project.read(cx);
|
||||
this.list.reset(Self::entry_count(project, cx));
|
||||
cx.notify();
|
||||
})
|
||||
.detach();
|
||||
|
||||
Self {
|
||||
list: ListState::new(
|
||||
{
|
||||
let project = project.read(cx);
|
||||
Self::entry_count(project, cx)
|
||||
},
|
||||
Orientation::Top,
|
||||
1000.,
|
||||
{
|
||||
let project = project.clone();
|
||||
let settings = settings.clone();
|
||||
move |ix, cx| {
|
||||
let project = project.read(cx);
|
||||
Self::render_entry_at_index(project, ix, &settings.borrow().theme, cx)
|
||||
}
|
||||
},
|
||||
),
|
||||
project,
|
||||
settings,
|
||||
}
|
||||
}
|
||||
|
||||
fn entry_count(project: &Project, cx: &AppContext) -> usize {
|
||||
project
|
||||
.worktrees()
|
||||
.iter()
|
||||
.map(|worktree| worktree.read(cx).visible_entry_count())
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn render_entry_at_index(
|
||||
project: &Project,
|
||||
mut ix: usize,
|
||||
theme: &Theme,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox {
|
||||
for worktree in project.worktrees() {
|
||||
let worktree = worktree.read(cx);
|
||||
let visible_entry_count = worktree.visible_entry_count();
|
||||
if ix < visible_entry_count {
|
||||
let entry = worktree.visible_entries(ix).next().unwrap();
|
||||
return Self::render_entry(worktree, entry, theme, cx);
|
||||
} else {
|
||||
ix -= visible_entry_count;
|
||||
}
|
||||
}
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
fn render_entry(
|
||||
worktree: &Worktree,
|
||||
entry: &worktree::Entry,
|
||||
theme: &Theme,
|
||||
_: &AppContext,
|
||||
) -> ElementBox {
|
||||
let path = &entry.path;
|
||||
let depth = path.iter().count() as f32;
|
||||
Label::new(
|
||||
path.file_name()
|
||||
.map_or(String::new(), |s| s.to_string_lossy().to_string()),
|
||||
theme.project_panel.entry.clone(),
|
||||
)
|
||||
.contained()
|
||||
.with_margin_left(depth * 20.)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl View for ProjectPanel {
|
||||
fn ui_name() -> &'static str {
|
||||
"ProjectPanel"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox {
|
||||
let theme = &self.settings.borrow().theme.project_panel;
|
||||
List::new(self.list.clone())
|
||||
.contained()
|
||||
.with_style(theme.container)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for ProjectPanel {
|
||||
type Event = Event;
|
||||
}
|
|
@ -25,6 +25,7 @@ pub struct Theme {
|
|||
pub workspace: Workspace,
|
||||
pub chat_panel: ChatPanel,
|
||||
pub people_panel: PeoplePanel,
|
||||
pub project_panel: ProjectPanel,
|
||||
pub selector: Selector,
|
||||
pub editor: EditorStyle,
|
||||
pub syntax: SyntaxTheme,
|
||||
|
@ -106,6 +107,13 @@ pub struct ChatPanel {
|
|||
pub hovered_sign_in_prompt: TextStyle,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ProjectPanel {
|
||||
#[serde(flatten)]
|
||||
pub container: ContainerStyle,
|
||||
pub entry: TextStyle,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PeoplePanel {
|
||||
#[serde(flatten)]
|
||||
|
|
|
@ -6,15 +6,13 @@ use crate::{
|
|||
chat_panel::ChatPanel,
|
||||
editor::Buffer,
|
||||
fs::Fs,
|
||||
language::LanguageRegistry,
|
||||
people_panel::{JoinWorktree, LeaveWorktree, PeoplePanel, ShareWorktree, UnshareWorktree},
|
||||
project::Project,
|
||||
project_browser::ProjectBrowser,
|
||||
project_panel::ProjectPanel,
|
||||
rpc,
|
||||
settings::Settings,
|
||||
user,
|
||||
util::TryFutureExt as _,
|
||||
worktree::{self, File, Worktree},
|
||||
worktree::{File, Worktree},
|
||||
AppState, Authenticate,
|
||||
};
|
||||
use anyhow::Result;
|
||||
|
@ -340,7 +338,6 @@ impl Clone for Box<dyn ItemHandle> {
|
|||
|
||||
pub struct Workspace {
|
||||
pub settings: watch::Receiver<Settings>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
rpc: Arc<rpc::Client>,
|
||||
user_store: ModelHandle<user::UserStore>,
|
||||
fs: Arc<dyn Fs>,
|
||||
|
@ -361,7 +358,8 @@ pub struct Workspace {
|
|||
|
||||
impl Workspace {
|
||||
pub fn new(app_state: &AppState, cx: &mut ViewContext<Self>) -> Self {
|
||||
let project = cx.add_model(|_| Project::new());
|
||||
let project = cx.add_model(|_| Project::new(app_state));
|
||||
cx.observe(&project, |_, _, cx| cx.notify()).detach();
|
||||
|
||||
let pane = cx.add_view(|_| Pane::new(app_state.settings.clone()));
|
||||
let pane_id = pane.id();
|
||||
|
@ -374,7 +372,8 @@ impl Workspace {
|
|||
let mut left_sidebar = Sidebar::new(Side::Left);
|
||||
left_sidebar.add_item(
|
||||
"icons/folder-tree-16.svg",
|
||||
cx.add_view(|_| ProjectBrowser).into(),
|
||||
cx.add_view(|cx| ProjectPanel::new(project.clone(), app_state.settings.clone(), cx))
|
||||
.into(),
|
||||
);
|
||||
|
||||
let mut right_sidebar = Sidebar::new(Side::Right);
|
||||
|
@ -421,7 +420,6 @@ impl Workspace {
|
|||
panes: vec![pane.clone()],
|
||||
active_pane: pane.clone(),
|
||||
settings: app_state.settings.clone(),
|
||||
languages: app_state.languages.clone(),
|
||||
rpc: app_state.rpc.clone(),
|
||||
user_store: app_state.user_store.clone(),
|
||||
fs: app_state.fs.clone(),
|
||||
|
@ -554,21 +552,8 @@ impl Workspace {
|
|||
path: &Path,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Result<ModelHandle<Worktree>>> {
|
||||
let languages = self.languages.clone();
|
||||
let rpc = self.rpc.clone();
|
||||
let fs = self.fs.clone();
|
||||
let path = Arc::from(path);
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let worktree = Worktree::open_local(rpc, path, fs, languages, &mut cx).await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
cx.observe(&worktree, |_, _, cx| cx.notify()).detach();
|
||||
this.project.update(cx, |project, _| {
|
||||
project.add_worktree(worktree.clone());
|
||||
});
|
||||
cx.notify();
|
||||
});
|
||||
Ok(worktree)
|
||||
})
|
||||
self.project
|
||||
.update(cx, |project, cx| project.add_local_worktree(path, cx))
|
||||
}
|
||||
|
||||
pub fn toggle_modal<V, F>(&mut self, cx: &mut ViewContext<Self>, add_view: F)
|
||||
|
@ -828,72 +813,23 @@ impl Workspace {
|
|||
}
|
||||
|
||||
fn share_worktree(&mut self, action: &ShareWorktree, cx: &mut ViewContext<Self>) {
|
||||
let rpc = self.rpc.clone();
|
||||
let remote_id = action.0;
|
||||
cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
|
||||
let task = this.update(&mut cx, |this, cx| {
|
||||
this.project
|
||||
.update(cx, |project, cx| project.share_worktree(remote_id, cx))
|
||||
});
|
||||
|
||||
if let Some(share_task) = task {
|
||||
share_task.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
self.project
|
||||
.update(cx, |p, cx| p.share_worktree(action.0, cx));
|
||||
}
|
||||
|
||||
fn unshare_worktree(&mut self, action: &UnshareWorktree, cx: &mut ViewContext<Self>) {
|
||||
let remote_id = action.0;
|
||||
self.project
|
||||
.update(cx, |project, cx| project.unshare_worktree(remote_id, cx));
|
||||
.update(cx, |p, cx| p.unshare_worktree(action.0, cx));
|
||||
}
|
||||
|
||||
fn join_worktree(&mut self, action: &JoinWorktree, cx: &mut ViewContext<Self>) {
|
||||
let rpc = self.rpc.clone();
|
||||
let languages = self.languages.clone();
|
||||
let worktree_id = action.0;
|
||||
|
||||
cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
let worktree =
|
||||
Worktree::open_remote(rpc.clone(), worktree_id, languages, &mut cx).await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
cx.observe(&worktree, |_, _, cx| cx.notify()).detach();
|
||||
cx.subscribe(&worktree, move |this, _, event, cx| match event {
|
||||
worktree::Event::Closed => {
|
||||
this.project.update(cx, |project, cx| {
|
||||
project.close_remote_worktree(worktree_id, cx);
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
this.project
|
||||
.update(cx, |project, _| project.add_worktree(worktree));
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
self.project
|
||||
.update(cx, |p, cx| p.add_remote_worktree(action.0, cx).detach());
|
||||
}
|
||||
|
||||
fn leave_worktree(&mut self, action: &LeaveWorktree, cx: &mut ViewContext<Self>) {
|
||||
let remote_id = action.0;
|
||||
self.project.update(cx, |project, cx| {
|
||||
project.close_remote_worktree(remote_id, cx);
|
||||
});
|
||||
self.project
|
||||
.update(cx, |p, cx| p.close_remote_worktree(action.0, cx));
|
||||
}
|
||||
|
||||
fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> ViewHandle<Pane> {
|
||||
|
|
|
@ -1474,12 +1474,24 @@ impl Snapshot {
|
|||
self.entries_by_path.summary().file_count
|
||||
}
|
||||
|
||||
pub fn visible_entry_count(&self) -> usize {
|
||||
self.entries_by_path.summary().visible_count
|
||||
}
|
||||
|
||||
pub fn visible_file_count(&self) -> usize {
|
||||
self.entries_by_path.summary().visible_file_count
|
||||
}
|
||||
|
||||
pub fn files(&self, start: usize) -> FileIter {
|
||||
FileIter::all(self, start)
|
||||
pub fn files(&self, start: usize) -> EntryIter {
|
||||
EntryIter::files(self, start)
|
||||
}
|
||||
|
||||
pub fn visible_entries(&self, start: usize) -> EntryIter {
|
||||
EntryIter::visible(self, start)
|
||||
}
|
||||
|
||||
pub fn visible_files(&self, start: usize) -> EntryIter {
|
||||
EntryIter::visible_files(self, start)
|
||||
}
|
||||
|
||||
pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> {
|
||||
|
@ -1490,10 +1502,6 @@ impl Snapshot {
|
|||
.map(|entry| &entry.path)
|
||||
}
|
||||
|
||||
pub fn visible_files(&self, start: usize) -> FileIter {
|
||||
FileIter::visible(self, start)
|
||||
}
|
||||
|
||||
fn child_entries<'a>(&'a self, path: &'a Path) -> ChildEntriesIter<'a> {
|
||||
ChildEntriesIter::new(path, self)
|
||||
}
|
||||
|
@ -1891,22 +1899,31 @@ impl sum_tree::Item for Entry {
|
|||
|
||||
fn summary(&self) -> Self::Summary {
|
||||
let file_count;
|
||||
let visible_count;
|
||||
let visible_file_count;
|
||||
if self.is_file() {
|
||||
file_count = 1;
|
||||
if self.is_ignored {
|
||||
visible_count = 0;
|
||||
visible_file_count = 0;
|
||||
} else {
|
||||
visible_count = 1;
|
||||
visible_file_count = 1;
|
||||
}
|
||||
} else {
|
||||
file_count = 0;
|
||||
visible_file_count = 0;
|
||||
if self.is_ignored {
|
||||
visible_count = 0;
|
||||
} else {
|
||||
visible_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
EntrySummary {
|
||||
max_path: self.path.clone(),
|
||||
file_count,
|
||||
visible_count,
|
||||
visible_file_count,
|
||||
}
|
||||
}
|
||||
|
@ -1925,6 +1942,7 @@ pub struct EntrySummary {
|
|||
max_path: Arc<Path>,
|
||||
file_count: usize,
|
||||
visible_file_count: usize,
|
||||
visible_count: usize,
|
||||
}
|
||||
|
||||
impl Default for EntrySummary {
|
||||
|
@ -1932,6 +1950,7 @@ impl Default for EntrySummary {
|
|||
Self {
|
||||
max_path: Arc::from(Path::new("")),
|
||||
file_count: 0,
|
||||
visible_count: 0,
|
||||
visible_file_count: 0,
|
||||
}
|
||||
}
|
||||
|
@ -1943,6 +1962,7 @@ impl sum_tree::Summary for EntrySummary {
|
|||
fn add_summary(&mut self, rhs: &Self, _: &()) {
|
||||
self.max_path = rhs.max_path.clone();
|
||||
self.file_count += rhs.file_count;
|
||||
self.visible_count += rhs.visible_count;
|
||||
self.visible_file_count += rhs.visible_file_count;
|
||||
}
|
||||
}
|
||||
|
@ -2054,6 +2074,15 @@ impl<'a> sum_tree::Dimension<'a, EntrySummary> for FileCount {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct VisibleCount(usize);
|
||||
|
||||
impl<'a> sum_tree::Dimension<'a, EntrySummary> for VisibleCount {
|
||||
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
|
||||
self.0 += summary.visible_count;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct VisibleFileCount(usize);
|
||||
|
||||
|
@ -2555,31 +2584,42 @@ impl WorktreeHandle for ModelHandle<Worktree> {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum FileIter<'a> {
|
||||
All(Cursor<'a, Entry, FileCount, ()>),
|
||||
Visible(Cursor<'a, Entry, VisibleFileCount, ()>),
|
||||
pub enum EntryIter<'a> {
|
||||
Files(Cursor<'a, Entry, FileCount, ()>),
|
||||
Visible(Cursor<'a, Entry, VisibleCount, ()>),
|
||||
VisibleFiles(Cursor<'a, Entry, VisibleFileCount, ()>),
|
||||
}
|
||||
|
||||
impl<'a> FileIter<'a> {
|
||||
fn all(snapshot: &'a Snapshot, start: usize) -> Self {
|
||||
impl<'a> EntryIter<'a> {
|
||||
fn files(snapshot: &'a Snapshot, start: usize) -> Self {
|
||||
let mut cursor = snapshot.entries_by_path.cursor();
|
||||
cursor.seek(&FileCount(start), Bias::Right, &());
|
||||
Self::All(cursor)
|
||||
Self::Files(cursor)
|
||||
}
|
||||
|
||||
fn visible(snapshot: &'a Snapshot, start: usize) -> Self {
|
||||
let mut cursor = snapshot.entries_by_path.cursor();
|
||||
cursor.seek(&VisibleFileCount(start), Bias::Right, &());
|
||||
cursor.seek(&VisibleCount(start), Bias::Right, &());
|
||||
Self::Visible(cursor)
|
||||
}
|
||||
|
||||
fn visible_files(snapshot: &'a Snapshot, start: usize) -> Self {
|
||||
let mut cursor = snapshot.entries_by_path.cursor();
|
||||
cursor.seek(&VisibleFileCount(start), Bias::Right, &());
|
||||
Self::VisibleFiles(cursor)
|
||||
}
|
||||
|
||||
fn next_internal(&mut self) {
|
||||
match self {
|
||||
Self::All(cursor) => {
|
||||
Self::Files(cursor) => {
|
||||
let ix = *cursor.seek_start();
|
||||
cursor.seek_forward(&FileCount(ix.0 + 1), Bias::Right, &());
|
||||
}
|
||||
Self::Visible(cursor) => {
|
||||
let ix = *cursor.seek_start();
|
||||
cursor.seek_forward(&VisibleCount(ix.0 + 1), Bias::Right, &());
|
||||
}
|
||||
Self::VisibleFiles(cursor) => {
|
||||
let ix = *cursor.seek_start();
|
||||
cursor.seek_forward(&VisibleFileCount(ix.0 + 1), Bias::Right, &());
|
||||
}
|
||||
|
@ -2588,13 +2628,14 @@ impl<'a> FileIter<'a> {
|
|||
|
||||
fn item(&self) -> Option<&'a Entry> {
|
||||
match self {
|
||||
Self::All(cursor) => cursor.item(),
|
||||
Self::Files(cursor) => cursor.item(),
|
||||
Self::Visible(cursor) => cursor.item(),
|
||||
Self::VisibleFiles(cursor) => cursor.item(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for FileIter<'a> {
|
||||
impl<'a> Iterator for EntryIter<'a> {
|
||||
type Item = &'a Entry;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
|
Loading…
Reference in a new issue