Struct broot::git::LineStatusComputer
source · pub struct LineStatusComputer { /* private fields */ }
Expand description
As a git repo can’t tell whether a path has a status, this computer looks at all the statuses of the repo and build a map path->status which can then be efficiently queried
Implementations§
source§impl LineStatusComputer
impl LineStatusComputer
pub fn from(repo: Repository) -> Option<Self>
sourcepub fn line_status(&self, path: &Path) -> Option<LineGitStatus>
pub fn line_status(&self, path: &Path) -> Option<LineGitStatus>
Examples found in repository?
src/tree_build/builder.rs (line 453)
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
fn take_as_tree(mut self, out_blines: &[BId]) -> Tree {
let mut lines: Vec<TreeLine> = Vec::new();
for id in out_blines.iter() {
if self.blines[*id].has_match {
// we need to count the children, so we load them
if self.blines[*id].can_enter() && self.blines[*id].children.is_none() {
self.load_children(*id);
}
if let Ok(tree_line) = self.blines[*id].to_tree_line(*id, self.con) {
lines.push(tree_line);
} else {
// I guess the file went missing during tree computation
warn!(
"Error while builind treeline for {:?}",
self.blines[*id].path,
);
}
}
}
let mut tree = Tree {
lines: lines.into_boxed_slice(),
selection: 0,
options: self.options.clone(),
scroll: 0,
total_search: self.total_search,
git_status: ComputationResult::None,
build_report: self.report,
};
tree.after_lines_changed();
if let Some(computer) = self.line_status_computer {
// tree git status is slow to compute, we just mark it should be
// done (later on)
tree.git_status = ComputationResult::NotComputed;
// it would make no sense to keep only files having a git status and
// not display that type
for mut line in tree.lines.iter_mut() {
line.git_status = computer.line_status(&line.path);
}
}
tree
}
sourcepub fn is_interesting(&self, path: &Path) -> bool
pub fn is_interesting(&self, path: &Path) -> bool
Examples found in repository?
src/tree_build/builder.rs (line 166)
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
fn make_line(
&mut self,
parent_id: BId,
e: &fs::DirEntry,
depth: u16,
) -> Option<BLine> {
let name = e.file_name();
if name.is_empty() {
self.report.error_count += 1;
return None;
}
if !self.options.show_hidden && name.as_bytes()[0] == b'.' {
self.report.hidden_count += 1;
return None;
}
let name = name.to_string_lossy();
let mut has_match = true;
let mut score = 10000 - i32::from(depth); // we dope less deep entries
let path = e.path();
let file_type = match e.file_type() {
Ok(ft) => ft,
Err(_) => {
self.report.error_count += 1;
return None;
}
};
let parent_subpath = &self.blines[parent_id].subpath;
let subpath = if !parent_subpath.is_empty() {
format!("{}/{}", parent_subpath, &name)
} else {
name.to_string()
};
let candidate = Candidate {
name: &name,
subpath: &subpath,
path: &path,
regular_file: file_type.is_file(),
};
let direct_match = if let Some(pattern_score) = self.options.pattern.pattern.score_of(candidate) {
// we dope direct matches to compensate for depth doping of parent folders
score += pattern_score + 10;
true
} else {
has_match = false;
false
};
let name = name.to_string();
if has_match && self.options.filter_by_git_status {
if let Some(line_status_computer) = &self.line_status_computer {
if !line_status_computer.is_interesting(&path) {
has_match = false;
}
}
}
if file_type.is_file() {
if !has_match {
return None;
}
if self.options.only_folders {
return None;
}
}
let special_handling = self.con.special_paths.find(&path);
if special_handling == SpecialHandling::Hide {
return None;
}
if self.options.respect_git_ignore {
let parent_chain = &self.blines[parent_id].git_ignore_chain;
if !self
.git_ignorer
.accepts(parent_chain, &path, &name, file_type.is_dir())
{
return None;
}
};
Some(BLine {
parent_id: Some(parent_id),
path,
depth,
subpath,
name,
file_type,
children: None,
next_child_idx: 0,
has_error: false,
has_match,
direct_match,
score,
nb_kept_children: 0,
git_ignore_chain: GitIgnoreChain::default(),
special_handling,
})
}