summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2020-12-14 08:42:58 +0100
committerCanop <cano.petrole@gmail.com>2020-12-14 08:42:58 +0100
commit1480427fefc1f96c7b6c8aace861024d7da753a3 (patch)
treecf3320957e946321515f356b8a4a0c37feec651b /src
parent2c06c7ca0a580618d932325e15d8d40e7640f24d (diff)
improve determination of whether a space is needed left of the tree
Cols order setting has been moved from context to tree options which is both more logical and simpler to deal with.
Diffstat (limited to 'src')
-rw-r--r--src/app/context.rs11
-rw-r--r--src/browser/browser_state.rs2
-rw-r--r--src/cli.rs12
-rw-r--r--src/display/col.rs43
-rw-r--r--src/display/displayable_tree.rs28
-rw-r--r--src/launchable.rs8
-rw-r--r--src/print.rs8
-rw-r--r--src/task_sync.rs3
-rw-r--r--src/tree/tree.rs10
-rw-r--r--src/tree/tree_options.rs38
10 files changed, 103 insertions, 60 deletions
diff --git a/src/app/context.rs b/src/app/context.rs
index 67e2a2e..ac4772d 100644
--- a/src/app/context.rs
+++ b/src/app/context.rs
@@ -3,7 +3,6 @@ use {
crate::{
cli::AppLaunchArgs,
conf::Conf,
- display::*,
errors::ConfError,
icon::*,
pattern::SearchModeMap,
@@ -38,9 +37,6 @@ pub struct AppContext {
/// the map between search prefixes and the search mode to apply
pub search_modes: SearchModeMap,
- /// order of columns in tree display
- pub cols: Cols,
-
/// whether to show a triangle left to selected lines
pub show_selection_mark: bool,
@@ -87,12 +83,6 @@ impl AppContext {
.map(|map| map.try_into())
.transpose()?
.unwrap_or_default();
- let cols = config
- .cols_order
- .as_ref()
- .map(Cols::try_from)
- .transpose()?
- .unwrap_or(DEFAULT_COLS);
let ext_colors = ExtColorMap::try_from(&config.ext_colors)?;
Ok(Self {
config_paths,
@@ -100,7 +90,6 @@ impl AppContext {
verb_store,
special_paths,
search_modes,
- cols,
show_selection_mark: config.show_selection_mark.unwrap_or(false),
ext_colors,
syntax_theme: config.syntax_theme.clone(),
diff --git a/src/browser/browser_state.rs b/src/browser/browser_state.rs
index 218ffd8..71efe55 100644
--- a/src/browser/browser_state.rs
+++ b/src/browser/browser_state.rs
@@ -523,8 +523,6 @@ impl AppState for BrowserState {
let dp = DisplayableTree {
tree: &self.displayed_tree(),
skin: &panel_skin.styles,
- cols: &con.cols,
- show_selection_mark: con.show_selection_mark,
ext_colors: &con.ext_colors,
area,
in_app: true,
diff --git a/src/cli.rs b/src/cli.rs
index a66e4a7..23b6e33 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -177,16 +177,8 @@ pub fn run() -> Result<Option<Launchable>, ProgramError> {
// found in the config file(s) (if any) then overriden
// by the cli args
let mut tree_options = TreeOptions::default();
- if let Some(default_flags) = &config.default_flags {
- let clap_app = crate::clap::clap_app().setting(clap::AppSettings::NoBinaryName);
- let flags_args = format!("-{}", default_flags);
- let conf_matches = clap_app.get_matches_from(vec![&flags_args]);
- tree_options.apply(&conf_matches);
- }
- tree_options.apply(&cli_matches);
- if let Some(format) = &config.date_time_format {
- tree_options.set_date_time_format(format.clone());
- }
+ tree_options.apply_config(&config)?;
+ tree_options.apply_launch_args(&cli_matches);
// verb store is completed from the config file(s)
let mut verb_store = VerbStore::default();
diff --git a/src/display/col.rs b/src/display/col.rs
index 04edb57..270a2f2 100644
--- a/src/display/col.rs
+++ b/src/display/col.rs
@@ -1,5 +1,8 @@
use {
- crate::errors::ConfError,
+ crate::{
+ errors::ConfError,
+ tree::Tree,
+ },
serde::Deserialize,
std::{
convert::TryFrom,
@@ -38,7 +41,7 @@ pub enum Col {
Name,
}
-pub type Cols = [Col;COLS_COUNT];
+pub type Cols = [Col; COLS_COUNT];
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
@@ -67,8 +70,8 @@ impl FromStr for Col {
let s = s.to_lowercase();
match s.as_ref() {
"m" | "mark" => Ok(Self::Mark),
- "g" | "git" => Ok(Self::Git),
- "b" | "branch" => Ok(Self::Branch),
+ "g" | "git" => Ok(Self::Git),
+ "b" | "branch" => Ok(Self::Branch),
"p" | "permission" => Ok(Self::Permission),
"d" | "date" => Ok(Self::Date),
"s" | "size" => Ok(Self::Size),
@@ -76,20 +79,48 @@ impl FromStr for Col {
"n" | "name" => Ok(Self::Name),
_ => Err(ConfError::InvalidCols {
details: format!("column not recognized : {}", s),
- })
+ }),
}
}
}
impl Col {
+ /// return the index of the column among the complete Cols ordered list
pub fn index_in(self, cols: &Cols) -> Option<usize> {
for (idx, col) in cols.iter().enumerate() {
- if *col==self {
+ if *col == self {
return Some(idx);
}
}
None
}
+ /// tell whether this column should have an empty character left
+ pub fn needs_left_margin(self) -> bool {
+ match self {
+ Col::Mark => false,
+ Col::Git => false,
+ Col::Size => true,
+ Col::Date => true,
+ Col::Permission => true,
+ Col::Count => false,
+ Col::Branch => false,
+ Col::Name => false,
+ }
+ }
+ pub fn is_visible(self, tree: &Tree) -> bool {
+ let tree_options = &tree.options;
+ match self {
+ Col::Mark => tree_options.show_selection_mark,
+ Col::Git => tree.git_status.is_some(),
+ Col::Size => tree_options.show_sizes,
+ Col::Date => tree_options.show_dates,
+ Col::Permission => tree_options.show_permissions,
+ Col::Count => tree_options.show_counts,
+ Col::Branch => true,
+ Col::Name => true,
+ }
+
+ }
}
impl TryFrom<&ColsConf> for Cols {
diff --git a/src/display/displayable_tree.rs b/src/display/displayable_tree.rs
index fcb1a3e..09c54d9 100644
--- a/src/display/displayable_tree.rs
+++ b/src/display/displayable_tree.rs
@@ -1,7 +1,6 @@
use {
super::{
Col,
- Cols,
CropWriter,
GitStatusDisplay,
SPACE_FILLING, BRANCH_FILLING,
@@ -40,8 +39,6 @@ pub struct DisplayableTree<'s, 't> {
pub skin: &'s StyleMap,
pub area: termimad::Area,
pub in_app: bool, // if true we show the selection and scrollbar
- pub cols: &'s Cols,
- pub show_selection_mark: bool,
pub ext_colors: &'s ExtColorMap,
}
@@ -50,15 +47,12 @@ impl<'s, 't> DisplayableTree<'s, 't> {
pub fn out_of_app(
tree: &'t Tree,
skin: &'s StyleMap,
- cols: &'s Cols,
ext_colors: &'s ExtColorMap,
width: u16,
) -> DisplayableTree<'s, 't> {
DisplayableTree {
tree,
skin,
- cols,
- show_selection_mark: false,
ext_colors,
area: termimad::Area {
left: 0,
@@ -402,6 +396,8 @@ impl<'s, 't> DisplayableTree<'s, 't> {
self.write_root_line(&mut cw, self.in_app && tree.selection == 0)?;
f.queue(SetBackgroundColor(Color::Reset))?;
+ let visible_cols = tree.visible_cols();
+
// we compute the length of the dates, depending on the format
let date_len = if tree.options.show_dates {
let date_time: DateTime<Local> = Local::now();
@@ -423,7 +419,6 @@ impl<'s, 't> DisplayableTree<'s, 't> {
let mut selected = false;
let mut cw = CropWriter::new(f, self.area.width as usize);
let cw = &mut cw;
- let add_left_margin = self.cols[0] != Col::Mark || !self.show_selection_mark;
if line_index < tree.lines.len() {
let line = &tree.lines[line_index];
selected = self.in_app && line_index == tree.selection;
@@ -434,17 +429,17 @@ impl<'s, 't> DisplayableTree<'s, 't> {
} else {
&self.skin.default
};
- if add_left_margin {
+ if visible_cols[0].needs_left_margin() {
cw.queue_char(space_style, ' ')?;
}
- for col in self.cols {
+ for col in &visible_cols {
let void_len = match col {
- Col::Mark if self.show_selection_mark => {
+ Col::Mark => {
self.write_line_selection_mark(cw, &label_style, selected)?
}
- Col::Git if !tree.git_status.is_none() => {
+ Col::Git => {
self.write_line_git_status(cw, line, selected)?
}
@@ -454,11 +449,11 @@ impl<'s, 't> DisplayableTree<'s, 't> {
}
#[cfg(not(any(target_family = "windows", target_os = "android")))]
- Col::Permission if tree.options.show_permissions => {
+ Col::Permission => {
perm_writer.write_permissions(cw, line, selected)?
}
- Col::Date if tree.options.show_dates => {
+ Col::Date => {
if let Some(seconds) = line.sum.and_then(|sum| sum.to_valid_seconds()) {
self.write_date(cw, seconds, selected)?
} else {
@@ -466,7 +461,7 @@ impl<'s, 't> DisplayableTree<'s, 't> {
}
}
- Col::Size if tree.options.show_sizes => {
+ Col::Size => {
if tree.options.sort.is_some() {
// as soon as there's only one level displayed we can show the size bars
self.write_line_size_with_bar(cw, line, &label_style, total_size, selected)?
@@ -475,7 +470,7 @@ impl<'s, 't> DisplayableTree<'s, 't> {
}
}
- Col::Count if tree.options.show_counts => {
+ Col::Count => {
self.write_line_count(cw, line, selected)?
}
@@ -484,9 +479,6 @@ impl<'s, 't> DisplayableTree<'s, 't> {
self.write_line_label(cw, line, &label_style, pattern_object, selected)?
}
- _ => {
- 0 // we don't write the intercol
- }
};
// void: intercol & replacing missing cells
if in_branch && void_len > 2 {
diff --git a/src/launchable.rs b/src/launchable.rs
index 8794d82..b7af6c1 100644
--- a/src/launchable.rs
+++ b/src/launchable.rs
@@ -1,7 +1,6 @@
use {
crate::{
display::{
- Cols,
DisplayableTree,
Screen,
W,
@@ -41,7 +40,6 @@ pub enum Launchable {
TreePrinter {
tree: Box<Tree>,
skin: Box<StyleMap>,
- cols: Cols,
ext_colors: ExtColorMap,
width: u16,
},
@@ -86,13 +84,11 @@ impl Launchable {
tree: &Tree,
screen: Screen,
style_map: StyleMap,
- cols: Cols,
ext_colors: ExtColorMap,
) -> Launchable {
Launchable::TreePrinter {
tree: Box::new(tree.clone()),
skin: Box::new(style_map),
- cols,
ext_colors,
width: screen.width,
}
@@ -119,8 +115,8 @@ impl Launchable {
println!("{}", to_print);
Ok(())
}
- Launchable::TreePrinter { tree, skin, cols, ext_colors, width } => {
- let dp = DisplayableTree::out_of_app(&tree, &skin, &cols, &ext_colors, *width);
+ Launchable::TreePrinter { tree, skin, ext_colors, width } => {
+ let dp = DisplayableTree::out_of_app(&tree, &skin, &ext_colors, *width);
dp.write_on(&mut std::io::stdout())
}
Launchable::Program { working_dir, exe, args } => {
diff --git a/src/print.rs b/src/print.rs
index 0409e7d..85e04b4 100644
--- a/src/print.rs
+++ b/src/print.rs
@@ -3,7 +3,7 @@
use {
crate::{
app::{AppContext, AppStateCmdResult},
- display::{Cols, DisplayableTree, Screen},
+ display::{DisplayableTree, Screen},
errors::ProgramError,
launchable::Launchable,
skin::{ExtColorMap, PanelSkin, StyleMap},
@@ -56,11 +56,10 @@ fn print_tree_to_file(
tree: &Tree,
screen: Screen,
file_path: &str,
- cols: &Cols,
ext_colors: &ExtColorMap,
) -> Result<AppStateCmdResult, ProgramError> {
let no_style_skin = StyleMap::no_term();
- let dp = DisplayableTree::out_of_app(tree, &no_style_skin, cols, ext_colors, screen.width);
+ let dp = DisplayableTree::out_of_app(tree, &no_style_skin, ext_colors, screen.width);
let mut f = OpenOptions::new()
.create(true)
.append(true)
@@ -77,7 +76,7 @@ pub fn print_tree(
) -> Result<AppStateCmdResult, ProgramError> {
if let Some(ref output_path) = con.launch_args.file_export_path {
// an output path was provided, we write to it
- print_tree_to_file(tree, screen, output_path, &con.cols, &con.ext_colors)
+ print_tree_to_file(tree, screen, output_path, &con.ext_colors)
} else {
// no output path provided. We write on stdout, but we must
// do it after app closing to have the normal terminal
@@ -90,7 +89,6 @@ pub fn print_tree(
tree,
screen,
styles,
- con.cols,
con.ext_colors.clone(),
)))
}
diff --git a/src/task_sync.rs b/src/task_sync.rs
index 09a0900..f270e8a 100644
--- a/src/task_sync.rs
+++ b/src/task_sync.rs
@@ -22,6 +22,9 @@ impl<V> ComputationResult<V> {
pub fn is_not_computed(&self) -> bool {
matches!(&self, Self::NotComputed)
}
+ pub fn is_some(&self) -> bool {
+ !matches!(&self, Self::None)
+ }
pub fn is_none(&self) -> bool {
matches!(&self, Self::None)
}
diff --git a/src/tree/tree.rs b/src/tree/tree.rs
index 97144fc..4599296 100644
--- a/src/tree/tree.rs
+++ b/src/tree/tree.rs
@@ -2,6 +2,7 @@ use {
super::*,
crate::{
app::AppContext,
+ display::Col,
errors,
file_sum::FileSum,
git::TreeGitStatus,
@@ -436,4 +437,13 @@ impl Tree {
sum
}
}
+ /// compute the ordered list of columns that should be displayed
+ /// for current tree state and options
+ pub fn visible_cols(&self) -> Vec<Col> {
+ self.options.cols_order
+ .iter()
+ .filter(|col| col.is_visible(&self))
+ .cloned()
+ .collect()
+ }
}
diff --git a/src/tree/tree_options.rs b/src/tree/tree_options.rs
index 16f75a0..862b8f9 100644
--- a/src/tree/tree_options.rs
+++ b/src/tree/tree_options.rs
@@ -1,12 +1,19 @@
use {
super::Sort,
- crate::pattern::*,
+ crate::{
+ conf::Conf,
+ display::{Cols, DEFAULT_COLS},
+ errors::ConfError,
+ pattern::*,
+ },
clap::ArgMatches,
+ std::convert::TryFrom,
};
/// Options defining how the tree should be build and|or displayed
#[derive(Debug, Clone)]
pub struct TreeOptions {
+ pub show_selection_mark: bool, // whether to have a triangle left of selected line
pub show_hidden: bool, // whether files whose name starts with a dot should be shown
pub only_folders: bool, // whether to hide normal files and links
pub show_counts: bool, // whether to show the number of files (> 1 only for dirs)
@@ -21,12 +28,14 @@ pub struct TreeOptions {
pub pattern: InputPattern, // an optional filtering/scoring pattern
pub date_time_format: &'static str,
pub sort: Sort,
+ pub cols_order: Cols, // order of columns
}
impl TreeOptions {
/// clone self but without the pattern (if any)
pub fn without_pattern(&self) -> Self {
TreeOptions {
+ show_selection_mark: self.show_selection_mark,
show_hidden: self.show_hidden,
only_folders: self.only_folders,
show_counts: self.show_counts,
@@ -41,6 +50,7 @@ impl TreeOptions {
pattern: InputPattern::none(),
date_time_format: self.date_time_format,
sort: self.sort,
+ cols_order: self.cols_order,
}
}
/// counts must be computed, either for sorting or just for display
@@ -63,8 +73,30 @@ impl TreeOptions {
pub fn set_date_time_format(&mut self, format: String) {
self.date_time_format = Box::leak(format.into_boxed_str());
}
+ /// change tree options according to configuration
+ pub fn apply_config(&mut self, config: &Conf) -> Result<(), ConfError> {
+ if let Some(default_flags) = &config.default_flags {
+ let clap_app = crate::clap::clap_app().setting(clap::AppSettings::NoBinaryName);
+ let flags_args = format!("-{}", default_flags);
+ let conf_matches = clap_app.get_matches_from(vec![&flags_args]);
+ self.apply_launch_args(&conf_matches);
+ }
+ if let Some(b) = &config.show_selection_mark {
+ self.show_selection_mark = *b;
+ }
+ if let Some(format) = &config.date_time_format {
+ self.set_date_time_format(format.clone());
+ }
+ self.cols_order = config
+ .cols_order
+ .as_ref()
+ .map(Cols::try_from)
+ .transpose()?
+ .unwrap_or(DEFAULT_COLS);
+ Ok(())
+ }
/// change tree options according to broot launch arguments
- pub fn apply(&mut self, cli_args: &ArgMatches<'_>) {
+ pub fn apply_launch_args(&mut self, cli_args: &ArgMatches<'_>) {
if cli_args.is_present("sizes") {
self.show_sizes = true;
self.show_root_fs = true;
@@ -141,6 +173,7 @@ impl TreeOptions {
impl Default for TreeOptions {
fn default() -> Self {
Self {
+ show_selection_mark: false,
show_hidden: false,
only_folders: false,
show_counts: false,
@@ -155,6 +188,7 @@ impl Default for TreeOptions {
pattern: InputPattern::none(),
date_time_format: "%Y/%m/%d %R",
sort: Sort::None,
+ cols_order: DEFAULT_COLS,
}
}
}