summaryrefslogtreecommitdiffstats
path: root/src/stage
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2021-06-01 13:01:54 +0200
committerCanop <cano.petrole@gmail.com>2021-06-01 13:03:44 +0200
commitf66974936561b95285aabfce0d194d1d574e9f5e (patch)
tree16fced838dc5c5eb25d6d291306d0a750c6999d1 /src/stage
parentde1bbcac35ac7c6ca736c7917c87f40e824e1a4a (diff)
compute total staging area size
when show_size has been set to true (for example with :toggle_sizes) The computation is done in background
Diffstat (limited to 'src/stage')
-rw-r--r--src/stage/mod.rs2
-rw-r--r--src/stage/stage.rs23
-rw-r--r--src/stage/stage_state.rs78
-rw-r--r--src/stage/stage_sum.rs44
4 files changed, 139 insertions, 8 deletions
diff --git a/src/stage/mod.rs b/src/stage/mod.rs
index e41a4e1..98bcbae 100644
--- a/src/stage/mod.rs
+++ b/src/stage/mod.rs
@@ -1,9 +1,11 @@
mod filtered_stage;
mod stage;
mod stage_state;
+mod stage_sum;
pub use {
filtered_stage::*,
stage::*,
stage_state::*,
+ stage_sum::*,
};
diff --git a/src/stage/stage.rs b/src/stage/stage.rs
index be04397..47f1d66 100644
--- a/src/stage/stage.rs
+++ b/src/stage/stage.rs
@@ -1,4 +1,9 @@
use {
+ crate::{
+ app::AppContext,
+ file_sum::FileSum,
+ task_sync::Dam,
+ },
std::{
path::{Path, PathBuf},
},
@@ -54,7 +59,7 @@ impl Stage {
}
pub fn clear(&mut self) {
self.version += 1;
- self.paths.clear()
+ self.paths.clear();
}
pub fn paths(&self) -> &[PathBuf] {
&self.paths
@@ -73,4 +78,20 @@ impl Stage {
pub fn version(&self) -> usize {
self.version
}
+ pub fn compute_sum(&self, dam: &Dam, con: &AppContext) -> Option<FileSum> {
+ let mut sum = FileSum::zero();
+ for path in &self.paths {
+ if path.is_dir() {
+ let dir_sum = FileSum::from_dir(path, dam, con);
+ if let Some(dir_sum) = dir_sum {
+ sum += dir_sum;
+ } else {
+ return None; // computation was interrupted
+ }
+ } else {
+ sum += FileSum::from_file(path);
+ }
+ }
+ Some(sum)
+ }
}
diff --git a/src/stage/stage_state.rs b/src/stage/stage_state.rs
index 4fac8c8..4dc5ed4 100644
--- a/src/stage/stage_state.rs
+++ b/src/stage/stage_state.rs
@@ -7,6 +7,7 @@ use {
errors::ProgramError,
pattern::*,
skin::*,
+ task_sync::Dam,
tree::*,
verb::*,
},
@@ -20,6 +21,8 @@ use {
};
static TITLE: &str = "Staging Area"; // no wide char allowed here
+static COUNT_LABEL: &str = " count: ";
+static SIZE_LABEL: &str = " size: ";
static ELLIPSIS: char = '…';
pub struct StageState {
@@ -28,14 +31,15 @@ pub struct StageState {
scroll: usize,
- /// those options are only kept for transmission to child state
- /// (if they become possible)
tree_options: TreeOptions,
/// the 'modal' mode
mode: Mode,
page_height: usize,
+
+ stage_sum: StageSum,
+
}
impl StageState {
@@ -55,9 +59,15 @@ impl StageState {
tree_options,
mode: initial_mode(con),
page_height: 0,
+ stage_sum: StageSum::default(),
}
}
+ fn need_sum_computation(&self) -> bool {
+ self.tree_options.show_sizes && !self.stage_sum.is_up_to_date()
+ }
+
+
pub fn try_scroll(
&mut self,
cmd: ScrollCommand,
@@ -98,7 +108,40 @@ impl StageState {
TITLE,
)?;
}
- cw.repeat(&styles.staging_area_title, &SPACE_FILLING, cw.allowed - count_len)?;
+ let mut show_count_label = false;
+ let mut rem = cw.allowed - count_len;
+ if COUNT_LABEL.len() < rem {
+ rem -= COUNT_LABEL.len();
+ show_count_label = true;
+ if self.tree_options.show_sizes {
+ if let Some(sum) = self.stage_sum.computed() {
+ let size = file_size::fit_4(sum.to_size());
+ let size_len = SIZE_LABEL.len() + size.len();
+ if size_len < rem {
+ rem -= size_len;
+ // we display the size in the middle, so we cut rem in two
+ let left_rem = rem / 2;
+ rem -= left_rem;
+ cw.repeat(&styles.staging_area_title, &SPACE_FILLING, left_rem)?;
+ cw.queue_g_string(
+ &styles.staging_area_title,
+ SIZE_LABEL.to_string(),
+ )?;
+ cw.queue_g_string(
+ &styles.staging_area_title,
+ size,
+ )?;
+ }
+ }
+ }
+ }
+ cw.repeat(&styles.staging_area_title, &SPACE_FILLING, rem)?;
+ if show_count_label {
+ cw.queue_g_string(
+ &styles.staging_area_title,
+ COUNT_LABEL.to_string(),
+ )?;
+ }
if self.filtered_stage.pattern().is_some() {
cw.queue_g_string(
&styles.char_match,
@@ -138,10 +181,6 @@ impl PanelState for StageState {
PanelStateType::Stage
}
- fn get_pending_task(&self) -> Option<&'static str> {
- None
- }
-
fn selected_path(&self) -> Option<&Path> {
None
}
@@ -150,6 +189,29 @@ impl PanelState for StageState {
None
}
+ fn clear_pending(&mut self) {
+ self.stage_sum.clear();
+ }
+ fn do_pending_task(
+ &mut self,
+ stage: &Stage,
+ _screen: Screen,
+ con: &AppContext,
+ dam: &mut Dam,
+ // need the stage here
+ ) {
+ if self.need_sum_computation() {
+ self.stage_sum.compute(stage, dam, con);
+ }
+ }
+ fn get_pending_task(&self) -> Option<&'static str> {
+ if self.need_sum_computation() {
+ Some("stage size summing")
+ } else {
+ None
+ }
+ }
+
fn sel_info<'c>(&'c self, app_state: &'c AppState) -> SelInfo<'c> {
match app_state.stage.len() {
0 => SelInfo::None,
@@ -192,6 +254,7 @@ impl PanelState for StageState {
mode: initial_mode(con),
tree_options: new_options,
page_height: self.page_height,
+ stage_sum: self.stage_sum,
}))
}
}
@@ -227,6 +290,7 @@ impl PanelState for StageState {
disc: &DisplayContext,
) -> Result<(), ProgramError> {
let stage = &disc.app_state.stage;
+ self.stage_sum.see_stage(stage); // this may invalidate the sum
if self.filtered_stage.update(stage) {
self.fix_scroll();
}
diff --git a/src/stage/stage_sum.rs b/src/stage/stage_sum.rs
new file mode 100644
index 0000000..da57628
--- /dev/null
+++ b/src/stage/stage_sum.rs
@@ -0,0 +1,44 @@
+use {
+ super::*,
+ crate::{
+ app::AppContext,
+ file_sum::FileSum,
+ task_sync::Dam,
+ },
+};
+
+#[derive(Clone, Copy, Default)]
+pub struct StageSum {
+ stage_version: usize,
+ sum: Option<FileSum>,
+}
+
+impl StageSum {
+ /// invalidates the computed sum if the version at compilation
+ /// time is older than the current one
+ pub fn see_stage(&mut self, stage: &Stage) {
+ if stage.version() != self.stage_version {
+ self.sum = None;
+ }
+ }
+ pub fn is_up_to_date(&self) -> bool {
+ self.sum.is_some()
+ }
+ pub fn clear(&mut self) {
+ self.sum = None;
+ }
+ pub fn compute(&mut self, stage: &Stage, dam: &Dam, con: &AppContext) -> Option<FileSum> {
+ if self.stage_version != stage.version() {
+ self.sum = None;
+ }
+ self.stage_version = stage.version();
+ if self.sum.is_none() {
+ // produces None in case of interruption
+ self.sum = stage.compute_sum(dam, con);
+ }
+ self.sum
+ }
+ pub fn computed(&self) -> Option<FileSum> {
+ self.sum
+ }
+}