summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,
}
}
}