A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/commands.rs')
-rw-r--r--src/commands.rs159
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);
+}