diff options
author | Canop <cano.petrole@gmail.com> | 2021-05-07 17:18:59 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2021-05-07 17:18:59 +0200 |
commit | ccf6da2d2ed5e30355e2c9e3fd445f6297c9493b (patch) | |
tree | 6ca4c5145224a8d6c0be6fe95adaa5b205c2dc62 /src | |
parent | 8593028c16d899b5b69dec45ac860d252d18af66 (diff) |
apply a different style to the subpath before the filename
This style is visible when searching on subpath
Diffstat (limited to 'src')
-rw-r--r-- | src/display/displayable_tree.rs | 40 | ||||
-rw-r--r-- | src/display/matched_string.rs | 28 | ||||
-rw-r--r-- | src/pattern/name_match.rs | 17 | ||||
-rw-r--r-- | src/pattern/pos.rs | 1 | ||||
-rw-r--r-- | src/skin/style_map.rs | 2 |
5 files changed, 75 insertions, 13 deletions
diff --git a/src/display/displayable_tree.rs b/src/display/displayable_tree.rs index 5834adc..ca8e9ab 100644 --- a/src/display/displayable_tree.rs +++ b/src/display/displayable_tree.rs @@ -285,19 +285,35 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { cw.queue_char(style, ' ')?; cw.queue_char(style, ' ')?; } - let label = if pattern_object.subpath { - &line.subpath + if pattern_object.subpath && line.unlisted == 0 { + let name_match = self.tree.options.pattern.pattern + .search_string(&line.subpath); + let mut path_ms = MatchedString::new( + name_match, + &line.subpath, + &style, + &char_match_style, + ); + let name_ms = path_ms.split_on_last('/'); + cond_bg!(parent_style, self, selected, self.skin.parent); + if name_ms.is_some() { + path_ms.base_style = &parent_style; + } + path_ms.queue_on(cw)?; + if let Some(name_ms) = name_ms { + name_ms.queue_on(cw)?; + } } else { - &line.name - }; - let name_match = self.tree.options.pattern.pattern.search_string(label); - let matched_string = MatchedString::new( - name_match, - label, - &style, - &char_match_style, - ); - matched_string.queue_on(cw)?; + let name_match = self.tree.options.pattern.pattern + .search_string(&line.name); + let matched_string = MatchedString::new( + name_match, + &line.name, + &style, + &char_match_style, + ); + matched_string.queue_on(cw)?; + } match &line.line_type { TreeLineType::Dir => { if line.unlisted > 0 { diff --git a/src/display/matched_string.rs b/src/display/matched_string.rs index 68b4dc9..45becfb 100644 --- a/src/display/matched_string.rs +++ b/src/display/matched_string.rs @@ -30,6 +30,34 @@ impl<'a, 'w> MatchedString<'a> { align: Alignment::Left, } } + /// If the string contains sep, then cut the tail of this matched + /// string and return it. + /// Note: a non none display_width currently prevents splitting + /// (i.e. it's not yet implemented and would involve compute width) + pub fn split_on_last(&mut self, sep: char) -> Option<Self> { + if self.display_width.is_some() { + // the proper algo would need measuring the left part I guess + None + } else { + self.string + .rfind(sep) + .map(|sep_idx| { + let right = &self.string[sep_idx+1..]; + self.string = &self.string[..sep_idx+1]; + let left_chars_count = self.string.chars().count(); + let right_name_match = self.name_match.as_mut() + .map(|nm| nm.cut_after(left_chars_count)); + MatchedString { + name_match: right_name_match, + string: right, + base_style: self.base_style, + match_style: self.match_style, + display_width: None, + align: self.align, + } + }) + } + } pub fn fill(&mut self, width: usize, align: Alignment) { self.display_width = Some(width); self.align = align; diff --git a/src/pattern/name_match.rs b/src/pattern/name_match.rs index a4bffcf..cdbeed3 100644 --- a/src/pattern/name_match.rs +++ b/src/pattern/name_match.rs @@ -1,5 +1,6 @@ use { super::Pos, + smallvec::SmallVec, }; /// A NameMatch is a positive result of pattern matching inside @@ -11,6 +12,7 @@ pub struct NameMatch { } impl NameMatch { + /// wraps any group of matching characters with match_start and match_end pub fn wrap(&self, name: &str, match_start: &str, match_end: &str) -> String { let mut result = String::new(); let mut index_in_pos = 0; @@ -33,5 +35,20 @@ impl NameMatch { } result } + // cut the name match in two parts by recomputing the pos + // arrays + pub fn cut_after(&mut self, chars_count: usize) -> Self { + let mut tail = Self { + score: self.score, + pos: SmallVec::new(), + }; + let idx = self.pos.iter().position(|&p| p >= chars_count); + if let Some(idx) = idx { + for p in self.pos.drain(idx..) { + tail.pos.push(p - chars_count); + } + } + tail + } } diff --git a/src/pattern/pos.rs b/src/pattern/pos.rs index cee14a5..11bdb3d 100644 --- a/src/pattern/pos.rs +++ b/src/pattern/pos.rs @@ -5,3 +5,4 @@ use { /// a vector of indexes of the matching characters (not bytes) pub type Pos = SmallVec<[usize; 8]>; + diff --git a/src/skin/style_map.rs b/src/skin/style_map.rs index 1669364..f1fbdd1 100644 --- a/src/skin/style_map.rs +++ b/src/skin/style_map.rs @@ -139,7 +139,7 @@ impl StyleMap { StyleMap! { default: gray(22), gray(2), [] / gray(20), gray(2), [] tree: gray(8), None, [] / gray(4), None, [] - parent: gray(17), None, [] / gray(13), None, [] + parent: gray(18), None, [] / gray(13), None, [] file: gray(22), None, [] / gray(15), None, [] directory: ansi(110), None, [Bold] / ansi(110), None, [] exe: Some(Cyan), None, [] |