1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
use fuzzy_matcher::clangd::ClangdMatcher;
use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;
use std::env;
use std::io::{self, BufRead};
use std::process::exit;
use termion::style::{Invert, Reset};
#[cfg(not(feature = "compact"))]
type IndexType = usize;
#[cfg(feature = "compact")]
type IndexType = u32;
pub fn main() {
let args: Vec<String> = env::args().collect();
// arg parsing (manually)
let mut arg_iter = args.iter().skip(1);
let mut pattern = "".to_string();
let mut algorithm = Some("skim");
while let Some(arg) = arg_iter.next() {
if arg == "--algo" {
algorithm = arg_iter.next().map(String::as_ref);
} else {
pattern = arg.to_string();
}
}
if &pattern == "" {
eprintln!("Usage: echo <piped_input> | fz --algo [skim|clangd] <pattern>");
exit(1);
}
let matcher: Box<dyn FuzzyMatcher> = match algorithm {
Some("skim") | Some("skim_v2") => Box::new(SkimMatcherV2::default()),
Some("clangd") => Box::new(ClangdMatcher::default()),
_ => panic!("Algorithm not supported: {:?}", algorithm),
};
let stdin = io::stdin();
for line in stdin.lock().lines() {
if let Ok(line) = line {
if let Some((score, indices)) = matcher.fuzzy_indices(&line, &pattern) {
println!("{:8}: {}", score, wrap_matches(&line, &indices));
}
}
}
}
fn wrap_matches(line: &str, indices: &[IndexType]) -> String {
let mut ret = String::new();
let mut peekable = indices.iter().peekable();
for (idx, ch) in line.chars().enumerate() {
let next_id = **peekable.peek().unwrap_or(&&(line.len() as IndexType));
if next_id == (idx as IndexType) {
ret.push_str(format!("{}{}{}", Invert, ch, Reset).as_str());
peekable.next();
} else {
ret.push(ch);
}
}
ret
}
|