1 use {
2     super::Sort,
3     crate::{
4         cli::clap_args,
5         conf::Conf,
6         display::{Cols, DEFAULT_COLS},
7         errors::ConfError,
8         pattern::*,
9     },
10     clap::ArgMatches,
11     std::convert::TryFrom,
12 };
13 
14 /// Options defining how the tree should be build and|or displayed
15 #[derive(Debug, Clone)]
16 pub struct TreeOptions {
17     pub show_selection_mark: bool, // whether to have a triangle left of selected line
18     pub show_hidden: bool, // whether files whose name starts with a dot should be shown
19     pub only_folders: bool, // whether to hide normal files and links
20     pub show_counts: bool, // whether to show the number of files (> 1 only for dirs)
21     pub show_dates: bool,  // whether to show the last modified date
22     pub show_sizes: bool,  // whether to show sizes of files and dirs
23     pub show_git_file_info: bool,
24     pub show_device_id: bool,
25     pub show_root_fs: bool, // show information relative to the fs of the root
26     pub trim_root: bool,    // whether to cut out direct children of root
27     pub show_permissions: bool, // show classic rwx unix permissions (only on unix)
28     pub respect_git_ignore: bool, // hide files as requested by .gitignore ?
29     pub filter_by_git_status: bool, // only show files whose git status is not nul
30     pub pattern: InputPattern, // an optional filtering/scoring pattern
31     pub date_time_format: &'static str,
32     pub sort: Sort,
33     pub cols_order: Cols, // order of columns
34 }
35 
36 impl TreeOptions {
37     /// clone self but without the pattern (if any)
without_pattern(&self) -> Self38     pub fn without_pattern(&self) -> Self {
39         TreeOptions {
40             show_selection_mark: self.show_selection_mark,
41             show_hidden: self.show_hidden,
42             only_folders: self.only_folders,
43             show_counts: self.show_counts,
44             show_dates: self.show_dates,
45             show_sizes: self.show_sizes,
46             show_permissions: self.show_permissions,
47             respect_git_ignore: self.respect_git_ignore,
48             filter_by_git_status: self.filter_by_git_status,
49             show_git_file_info: self.show_git_file_info,
50             show_device_id: self.show_device_id,
51             show_root_fs: self.show_root_fs,
52             trim_root: self.trim_root,
53             pattern: InputPattern::none(),
54             date_time_format: self.date_time_format,
55             sort: self.sort,
56             cols_order: self.cols_order,
57         }
58     }
59     /// counts must be computed, either for sorting or just for display
needs_counts(&self) -> bool60     pub fn needs_counts(&self) -> bool {
61         self.show_counts || self.sort == Sort::Count
62     }
63     /// dates must be computed, either for sorting or just for display
needs_dates(&self) -> bool64     pub fn needs_dates(&self) -> bool {
65         self.show_dates || self.sort == Sort::Date
66     }
67     /// sizes must be computed, either for sorting or just for display
needs_sizes(&self) -> bool68     pub fn needs_sizes(&self) -> bool {
69         self.show_sizes || self.sort == Sort::Size
70     }
needs_sum(&self) -> bool71     pub fn needs_sum(&self) -> bool {
72         self.needs_counts() || self.needs_dates() || self.needs_sizes()
73     }
74     /// this method does not exist, you saw nothing
75     /// (at least don't call it other than with the config, once)
set_date_time_format(&mut self, format: String)76     pub fn set_date_time_format(&mut self, format: String) {
77         self.date_time_format = Box::leak(format.into_boxed_str());
78     }
79     /// change tree options according to configuration
apply_config(&mut self, config: &Conf) -> Result<(), ConfError>80     pub fn apply_config(&mut self, config: &Conf) -> Result<(), ConfError> {
81         if let Some(default_flags) = &config.default_flags {
82             let clap_app = clap_args::clap_app().setting(clap::AppSettings::NoBinaryName);
83             let flags_args = format!("-{}", default_flags);
84             let conf_matches = clap_app.get_matches_from(vec![&flags_args]);
85             self.apply_launch_args(&conf_matches);
86         }
87         if let Some(b) = &config.show_selection_mark {
88             self.show_selection_mark = *b;
89         }
90         if let Some(format) = &config.date_time_format {
91             self.set_date_time_format(format.clone());
92         }
93         self.cols_order = config
94             .cols_order
95             .as_ref()
96             .map(Cols::try_from)
97             .transpose()?
98             .unwrap_or(DEFAULT_COLS);
99         Ok(())
100     }
101     /// change tree options according to broot launch arguments
apply_launch_args(&mut self, cli_args: &ArgMatches<'_>)102     pub fn apply_launch_args(&mut self, cli_args: &ArgMatches<'_>) {
103         if cli_args.is_present("sizes") {
104             self.show_sizes = true;
105             self.show_root_fs = true;
106         } else if cli_args.is_present("no-sizes") {
107             self.show_sizes = false;
108         }
109         if cli_args.is_present("whale-spotting") {
110             self.show_hidden = true;
111             self.respect_git_ignore = false;
112             self.sort = Sort::Size;
113             self.show_sizes = true;
114             self.show_root_fs = true;
115         }
116         if cli_args.is_present("only-folders") {
117             self.only_folders = true;
118         } else if cli_args.is_present("no-only-folders") {
119             self.only_folders = false;
120         }
121         if cli_args.is_present("git-status") {
122             self.filter_by_git_status = true;
123             self.show_hidden = true;
124         }
125         if cli_args.is_present("hidden") {
126             self.show_hidden = true;
127         } else if cli_args.is_present("no-hidden") {
128             self.show_hidden = false;
129         }
130         if cli_args.is_present("dates") {
131             self.show_dates = true;
132         } else if cli_args.is_present("no-dates") {
133             self.show_dates = false;
134         }
135         if cli_args.is_present("permissions") {
136             self.show_permissions = true;
137         } else if cli_args.is_present("no-permissions") {
138             self.show_permissions = false;
139         }
140         if cli_args.is_present("show-root-fs") {
141             self.show_root_fs = true;
142         }
143         if cli_args.is_present("show-gitignored") {
144             self.respect_git_ignore = false;
145         } else if cli_args.is_present("no-show-gitignored") {
146             self.respect_git_ignore = true;
147         }
148         if cli_args.is_present("show-git-info") {
149             self.show_git_file_info = true;
150         } else if cli_args.is_present("no-show-git-info") {
151             self.show_git_file_info = false;
152         }
153         if cli_args.is_present("sort-by-count") {
154             self.sort = Sort::Count;
155             self.show_counts = true;
156         }
157         if cli_args.is_present("sort-by-date") {
158             self.sort = Sort::Date;
159             self.show_dates = true;
160         }
161         if cli_args.is_present("sort-by-size") {
162             self.sort = Sort::Size;
163             self.show_sizes = true;
164         }
165         if cli_args.is_present("no-sort") {
166             self.sort = Sort::None;
167         }
168         if cli_args.is_present("trim-root") {
169             self.trim_root = true;
170         } else if cli_args.is_present("no-trim-root") {
171             self.trim_root = false;
172         }
173     }
174 }
175 
176 impl Default for TreeOptions {
default() -> Self177     fn default() -> Self {
178         Self {
179             show_selection_mark: false,
180             show_hidden: false,
181             only_folders: false,
182             show_counts: false,
183             show_dates: false,
184             show_sizes: false,
185             show_git_file_info: false,
186             show_device_id: false,
187             show_root_fs: false,
188             trim_root: false,
189             show_permissions: false,
190             respect_git_ignore: true,
191             filter_by_git_status: false,
192             pattern: InputPattern::none(),
193             date_time_format: "%Y/%m/%d %R",
194             sort: Sort::None,
195             cols_order: DEFAULT_COLS,
196         }
197     }
198 }
199