aboutsummaryrefslogtreecommitdiffstats
path: root/default-plugins/strider/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-02-28 16:12:12 +0100
committerGitHub <noreply@github.com>2024-02-28 16:12:12 +0100
commit6340b5e312cd4c52fa7a967b44aa331253c64779 (patch)
tree425a42f6c42599f5e348df54028321ff04f65739 /default-plugins/strider/src
parentdocs(changelog): plugin aliases (diff)
downloadsl0ppij-6340b5e312cd4c52fa7a967b44aa331253c64779.tar.gz
sl0ppij-6340b5e312cd4c52fa7a967b44aa331253c64779.tar.xz
sl0ppij-6340b5e312cd4c52fa7a967b44aa331253c64779.zip
fix(plugins): respect cwd and start filepicker at filesystem root (#3161)
* allow padding cwd to plugins * improve strider performance and fix alias cwd issue * style(fmt): rustfmt
Diffstat (limited to 'default-plugins/strider/src')
-rw-r--r--default-plugins/strider/src/main.rs7
-rw-r--r--default-plugins/strider/src/state.rs48
2 files changed, 34 insertions, 21 deletions
diff --git a/default-plugins/strider/src/main.rs b/default-plugins/strider/src/main.rs
index 2e06240a..1ad2e70c 100644
--- a/default-plugins/strider/src/main.rs
+++ b/default-plugins/strider/src/main.rs
@@ -43,6 +43,9 @@ impl ZellijPlugin for State {
Key::Down | Key::Char('j') => {
let currently_selected = self.selected();
let next = self.selected().saturating_add(1);
+ if next >= self.files.len() {
+ refresh_directory(self);
+ }
*self.selected_mut() = min(self.files.len().saturating_sub(1), next);
if currently_selected != self.selected() {
should_render = true;
@@ -76,6 +79,9 @@ impl ZellijPlugin for State {
Mouse::ScrollDown(_) => {
let currently_selected = self.selected();
let next = self.selected().saturating_add(1);
+ if next >= self.files.len() {
+ refresh_directory(self);
+ }
*self.selected_mut() = min(self.files.len().saturating_sub(1), next);
if currently_selected != self.selected() {
should_render = true;
@@ -121,6 +127,7 @@ impl ZellijPlugin for State {
}
fn render(&mut self, rows: usize, cols: usize) {
+ self.current_rows = Some(rows);
for i in 0..rows {
if self.selected() < self.scroll() {
*self.scroll_mut() = self.selected();
diff --git a/default-plugins/strider/src/state.rs b/default-plugins/strider/src/state.rs
index be4ede4b..230e92ea 100644
--- a/default-plugins/strider/src/state.rs
+++ b/default-plugins/strider/src/state.rs
@@ -19,6 +19,7 @@ pub struct State {
pub loading: bool,
pub loading_animation_offset: u8,
pub should_open_floating: bool,
+ pub current_rows: Option<usize>,
}
impl State {
@@ -40,7 +41,7 @@ impl State {
pub fn traverse_dir_or_open_file(&mut self) {
if let Some(f) = self.files.get(self.selected()) {
match f.clone() {
- FsEntry::Dir(p, _) => {
+ FsEntry::Dir(p) => {
self.path = p;
refresh_directory(self);
},
@@ -55,14 +56,14 @@ impl State {
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum FsEntry {
- Dir(PathBuf, usize),
+ Dir(PathBuf),
File(PathBuf, u64),
}
impl FsEntry {
pub fn name(&self) -> String {
let path = match self {
- FsEntry::Dir(p, _) => p,
+ FsEntry::Dir(p) => p,
FsEntry::File(p, _) => p,
};
path.file_name().unwrap().to_string_lossy().into_owned()
@@ -70,7 +71,7 @@ impl FsEntry {
pub fn as_line(&self, width: usize) -> String {
let info = match self {
- FsEntry::Dir(_, s) => s.to_string(),
+ FsEntry::Dir(_s) => "".to_owned(),
FsEntry::File(_, s) => pb::convert(*s as f64),
};
let space = width.saturating_sub(info.len());
@@ -89,22 +90,27 @@ impl FsEntry {
}
pub(crate) fn refresh_directory(state: &mut State) {
- state.files = read_dir(Path::new(ROOT).join(&state.path))
- .unwrap()
- .filter_map(|res| {
- res.and_then(|d| {
- if d.metadata()?.is_dir() {
- let children = read_dir(d.path())?.count();
- Ok(FsEntry::Dir(d.path(), children))
- } else {
- let size = d.metadata()?.len();
- Ok(FsEntry::File(d.path(), size))
- }
- })
- .ok()
- .filter(|d| !d.is_hidden_file() || !state.hide_hidden_files)
- })
- .collect();
-
+ // TODO: might be good to do this asynchronously with a worker
+ let mut max_lines = (state.current_rows.unwrap_or(50) + state.scroll()) * 2; // 100 is arbitrary for performance reasons
+ let mut files = vec![];
+ for entry in read_dir(Path::new(ROOT).join(&state.path)).unwrap() {
+ if let Ok(entry) = entry {
+ if max_lines == 0 {
+ break;
+ }
+ let entry_metadata = entry.metadata().unwrap();
+ let entry = if entry_metadata.is_dir() {
+ FsEntry::Dir(entry.path())
+ } else {
+ let size = entry_metadata.len();
+ FsEntry::File(entry.path(), size)
+ };
+ if !entry.is_hidden_file() || !state.hide_hidden_files {
+ max_lines = max_lines.saturating_sub(1);
+ files.push(entry);
+ }
+ }
+ }
+ state.files = files;
state.files.sort_unstable();
}