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}; type IndexType = usize; pub fn main() { let args: Vec = 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.is_empty() { eprintln!("Usage: echo | fz --algo [skim|clangd] "); exit(1); } let matcher: Box = match algorithm { Some("skim") | Some("skim_v2") => Box::::default(), Some("clangd") => Box::::default(), _ => panic!("Algorithm not supported: {:?}", algorithm), }; let stdin = io::stdin(); for line in stdin.lock().lines().flatten() { 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 }