diff options
-rw-r--r-- | src/app/display_settings.rs | 61 | ||||
-rw-r--r-- | src/app/mod.rs | 2 | ||||
-rw-r--r-- | src/app/status.rs | 67 | ||||
-rw-r--r-- | src/event/event_exec.rs | 8 | ||||
-rw-r--r-- | src/io/display.rs | 16 |
5 files changed, 92 insertions, 62 deletions
diff --git a/src/app/display_settings.rs b/src/app/display_settings.rs new file mode 100644 index 0000000..9f2b3f8 --- /dev/null +++ b/src/app/display_settings.rs @@ -0,0 +1,61 @@ +use anyhow::Result; +use std::sync::Arc; + +use tuikit::term::Term; + +use crate::config::Settings; +use crate::io::Args; +use crate::io::MIN_WIDTH_FOR_DUAL_PANE; + +/// Holds settings about display : +/// - do we display one or two tabs ? +/// - do we display files metadata ? +/// - do we use to second pane to preview files ? +pub struct DisplaySettings { + /// do we display one or two tabs ? + pub dual: bool, + /// do we display all info or only the filenames ? + pub metadata: bool, + /// use the second pane to preview + pub preview: bool, +} + +impl DisplaySettings { + pub fn new(args: Args, settings: &Settings, term: &Arc<Term>) -> Result<Self> { + Ok(Self { + metadata: Self::parse_display_full(args.simple, settings.full), + dual: Self::parse_dual_pane(args.dual, settings.dual, &term)?, + preview: args.preview, + }) + } + + fn parse_dual_pane( + args_dual: Option<bool>, + dual_config: bool, + term: &Arc<Term>, + ) -> Result<bool> { + if !Self::display_wide_enough(term)? { + return Ok(false); + } + if let Some(args_dual) = args_dual { + return Ok(args_dual); + } + Ok(dual_config) + } + + fn parse_display_full(simple_args: Option<bool>, full_config: bool) -> bool { + if let Some(simple_args) = simple_args { + return !simple_args; + } + full_config + } + + /// True iff the terminal is wide enough to display two panes + /// + /// # Errors + /// + /// Fail if the terminal has crashed + pub fn display_wide_enough(term: &Arc<Term>) -> Result<bool> { + Ok(term.term_size()?.0 >= MIN_WIDTH_FOR_DUAL_PANE) + } +} diff --git a/src/app/mod.rs b/src/app/mod.rs index e521e07..b647816 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,10 +1,12 @@ mod application; +mod display_settings; mod first_line; mod refresher; mod status; mod tab; pub use application::FM; +pub use display_settings::DisplaySettings; pub use first_line::FirstLine; pub use refresher::Refresher; pub use status::Status; diff --git a/src/app/status.rs b/src/app/status.rs index 8a47efb..818f60f 100644 --- a/src/app/status.rs +++ b/src/app/status.rs @@ -9,6 +9,7 @@ use sysinfo::{Disk, DiskExt, RefreshKind, System, SystemExt}; use tuikit::prelude::{from_keyname, Event}; use tuikit::term::Term; +use crate::app::DisplaySettings; use crate::app::Tab; use crate::common::{args_is_empty, is_sudo_command, path_to_string}; use crate::common::{current_username, disk_space, filename_from_path, is_program_in_path}; @@ -55,12 +56,6 @@ pub struct Status { pub tabs: [Tab; 2], /// Index of the current selected tab pub index: usize, - /// do we display one or two tabs ? - pub dual_pane: bool, - /// do we display all info or only the filenames ? - pub display_metadata: bool, - /// use the second pane to preview auto - pub preview_second: bool, /// Do we have to clear the screen ? pub force_clear: bool, @@ -68,7 +63,7 @@ pub struct Status { pub term: Arc<Term>, /// Info about the running machine. Only used to detect disks /// and their mount points. - pub system_info: System, + pub sys: System, /// NVIM RPC server address pub nvim_server: String, @@ -79,6 +74,8 @@ pub struct Status { /// Navigable menu pub menu: Menu, + /// Display settings + pub settings: DisplaySettings, } impl Status { @@ -92,18 +89,13 @@ impl Status { settings: &Settings, ) -> Result<Self> { let args = Args::parse(); - let preview_second = args.preview; let nvim_server = args.server.clone(); - let display_metadata = Self::parse_display_full(args.simple, settings.full); - let dual_pane = Self::parse_dual_pane(args.dual, settings.dual, &term)?; let sys = System::new_with_specifics(RefreshKind::new().with_disks()); let force_clear = false; let skimer = None; let index = 0; - // unsafe because of UsersCache::with_all_users let users = Users::new(); - // unsafe because of UsersCache::with_all_users let users2 = users.clone(); let mount_points = Self::disks_mounts(sys.disks()); @@ -112,20 +104,19 @@ impl Status { Tab::new(&args, height, users, settings, &mount_points)?, Tab::new(&args, height, users2, settings, &mount_points)?, ]; + let settings = DisplaySettings::new(args, settings, &term)?; let menu = Menu::new()?; Ok(Self { tabs, index, skimer, term, - dual_pane, - preview_second, - system_info: sys, - display_metadata, + sys, opener, nvim_server, force_clear, menu, + settings, }) } @@ -136,33 +127,9 @@ impl Status { Ok(()) } - fn display_wide_enough(term: &Arc<Term>) -> Result<bool> { - Ok(term.term_size()?.0 >= MIN_WIDTH_FOR_DUAL_PANE) - } - - fn parse_display_full(simple_args: Option<bool>, full_config: bool) -> bool { - if let Some(simple_args) = simple_args { - return !simple_args; - } - full_config - } - - fn parse_dual_pane( - args_dual: Option<bool>, - dual_config: bool, - term: &Arc<Term>, - ) -> Result<bool> { - if !Self::display_wide_enough(term)? { - return Ok(false); - } - if let Some(args_dual) = args_dual { - return Ok(args_dual); - } - Ok(dual_config) - } /// Select the other tab if two are displayed. Does nother otherwise. pub fn next(&mut self) { - if !self.dual_pane { + if !self.settings.dual { return; } self.index = 1 - self.index @@ -445,8 +412,8 @@ impl Status { // self.system_info.refresh_disks(); // the slow variant, which check if the disks have changed. - self.system_info.refresh_disks_list(); - let disks = self.system_info.disks(); + self.sys.refresh_disks_list(); + let disks = self.sys.disks(); let mounts = Self::disks_mounts(disks); self.tabs[0].refresh_shortcuts(&mounts); self.tabs[1].refresh_shortcuts(&mounts); @@ -454,7 +421,7 @@ impl Status { /// Returns an array of Disks pub fn disks(&self) -> &[Disk] { - self.system_info.disks() + self.sys.disks() } /// Returns a the disk spaces for the selected tab.. @@ -535,7 +502,7 @@ impl Status { }?; self.selected().set_display_mode(Display::Normal) } else { - self.display_metadata = true; + self.settings.metadata = true; self.selected().make_tree(None)?; self.selected().set_display_mode(Display::Tree); } @@ -544,7 +511,7 @@ impl Status { /// Check if the second pane should display a preview and force it. pub fn update_second_pane_for_preview(&mut self) -> Result<()> { - if self.index == 0 && self.preview_second { + if self.index == 0 && self.settings.preview { self.set_second_pane_for_preview()?; }; Ok(()) @@ -553,7 +520,7 @@ impl Status { /// Force preview the selected file of the first pane in the second pane. /// Doesn't check if it has do. pub fn set_second_pane_for_preview(&mut self) -> Result<()> { - if !Self::display_wide_enough(&self.term)? { + if !DisplaySettings::display_wide_enough(&self.term)? { self.tabs[1].preview = Preview::empty(); return Ok(()); } @@ -577,9 +544,9 @@ impl Status { pub fn set_dual_pane_if_wide_enough(&mut self, width: usize) -> Result<()> { if width < MIN_WIDTH_FOR_DUAL_PANE { self.select_tab(0)?; - self.dual_pane = false; + self.settings.dual = false; } else { - self.dual_pane = true; + self.settings.dual = true; } Ok(()) } @@ -979,7 +946,7 @@ impl Status { /// Select the left or right tab depending on where the user clicked. pub fn select_pane(&mut self, col: u16) -> Result<()> { let (width, _) = self.term_size()?; - if self.dual_pane { + if self.settings.dual { if (col as usize) < width / 2 { self.select_tab(0)?; } else { diff --git a/src/event/event_exec.rs b/src/event/event_exec.rs index c289c88..3993c8a 100644 --- a/src/event/event_exec.rs +++ b/src/event/event_exec.rs @@ -855,14 +855,14 @@ impl EventAction { /// Toggle between a full display (aka ls -lah) or a simple mode (only the /// filenames). pub fn toggle_display_full(status: &mut Status) -> Result<()> { - status.display_metadata = !status.display_metadata; + status.settings.metadata = !status.settings.metadata; Ok(()) } /// Toggle between dualpane and single pane. Does nothing if the width /// is too low to display both panes. pub fn toggle_dualpane(status: &mut Status) -> Result<()> { - status.dual_pane = !status.dual_pane; + status.settings.dual = !status.settings.dual; status.select_tab(0)?; Ok(()) } @@ -995,8 +995,8 @@ impl EventAction { /// Toggle the second pane between preview & normal mode (files). pub fn toggle_preview_second(status: &mut Status) -> Result<()> { - status.preview_second = !status.preview_second; - if status.preview_second { + status.settings.preview = !status.settings.preview; + if status.settings.preview { status.set_second_pane_for_preview()?; } else { status.tabs[1].reset_edit_mode(); diff --git a/src/io/display.rs b/src/io/display.rs index cfcb8d2..9c8d0eb 100644 --- a/src/io/display.rs +++ b/src/io/display.rs @@ -125,7 +125,7 @@ struct WinMain<'a> { impl<'a> Draw for WinMain<'a> { fn draw(&self, canvas: &mut dyn Canvas) -> DrawResult<()> { canvas.clear()?; - if self.status.dual_pane && self.is_right() && self.status.preview_second { + if self.status.settings.dual && self.is_right() && self.status.settings.preview { self.draw_preview_as_second_pane(canvas)?; return Ok(()); } @@ -180,7 +180,7 @@ impl<'a> WinMain<'a> { let len = self.tab.path_content.content.len(); let group_size: usize; let owner_size: usize; - if self.status.display_metadata { + if self.status.settings.metadata { group_size = self.tab.path_content.group_column_width(); owner_size = self.tab.path_content.owner_column_width(); } else { @@ -222,7 +222,7 @@ impl<'a> WinMain<'a> { owner_size: usize, group_size: usize, ) -> Result<String> { - if self.status.display_metadata { + if self.status.settings.metadata { file.format(owner_size, group_size) } else { file.format_simple() @@ -250,7 +250,7 @@ impl<'a> WinMain<'a> { } fn draw_tree_content(&self, canvas: &mut dyn Canvas) -> Result<usize> { - let left_margin = if self.status.display_metadata { 1 } else { 3 }; + let left_margin = if self.status.settings.metadata { 1 } else { 3 }; let (_, height) = canvas.size()?; let (selected_index, content) = self.tab.tree.into_navigable_content(&self.tab.users); let (top, bottom) = calculate_top_bottom(selected_index, height); @@ -282,7 +282,7 @@ impl<'a> WinMain<'a> { let mut attr = colored_filename.color_effect.attr(); self.print_as_flagged(canvas, row, &colored_filename.path, &mut attr)?; - let col_metadata = if self.status.display_metadata { + let col_metadata = if self.status.settings.metadata { canvas.print_with_attr(row, left_margin, s_metadata, attr)? } else { 0 @@ -496,7 +496,7 @@ impl PreviewFirstLine { } fn _pick_previewed_fileinfo(status: &Status) -> Result<FileInfo> { - if status.dual_pane && status.preview_second { + if status.settings.dual && status.settings.preview { status.tabs[0].selected() } else { status.selected_non_mut().selected() @@ -540,7 +540,7 @@ impl WinMainSecondLine { fn new(status: &Status, tab: &Tab) -> Self { let (content, attr) = match tab.display_mode { DisplayMode::Normal | DisplayMode::Tree => { - if !status.display_metadata { + if !status.settings.metadata { if let Ok(file) = tab.selected() { Self::second_line_detailed(&file) } else { @@ -988,7 +988,7 @@ impl Display { self.term.clear()?; let (width, _) = self.term.term_size()?; - if status.dual_pane && width > MIN_WIDTH_FOR_DUAL_PANE { + if status.settings.dual && width > MIN_WIDTH_FOR_DUAL_PANE { self._draw_dual_pane(status)? } else { self._draw_single_pane(status)? |