A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/commands.rs')
-rw-r--r--src/commands.rs163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/commands.rs b/src/commands.rs
new file mode 100644
index 0000000..4f19b01
--- /dev/null
+++ b/src/commands.rs
@@ -0,0 +1,163 @@
+use std::iter::repeat;
+use std::path::Path;
+
+use Default::default;
+use dsb::Cell;
+use dsb::cell::Style;
+use lsp_types::*;
+
+use crate::FG;
+use crate::com::{back, filter, next, score};
+use crate::text::{TextArea, col, color_, set_a};
+
+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>(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>(n, &mut self.selection, &mut self.vo);
+ }
+ pub fn cells(&self, c: usize, ws: &Path) -> Vec<Cell> {
+ 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<Item = &'a str>,
+ filter: &'_ str,
+) -> Vec<(u32, &'a str, Vec<u32>)> {
+ score(x, std::convert::identity, filter)
+}
+
+fn filter_c<'a>(
+ completion: &'a Commands,
+ f: &'_ str,
+) -> impl Iterator<Item = &'a str> {
+ filter(COMMANDS.into_iter().map(|(x, _)| x), std::convert::identity, f)
+}
+fn sym_as_str(x: &str) -> &str {
+ &x
+}
+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<Cell>,
+) {
+ 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);
+}