|
1 | | -use anyhow::Result; |
| 1 | +use anyhow::{anyhow, Context, Result}; |
| 2 | +use bstr::BString; |
2 | 3 | use crosstermion::input::Key; |
3 | 4 | use dua::traverse::{Tree, TreeIndex}; |
4 | | -use globset::{Glob, GlobMatcher}; |
5 | 5 | use petgraph::Direction; |
6 | 6 | use std::borrow::Borrow; |
7 | | -use std::path::PathBuf; |
8 | 7 | use tui::backend::Backend; |
9 | 8 | use tui::prelude::Buffer; |
10 | 9 | use tui::{ |
@@ -112,7 +111,7 @@ impl GlobPane { |
112 | 111 | has_focus, |
113 | 112 | } = props.borrow(); |
114 | 113 |
|
115 | | - let title = "Glob search from top"; |
| 114 | + let title = "Git-Glob"; |
116 | 115 | let block = Block::default() |
117 | 116 | .title(title) |
118 | 117 | .border_style(*border_style) |
@@ -178,26 +177,40 @@ fn glob_search_neighbours( |
178 | 177 | results: &mut Vec<TreeIndex>, |
179 | 178 | tree: &Tree, |
180 | 179 | root_index: TreeIndex, |
181 | | - glob: &GlobMatcher, |
182 | | - path: &mut PathBuf, |
| 180 | + glob: &gix_glob::Pattern, |
| 181 | + path: &mut BString, |
183 | 182 | ) { |
184 | 183 | for node_index in tree.neighbors_directed(root_index, Direction::Outgoing) { |
185 | 184 | if let Some(node) = tree.node_weight(node_index) { |
186 | | - path.push(&node.name); |
187 | | - if glob.is_match(&path) { |
| 185 | + let previous_len = path.len(); |
| 186 | + let basename_start = if path.is_empty() { |
| 187 | + None |
| 188 | + } else { |
| 189 | + path.push(b'/'); |
| 190 | + Some(previous_len + 1) |
| 191 | + }; |
| 192 | + path.extend_from_slice(gix_path::into_bstr(&node.name).as_ref()); |
| 193 | + if glob.matches_repo_relative_path( |
| 194 | + path.as_ref(), |
| 195 | + basename_start, |
| 196 | + Some(node.is_dir), |
| 197 | + gix_glob::pattern::Case::Fold, |
| 198 | + gix_glob::wildmatch::Mode::NO_MATCH_SLASH_LITERAL, |
| 199 | + ) { |
188 | 200 | results.push(node_index); |
189 | 201 | } else { |
190 | 202 | glob_search_neighbours(results, tree, node_index, glob, path); |
191 | 203 | } |
192 | | - path.pop(); |
| 204 | + path.truncate(previous_len); |
193 | 205 | } |
194 | 206 | } |
195 | 207 | } |
196 | 208 |
|
197 | 209 | pub fn glob_search(tree: &Tree, root_index: TreeIndex, glob: &str) -> Result<Vec<TreeIndex>> { |
198 | | - let glob = Glob::new(glob)?.compile_matcher(); |
| 210 | + let glob = gix_glob::Pattern::from_bytes_without_negation(glob.as_bytes()) |
| 211 | + .with_context(|| anyhow!("Glob was empty or only whitespace"))?; |
199 | 212 | let mut results = Vec::new(); |
200 | | - let mut path = PathBuf::new(); |
| 213 | + let mut path = Default::default(); |
201 | 214 | glob_search_neighbours(&mut results, tree, root_index, &glob, &mut path); |
202 | 215 | Ok(results) |
203 | 216 | } |
0 commit comments