A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/commands.rs')
| -rw-r--r-- | src/commands.rs | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/commands.rs b/src/commands.rs new file mode 100644 index 0000000..c21acb1 --- /dev/null +++ b/src/commands.rs @@ -0,0 +1,159 @@ +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, charc, filter, next, score}; +use crate::text::{TextArea, col, color_}; + +macro_rules! commands { + ($(#[doc = $d: literal] $t:tt $identifier: ident: $c:literal),+ $(,)?) => { + #[derive(Copy, Clone, PartialEq, Eq)] + pub enum Cmd { + $(#[doc = $d] $identifier),+ + } + impl Cmd { + pub const ALL: [Cmd; { [$($c),+].len() }] = [$(Self::$identifier,)+]; + pub fn name(self) -> &'static str { + match self { + $(Self::$identifier => $c,)+ + } + } + pub fn desc(self) -> &'static str { + match self { + $(Self::$identifier => $d,)+ + } + } + pub fn needs_lsp(self) -> bool { + match self { + $(Self::$identifier => stringify!($t) == "@",)+ + } + } + } + }; +} +commands!( + /// move item at cursor down + @ RAMoveID: "move-item-down", + /// move item at cursor up + @ RAMoveIU: "move-item-up", + /// restart rust analyzer + @ RARestart: "ra-restart", + /// go to parent module + @ RAParent: "parent", + +); + +#[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) -> Self { + let n = filter_c(&self.f()).count(); + // coz its bottom up + back::<N>(n, &mut self.selection, &mut self.vo); + self + } + + pub fn sel(&self) -> Cmd { + let f = self.f(); + score_c(filter_c(&f), &f)[self.selection].1 + } + + pub fn back(mut self) -> Self { + let n = filter_c(&self.f()).count(); + next::<N>(n, &mut self.selection, &mut self.vo); + self + } + pub fn cells(&self, c: usize, ws: &Path) -> Vec<Cell> { + let f = self.f(); + let mut out = vec![]; + let v = score_c(filter_c(&f), &f); + let vlen = v.len(); + let i = v.into_iter().zip(0..vlen).skip(self.vo).take(N).rev(); + + i.for_each(|((_, x, indices), i)| { + r(x, ws, c, i == self.selection, &indices, &mut out) + }); + + out + } +} +fn score_c( + x: impl Iterator<Item = Cmd>, + filter: &'_ str, +) -> Vec<(u32, Cmd, Vec<u32>)> { + score(x, filter) +} + +fn filter_c(f: &'_ str) -> impl Iterator<Item = Cmd> { + filter(Cmd::ALL.into_iter(), f) +} +impl crate::menu::Key<'static> for Cmd { + fn key(&self) -> impl Into<std::borrow::Cow<'static, str>> { + self.name() + } +} +#[implicit_fn::implicit_fn] +fn r( + x: Cmd, + _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[..]; + let qualifier = x.desc().chars(); + let _left = i.len() as i32 + - (charc(&x.name()) as i32 + qualifier.clone().count() as i32) + - 3; + + i.iter_mut() + .zip( + x.name() + .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); +} |