summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2022-10-01 19:53:46 +0200
committerCanop <cano.petrole@gmail.com>2022-10-01 19:53:46 +0200
commitc372aef844ae59e5cb65f0815c2868f19d58aa64 (patch)
tree29e01cbe1530bf73684899a1b2c200c85dedb430
parent79ed47d94cc011b2bc3dc597226768c4aed0f0c7 (diff)
Status message on toggling tree options
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/app/app.rs32
-rw-r--r--src/app/cmd_result.rs16
-rw-r--r--src/app/panel.rs3
-rw-r--r--src/app/panel_state.rs218
-rw-r--r--src/browser/browser_state.rs36
-rw-r--r--src/filesystems/filesystems_state.rs3
-rw-r--r--src/help/help_state.rs2
-rw-r--r--src/preview/preview_state.rs2
-rw-r--r--src/stage/stage_state.rs9
-rw-r--r--src/verb/internal_focus.rs1
11 files changed, 269 insertions, 56 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e03bd2b..1c9add3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+### next
+- status messages now displayed on toggling (for example showing hidden files)
+
### v1.15.0 - 2022-09-24
<a name="v1.15.0"></a>
- with `show_matching_characters_on_path_searches: false`, it's possible to show only file names even when searching paths - Fix #490
diff --git a/src/app/app.rs b/src/app/app.rs
index f9034f9..1533aba 100644
--- a/src/app/app.rs
+++ b/src/app/app.rs
@@ -266,7 +266,9 @@ impl App {
screen: self.screen, // it can't change in this function
con,
};
- match self.mut_panel().apply_command(w, &cmd, app_state, &app_cmd_context)? {
+ let cmd_result = self.mut_panel().apply_command(w, &cmd, app_state, &app_cmd_context)?;
+ debug!("cmd_result: {:?}", &cmd_result);
+ match cmd_result {
ApplyOnPanel { id } => {
if let Some(idx) = self.panel_id_to_idx(id) {
if let DisplayError(txt) = self.panels[idx].apply_command(
@@ -461,10 +463,14 @@ impl App {
error = Some(s);
}
}
- NewState(state) => {
+ NewState { state, message } => {
self.mut_panel().clear_input();
self.mut_panel().push_state(state);
- self.mut_panel().refresh_input_status(app_state, &app_cmd_context);
+ if let Some(md) = message {
+ self.mut_panel().set_message(md);
+ } else {
+ self.mut_panel().refresh_input_status(app_state, &app_cmd_context);
+ }
}
PopState => {
if is_input_invocation {
@@ -621,15 +627,17 @@ impl App {
self.update_preview(con, false); // the selection may have changed
if let Some(error) = &error {
self.mut_panel().set_error(error.to_string());
- } else {
- let app_cmd_context = AppCmdContext {
- panel_skin: &skin.focused,
- preview_panel: self.preview_panel,
- stage_panel: self.stage_panel,
- screen: self.screen,
- con,
- };
- self.mut_panel().refresh_input_status(app_state, &app_cmd_context);
+ //} else {
+ // // the refresh here removes the toggle status message. Not
+ // // sure there's a case it's useful
+ // let app_cmd_context = AppCmdContext {
+ // panel_skin: &skin.focused,
+ // preview_panel: self.preview_panel,
+ // stage_panel: self.stage_panel,
+ // screen: self.screen,
+ // con,
+ // };
+ // self.mut_panel().refresh_input_status(app_state, &app_cmd_context);
}
self.display_panels(w, skin, app_state, con)?;
if error.is_some() {
diff --git a/src/app/cmd_result.rs b/src/app/cmd_result.rs
index 465feff..ff7b462 100644
--- a/src/app/cmd_result.rs
+++ b/src/app/cmd_result.rs
@@ -48,7 +48,10 @@ pub enum CmdResult {
purpose: PanelPurpose,
direction: HDir,
},
- NewState(Box<dyn PanelState>),
+ NewState {
+ state: Box<dyn PanelState>,
+ message: Option<&'static str>, // explaining why there's a new state
+ },
PopStateAndReapply, // the state asks the command be executed on a previous state
PopState,
Quit,
@@ -63,24 +66,31 @@ impl CmdResult {
}
pub fn from_optional_state(
os: Result<BrowserState, TreeBuildError>,
+ message: Option<&'static str>,
in_new_panel: bool,
) -> CmdResult {
match os {
Ok(os) => {
if in_new_panel {
- CmdResult::NewPanel {
+ CmdResult::NewPanel { // TODO keep the message ?
state: Box::new(os),
purpose: PanelPurpose::None,
direction: HDir::Right,
}
} else {
- CmdResult::NewState(Box::new(os))
+ CmdResult::NewState {
+ state: Box::new(os),
+ message,
+ }
}
}
Err(TreeBuildError::Interrupted) => CmdResult::Keep,
Err(e) => CmdResult::error(e.to_string()),
}
}
+ pub fn new_state(state: Box<dyn PanelState>) -> Self {
+ Self::NewState { state, message: None }
+ }
pub fn error<S: Into<String>>(message: S) -> Self {
Self::DisplayError(message.into())
}
diff --git a/src/app/panel.rs b/src/app/panel.rs
index 9a2757d..9577adf 100644
--- a/src/app/panel.rs
+++ b/src/app/panel.rs
@@ -57,6 +57,9 @@ impl Panel {
pub fn set_error(&mut self, text: String) {
self.status = Status::from_error(text);
}
+ pub fn set_message<S: Into<String>>(&mut self, md: S) {
+ self.status = Status::from_message(md.into());
+ }
/// apply a command on the current state, with no
/// effect on screen
diff --git a/src/app/panel_state.rs b/src/app/panel_state.rs
index f84f697..0d79d63 100644
--- a/src/app/panel_state.rs
+++ b/src/app/panel_state.rs
@@ -153,7 +153,7 @@ pub trait PanelState {
direction: HDir::Right,
}
} else {
- CmdResult::NewState(Box::new(state))
+ CmdResult::new_state(Box::new(state))
}
}
Err(e) => CmdResult::DisplayError(format!("{}", e)),
@@ -170,7 +170,7 @@ pub trait PanelState {
direction: HDir::Right,
}
} else {
- CmdResult::NewState(Box::new(
+ CmdResult::new_state(Box::new(
HelpState::new(self.tree_options(), screen, con)
))
}
@@ -195,9 +195,11 @@ pub trait PanelState {
if o.sort == Sort::Count {
o.sort = Sort::None;
o.show_counts = false;
+ "*not sorting anymore*"
} else {
o.sort = Sort::Count;
o.show_counts = true;
+ "*now sorting by file count*"
}
},
bang,
@@ -209,9 +211,11 @@ pub trait PanelState {
if o.sort == Sort::Date {
o.sort = Sort::None;
o.show_dates = false;
+ "*not sorting anymore*"
} else {
o.sort = Sort::Date;
o.show_dates = true;
+ "*now sorting by last modified date*"
}
},
bang,
@@ -223,10 +227,12 @@ pub trait PanelState {
if o.sort == Sort::Size {
o.sort = Sort::None;
o.show_sizes = false;
+ "*not sorting anymore*"
} else {
o.sort = Sort::Size;
o.show_sizes = true;
o.show_root_fs = true;
+ "*now sorting files and directories by total size*"
}
},
bang,
@@ -235,11 +241,20 @@ pub trait PanelState {
Internal::sort_by_type => self.with_new_options(
screen,
&|o| {
- o.sort = match o.sort {
- Sort::TypeDirsFirst => Sort::TypeDirsLast,
- Sort::TypeDirsLast => Sort::None,
- _ => Sort::TypeDirsFirst,
- };
+ match o.sort {
+ Sort::TypeDirsFirst => {
+ o.sort = Sort::TypeDirsLast;
+ "*sorting by type, directories last*"
+ }
+ Sort::TypeDirsLast => {
+ o.sort = Sort::None;
+ "*not sorting anymore*"
+ }
+ _ => {
+ o.sort = Sort::TypeDirsFirst;
+ "*sorting by type, directories first*"
+ }
+ }
},
bang,
con,
@@ -247,10 +262,13 @@ pub trait PanelState {
Internal::sort_by_type_dirs_first => self.with_new_options(
screen,
&|o| {
- o.sort = match o.sort {
- Sort::TypeDirsFirst => Sort::None,
- _ => Sort::TypeDirsFirst,
- };
+ if o.sort == Sort::TypeDirsFirst {
+ o.sort = Sort::None;
+ "*not sorting anymore*"
+ } else {
+ o.sort = Sort::TypeDirsFirst;
+ "*now sorting by type, directories first*"
+ }
},
bang,
con,
@@ -258,53 +276,178 @@ pub trait PanelState {
Internal::sort_by_type_dirs_last => self.with_new_options(
screen,
&|o| {
- o.sort = match o.sort {
- Sort::TypeDirsLast => Sort::None,
- _ => Sort::TypeDirsLast,
- };
+ if o.sort == Sort::TypeDirsLast {
+ o.sort = Sort::None;
+ "*not sorting anymore*"
+ } else {
+ o.sort = Sort::TypeDirsLast;
+ "*now sorting by type, directories last*"
+ }
+ },
+ bang,
+ con,
+ ),
+ Internal::no_sort => self.with_new_options(
+ screen,
+ &|o| {
+ if o.sort == Sort::None {
+ "*still not searching*"
+ } else {
+ o.sort = Sort::None;
+ "*not sorting anymore*"
+ }
},
bang,
con,
),
- Internal::no_sort => self.with_new_options(screen, &|o| o.sort = Sort::None, bang, con),
Internal::toggle_counts => {
- self.with_new_options(screen, &|o| o.show_counts ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_counts ^= true;
+ if o.show_counts {
+ "*displaying file counts*"
+ } else {
+ "*hiding file counts*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_dates => {
- self.with_new_options(screen, &|o| o.show_dates ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_dates ^= true;
+ if o.show_dates {
+ "*displaying last modified dates*"
+ } else {
+ "*hiding last modified dates*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_device_id => {
- self.with_new_options(screen, &|o| o.show_device_id ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_device_id ^= true;
+ if o.show_device_id {
+ "*displaying device id*"
+ } else {
+ "*hiding device id*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_files => {
- self.with_new_options(screen, &|o: &mut TreeOptions| o.only_folders ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.only_folders ^= true;
+ if o.only_folders {
+ "*displaying only directories*"
+ } else {
+ "*displaying both files and directories*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_hidden => {
- self.with_new_options(screen, &|o| o.show_hidden ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_hidden ^= true;
+ if o.show_hidden {
+ "h:**y** - *Hidden files displayed*"
+ } else {
+ "h:**n** - *Hidden files not displayed*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_root_fs => {
- self.with_new_options(screen, &|o| o.show_root_fs ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_root_fs ^= true;
+ if o.show_root_fs {
+ "*displaying filesystem info for the tree's root directory*"
+ } else {
+ "*removing filesystem info*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_git_ignore => {
- self.with_new_options(screen, &|o| o.respect_git_ignore ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.respect_git_ignore ^= true;
+ if o.respect_git_ignore {
+ "gi:**y** - *applying gitignore rules*"
+ } else {
+ "gi:**n** - *not applying gitignore rules*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_git_file_info => {
- self.with_new_options(screen, &|o| o.show_git_file_info ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_git_file_info ^= true;
+ if o.show_git_file_info {
+ "*displaying git info next to files*"
+ } else {
+ "*removing git file info*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_git_status => {
self.with_new_options(
screen, &|o| {
if o.filter_by_git_status {
o.filter_by_git_status = false;
+ "*not filtering according to git status anymore*"
} else {
o.filter_by_git_status = true;
o.show_hidden = true;
+ "*only displaying new or modified files*"
}
}, bang, con
)
}
Internal::toggle_perm => {
- self.with_new_options(screen, &|o| o.show_permissions ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.show_permissions ^= true;
+ if o.show_permissions {
+ "*displaying file permissions*"
+ } else {
+ "*removing file permissions*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::toggle_sizes => self.with_new_options(
screen,
@@ -312,16 +455,30 @@ pub trait PanelState {
if o.show_sizes {
o.show_sizes = false;
o.show_root_fs = false;
+ "*removing sizes of files and directories*"
} else {
o.show_sizes = true;
o.show_root_fs = true;
+ "*now diplaying sizes of files and directories*"
}
},
bang,
con,
),
Internal::toggle_trim_root => {
- self.with_new_options(screen, &|o| o.trim_root ^= true, bang, con)
+ self.with_new_options(
+ screen,
+ &|o| {
+ o.trim_root ^= true;
+ if o.trim_root {
+ "*now trimming root from excess files*"
+ } else {
+ "*not trimming root files anymore*"
+ }
+ },
+ bang,
+ con,
+ )
}
Internal::close_preview => {
if let Some(id) = cc.app.preview_panel {
@@ -709,12 +866,15 @@ pub trait PanelState {
fn tree_options(&self) -> TreeOptions;
- /// build a cmdResult in response to a command being a change of
- /// tree options. This may or not be a new state
+ /// Build a cmdResult in response to a command being a change of
+ /// tree options. This may or not be a new state.
+ ///
+ /// The provided `change_options` function returns a status message
+ /// explaining the change
fn with_new_options(
&mut self,
screen: Screen,
- change_options: &dyn Fn(&mut TreeOptions),
+ change_options: &dyn Fn(&mut TreeOptions) -> &'static str,
in_new_panel: bool,
con: &AppContext,
) -> CmdResult;
diff --git a/src/browser/browser_state.rs b/src/browser/browser_state.rs
index 7c222c6..5a3c4ef 100644
--- a/src/browser/browser_state.rs
+++ b/src/browser/browser_state.rs
@@ -80,6 +80,7 @@ impl BrowserState {
screen: Screen,
root: PathBuf,
options: TreeOptions,
+ message: Option<&'static str>,
in_new_panel: bool,
con: &AppContext,
) -> CmdResult {
@@ -92,6 +93,7 @@ impl BrowserState {
}
CmdResult::from_optional_state(
new_state,
+ message,
in_new_panel,
)
}
@@ -147,6 +149,7 @@ impl BrowserState {
con,
&dam,
),
+ None,
in_new_panel,
))
} else {
@@ -175,6 +178,7 @@ impl BrowserState {
con,
&Dam::unlimited(),
),
+ None,
in_new_panel,
),
None => CmdResult::error("no parent found"),
@@ -238,14 +242,22 @@ impl PanelState for BrowserState {
fn with_new_options(
&mut self,
screen: Screen,
- change_options: &dyn Fn(&mut TreeOptions),
+ change_options: &dyn Fn(&mut TreeOptions) -> &'static str,
in_new_panel: bool,
con: &AppContext,
) -> CmdResult {
let tree = self.displayed_tree();
let mut options = tree.options.clone();
- change_options(&mut options);
- self.modified(screen, tree.root().clone(), options, in_new_panel, con)
+ let message = change_options(&mut options);
+ let message = Some(message);
+ self.modified(
+ screen,
+ tree.root().clone(),
+ options,
+ message,
+ in_new_panel,
+ con,
+ )
}
fn clear_pending(&mut self) {
@@ -478,7 +490,14 @@ impl PanelState for BrowserState {
let tree = self.displayed_tree();
let root = tree.root();
if let Some(new_root) = root.parent() {
- self.modified(screen, new_root.to_path_buf(), tree.options.clone(), bang, con)
+ self.modified(
+ screen,
+ new_root.to_path_buf(),
+ tree.options.clone(),
+ None,
+ bang,
+ con,
+ )
} else {
CmdResult::error(format!("{:?} has no parent", root))
}
@@ -491,7 +510,14 @@ impl PanelState for BrowserState {
.components()
.take(root_len + 1)
.collect();
- self.modified(screen, new_root, tree.options.clone(), bang, con)
+ self.modified(
+ screen,
+ new_root,
+ tree.options.clone(),
+ None,
+ bang,
+ con,
+ )
} else {
CmdResult::error("No selected line")
}
diff --git a/src/filesystems/filesystems_state.rs b/src/filesystems/filesystems_state.rs
index 0465020..e46346a 100644
--- a/src/filesystems/filesystems_state.rs
+++ b/src/filesystems/filesystems_state.rs
@@ -178,7 +178,7 @@ impl PanelState for FilesystemState {
fn with_new_options(
&mut self,
_screen: Screen,
- change_options: &dyn Fn(&mut TreeOptions),
+ change_options: &dyn Fn(&mut TreeOptions) -> &'static str,
_in_new_panel: bool, // TODO open tree if true
_con: &AppContext,
) -> CmdResult {
@@ -523,6 +523,7 @@ impl PanelState for FilesystemState {
con,
&dam,
),
+ None,
in_new_panel,
)
}
diff --git a/src/help/help_state.rs b/src/help/help_state.rs
index be309f1..0021ae3 100644
--- a/src/help/help_state.rs
+++ b/src/help/help_state.rs
@@ -77,7 +77,7 @@ impl PanelState for HelpState {
fn with_new_options(
&mut self,
_screen: Screen,
- change_options: &dyn Fn(&mut TreeOptions),
+ change_options: &dyn Fn(&mut TreeOptions) -> &'static str,
_in_new_panel: bool, // TODO open a tree if true
_con: &AppContext,
) -> CmdResult {
diff --git a/src/preview/preview_state.rs b/src/preview/preview_state.rs
index 6cc6eb0..0d9e577 100644
--- a/src/preview/preview_state.rs
+++ b/src/preview/preview_state.rs
@@ -203,7 +203,7 @@ impl PanelState for PreviewState {
fn with_new_options(
&mut self,
_screen: Screen,
- change_options: &dyn Fn(&mut TreeOptions),
+ change_options: &dyn Fn(&mut TreeOptions) -> &'static str,
_in_new_panel: bool, // TODO open tree if true
_con: &AppContext,
) -> CmdResult {
diff --git a/src/stage/stage_state.rs b/src/stage/stage_state.rs
index 997e544..229413c 100644
--- a/src/stage/stage_state.rs
+++ b/src/stage/stage_state.rs
@@ -240,7 +240,7 @@ impl PanelState for StageState {
fn with_new_options(
&mut self,
_screen: Screen,
- change_options: &dyn Fn(&mut TreeOptions),
+ change_options: &dyn Fn(&mut TreeOptions) -> &'static str,
in_new_panel: bool,
con: &AppContext,
) -> CmdResult {
@@ -248,15 +248,16 @@ impl PanelState for StageState {
CmdResult::error("stage can't be displayed in two panels")
} else {
let mut new_options= self.tree_options();
- change_options(&mut new_options);
- CmdResult::NewState(Box::new(StageState {
+ let message = change_options(&mut new_options);
+ let state = Box::new(StageState {
filtered_stage: self.filtered_stage.clone(),
scroll: self.scroll,
mode: initial_mode(con),
tree_options: new_options,
page_height: self.page_height,
stage_sum: self.stage_sum,
- }))
+ });
+ CmdResult::NewState { state, message: Some(message) }
}
}
diff --git a/src/verb/internal_focus.rs b/src/verb/internal_focus.rs
index 7a13673..b883e30 100644
--- a/src/verb/internal_focus.rs
+++ b/src/verb/internal_focus.rs
@@ -45,6 +45,7 @@ pub fn new_state_on_path(
let path = path::closest_dir(&path);
CmdResult::from_optional_state(
BrowserState::new(path, tree_options, screen, con, &Dam::unlimited()),
+ None,
false,
)
}