use std::iter::repeat; use std::path::Path; use Default::default; use dsb::Cell; use dsb::cell::Style; use crate::FG; use crate::menu::{back, filter, next, score}; use crate::text::{TextArea, col, color_}; const COMMANDS: [(&str, &str); 3] = [ ("w", "Write / Save"), ("q", "Quit"), ("exit-vim-mode", "Go back to default editting mode"), ]; #[derive(Debug, Default)] pub struct Commands { pub tedit: TextArea, pub selection: usize, pub vo: usize, } const N: usize = 30; impl Commands { fn f(&self) -> String { self.tedit.rope.to_string() } pub fn next(&mut self) { let n = filter_c(self, &self.f()).count(); // coz its bottom up back::(n, &mut self.selection, &mut self.vo); } pub fn sel(&self) -> &str { let f = self.f(); score_c(filter_c(self, &f), &f)[self.selection].1 } pub fn back(&mut self) { let n = filter_c(self, &self.f()).count(); next::(n, &mut self.selection, &mut self.vo); } pub fn cells(&self, c: usize, ws: &Path) -> Vec { let f = self.f(); let mut out = vec![]; let v = score_c(filter_c(self, &f), &f); let vlen = v.len(); let i = v.into_iter().zip(0..vlen).skip(self.vo).take(N).rev(); // let Some((s, x)) = i.next() else { // return vec![]; // }; // let mut q = Dq::<_, 13>::new((s, x)); // for (s, x) in i { // if q.first().0 <= s { // q.push_front((s, x)); // } // } // fuzzy_aho_corasick::FuzzyAhoCorasickBuilder::new() // .fuzzy( // FuzzyLimits::new() // .insertions(20) // .deletions(2) // .edits(4) // .substitutions(5) // .swaps(3), // .penalties(FuzzyPenalties { // ) // insertion: 0.0, // deletion: 1.0, // substitution: 0.5, // swap: 0.5, // }) // .build( // y.iter().map(|x| x.filter_text.as_deref().unwrap_or(&x.label)), // ) // .search(filter, 0.25) // .into_iter() // .map(|x| &y[x.pattern_index]) // // .take(13); // // for x in y // // .iter() // // .filter(|x| { // // x.filter_text // // .as_deref() // // .unwrap_or(&x.label) // // .starts_with(filter) // // }) // .take(13) i.for_each(|((_, x, indices), i)| { r(x, ws, c, i == self.selection, &indices, &mut out) }); out } } fn score_c<'a>( x: impl Iterator, filter: &'_ str, ) -> Vec<(u32, &'a str, Vec)> { score(x, filter) } fn filter_c<'a>( _me: &'a Commands, f: &'_ str, ) -> impl Iterator { filter(COMMANDS.into_iter().map(|(x, _)| x), f) } impl<'a> crate::menu::Key<'a> for &'a str { fn key(&self) -> impl Into> { *self } } fn charc(c: &str) -> usize { c.chars().count() } #[implicit_fn::implicit_fn] fn r( x: &str, _workspace: &Path, c: usize, selected: bool, indices: &[u32], to: &mut Vec, ) { let bg = if selected { col!("#262d3b") } else { col!("#1c212b") }; let ds: Style = Style::new(FG, bg); let d: Cell = Cell { letter: None, style: ds }; let mut b = vec![d; c]; let (bgt, col, ty) = (col!("#FFFFFF"), col!("#ACACAC"), ""); b.iter_mut().zip(ty.chars()).for_each(|(x, c)| { *x = (Style::new(col, bgt) | Style::BOLD).basic(c) }); let i = &mut b[2..]; let qualifier = COMMANDS.iter().find(|y| y.0 == x).unwrap().1.chars(); let _left = i.len() as i32 - (charc(&x) as i32 + qualifier.clone().count() as i32) - 3; i.iter_mut() .zip( x.chars().chain([' ']).map(|x| ds.basic(x)).zip(0..).chain( qualifier .map(|x| { Style { bg, fg: color_("#858685"), ..default() } .basic(x) }) .zip(repeat(u32::MAX)), ), ) .for_each(|(a, (b, i))| { *a = b; if indices.contains(&i) { a.style |= (Style::BOLD, color_("#ffcc66")); } }); to.extend(b); }