mirror of https://github.com/sharkdp/fd.git
parent
2d1d24c38c
commit
e06189e654
70
src/main.rs
70
src/main.rs
|
@ -17,6 +17,7 @@ use std::ops::Deref;
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::{Path, Component};
|
use std::path::{Path, Component};
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use clap::{App, AppSettings, Arg};
|
use clap::{App, AppSettings, Arg};
|
||||||
use atty::Stream;
|
use atty::Stream;
|
||||||
|
@ -93,6 +94,9 @@ fn print_entry(base: &Path, entry: &Path, config: &FdOptions) {
|
||||||
#[cfg(not(target_family = "unix"))]
|
#[cfg(not(target_family = "unix"))]
|
||||||
let is_executable = |p: &std::path::PathBuf| {false};
|
let is_executable = |p: &std::path::PathBuf| {false};
|
||||||
|
|
||||||
|
let stdout = std::io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
|
||||||
if let Some(ref ls_colors) = config.ls_colors {
|
if let Some(ref ls_colors) = config.ls_colors {
|
||||||
let default_style = ansi_term::Style::default();
|
let default_style = ansi_term::Style::default();
|
||||||
|
|
||||||
|
@ -139,17 +143,17 @@ fn print_entry(base: &Path, entry: &Path, config: &FdOptions) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
print!("{}", style.paint(comp_str));
|
write!(handle, "{}", style.paint(comp_str));
|
||||||
|
|
||||||
if component_path.is_dir() && component_path != path_full {
|
if component_path.is_dir() && component_path != path_full {
|
||||||
let sep = std::path::MAIN_SEPARATOR.to_string();
|
let sep = std::path::MAIN_SEPARATOR.to_string();
|
||||||
print!("{}", style.paint(sep));
|
write!(handle, "{}", style.paint(sep));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.null_separator {
|
if config.null_separator {
|
||||||
print!("{}", '\0');
|
writeln!(handle, "{}", '\0');
|
||||||
} else {
|
} else {
|
||||||
println!();
|
writeln!(handle);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Uncolorized output
|
// Uncolorized output
|
||||||
|
@ -157,7 +161,7 @@ fn print_entry(base: &Path, entry: &Path, config: &FdOptions) {
|
||||||
let prefix = if config.path_display == PathDisplay::Absolute { ROOT_DIR } else { "" };
|
let prefix = if config.path_display == PathDisplay::Absolute { ROOT_DIR } else { "" };
|
||||||
let separator = if config.null_separator { "\0" } else { "\n" };
|
let separator = if config.null_separator { "\0" } else { "\n" };
|
||||||
|
|
||||||
let r = write!(&mut std::io::stdout(), "{}{}{}", prefix, path_str, separator);
|
let r = writeln!(&mut std::io::stdout(), "{}{}{}", prefix, path_str, separator);
|
||||||
|
|
||||||
if r.is_err() {
|
if r.is_err() {
|
||||||
// Probably a broken pipe. Exit gracefully.
|
// Probably a broken pipe. Exit gracefully.
|
||||||
|
@ -167,7 +171,7 @@ fn print_entry(base: &Path, entry: &Path, config: &FdOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively scan the given search path and search for files / pathnames matching the pattern.
|
/// Recursively scan the given search path and search for files / pathnames matching the pattern.
|
||||||
fn scan(root: &Path, pattern: &Regex, base: &Path, config: &FdOptions) {
|
fn scan(root: &Path, pattern: Arc<Regex>, base: &Path, config: Arc<FdOptions>) {
|
||||||
let walker = WalkBuilder::new(root)
|
let walker = WalkBuilder::new(root)
|
||||||
.hidden(config.ignore_hidden)
|
.hidden(config.ignore_hidden)
|
||||||
.ignore(config.read_ignore)
|
.ignore(config.read_ignore)
|
||||||
|
@ -177,31 +181,41 @@ fn scan(root: &Path, pattern: &Regex, base: &Path, config: &FdOptions) {
|
||||||
.git_exclude(config.read_ignore)
|
.git_exclude(config.read_ignore)
|
||||||
.follow_links(config.follow_links)
|
.follow_links(config.follow_links)
|
||||||
.max_depth(config.max_depth)
|
.max_depth(config.max_depth)
|
||||||
.build()
|
.build_parallel();
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
.filter(|e| e.path() != root);
|
|
||||||
|
|
||||||
for entry in walker {
|
walker.run(|| {
|
||||||
let path_rel_buf = match fshelper::path_relative_from(entry.path(), base) {
|
let base = base.to_owned();
|
||||||
Some(p) => p,
|
let config = config.clone();
|
||||||
None => error("Error: could not get relative path for directory entry.")
|
let pattern = pattern.clone();
|
||||||
};
|
|
||||||
let path_rel = path_rel_buf.as_path();
|
|
||||||
|
|
||||||
let search_str_o =
|
Box::new(move |entry_o| {
|
||||||
if config.search_full_path {
|
let entry = match entry_o {
|
||||||
Some(path_rel.to_string_lossy())
|
Ok(e) => e,
|
||||||
} else {
|
Err(_) => return ignore::WalkState::Continue
|
||||||
path_rel.file_name()
|
|
||||||
.map(|f| f.to_string_lossy())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(search_str) = search_str_o {
|
let path_rel_buf = match fshelper::path_relative_from(entry.path(), &*base) {
|
||||||
pattern.find(&*search_str)
|
Some(p) => p,
|
||||||
.map(|_| print_entry(base, path_rel, config));
|
None => error("Error: could not get relative path for directory entry.")
|
||||||
}
|
};
|
||||||
}
|
let path_rel = path_rel_buf.as_path();
|
||||||
|
|
||||||
|
let search_str_o =
|
||||||
|
if config.search_full_path {
|
||||||
|
Some(path_rel.to_string_lossy())
|
||||||
|
} else {
|
||||||
|
path_rel.file_name()
|
||||||
|
.map(|f| f.to_string_lossy())
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(search_str) = search_str_o {
|
||||||
|
pattern.find(&*search_str)
|
||||||
|
.map(|_| print_entry(&base, path_rel, &config));
|
||||||
|
}
|
||||||
|
|
||||||
|
ignore::WalkState::Continue
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print error message to stderr and exit with status `1`.
|
/// Print error message to stderr and exit with status `1`.
|
||||||
|
@ -338,7 +352,7 @@ fn main() {
|
||||||
match RegexBuilder::new(pattern)
|
match RegexBuilder::new(pattern)
|
||||||
.case_insensitive(!config.case_sensitive)
|
.case_insensitive(!config.case_sensitive)
|
||||||
.build() {
|
.build() {
|
||||||
Ok(re) => scan(root_dir, &re, base, &config),
|
Ok(re) => scan(root_dir, Arc::new(re), base, Arc::new(config)),
|
||||||
Err(err) => error(err.description())
|
Err(err) => error(err.description())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue