A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/commands.rs')
-rw-r--r--src/commands.rs100
1 files changed, 70 insertions, 30 deletions
diff --git a/src/commands.rs b/src/commands.rs
index 5b99581..a0b28f8 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -16,7 +16,9 @@ use crate::edi::{Editor, lsp_m};
use crate::lsp::{PathURI, Rq};
use crate::menu::charc;
use crate::menu::generic::{CorA, GenericMenu, MenuData};
-use crate::text::{RopeExt, SortTedits, col, color_};
+use crate::text::{
+ Bookmark, RopeExt, SortTedits, TextArea, col, color_,
+};
macro_rules! repl {
($x:ty, $($with:tt)+) => {
@@ -25,7 +27,7 @@ macro_rules! repl {
}
macro_rules! commands {
($(#[doc = $d: literal] $t:tt $identifier: ident$(($($thing:ty),+))?: $c:literal),+ $(,)?) => {
- #[derive(Copy, Clone, PartialEq, Eq, Debug)]
+ #[derive(Clone, PartialEq, Eq, Debug)]
pub enum Cmd {
$(#[doc = $d] $identifier $( ( $(Option<$thing>,)+ ) )?
@@ -35,7 +37,7 @@ macro_rules! commands {
pub const ALL: [Cmd; { [$($c),+].len() }] = [$(Self::$identifier
$( ( $(None::<$thing>,)+) )?
,)+];
- pub fn name(self) -> &'static str {
+ pub fn name(&self) -> &'static str {
match self {
$(Self::$identifier $( ( $(repl!($thing, _),)+ ) )? => $c,)+
}
@@ -45,16 +47,42 @@ macro_rules! commands {
// $(Self::$identifier => &[$($(wants::$thing as u8,)+)?],)+
// }
// }
- pub fn desc(self) -> &'static str {
+ pub fn desc(&self) -> &'static str {
match self {
$(Self::$identifier $( ( $(repl!($thing, _),)+ ) )? => $d,)+
}
}
- pub fn needs_lsp(self) -> bool {
+ pub fn needs_lsp(&self) -> bool {
match self {
$(Self::$identifier $( ( $(repl!($thing, _),)+ ) )? => stringify!($t) == "@",)+
}
}
+ fn map(self, t: &TextArea) -> Result<Self, &'static str> {
+ match self {
+ $($(
+ Self::$identifier($( repl!($thing, None),)+) => {
+ if !t.rope.to_string().starts_with(Self::$identifier(None).name()) { return Ok(self) }
+ if let Some((_, x)) = t.to_string().split_once(" ")
+ // && x.chars().all(|x| x.is_numeric())s
+ && let Ok(n) = x.parse()
+ {
+ Ok(Self::$identifier(Some(n)))
+ } else {
+ Err(concat! ("supply ", $(stringify!($thing))+))
+ }
+ })?)+
+ _ => Ok(self),
+ }
+ }
+ fn cora(&self) -> CorA {
+ match self {
+ $($(
+ Self::$identifier($( repl!($thing, None),)+) => {
+ CorA::Complete
+ })?)+
+ _ => CorA::Accept,
+ }
+ }
}
};
}
@@ -71,13 +99,13 @@ commands!(
@ RAJoinLines: "join-lines",
/// gets list of runnables
@ RARunnables: "runnables",
- /// Open docs for type at cursor
+ /// 󱛉 Open docs for type at cursor
@ RADocs: "open-docs",
/// Rebuilds rust-analyzer proc macros
@ RARebuildProcMacros: "rebuild-proc-macros",
/// Cancels current running rust-analyzer check process
@ RACancelFlycheck: "cancel-flycheck",
- /// Opens Cargo.toml file for this workspace
+ ///  Opens Cargo.toml file for this workspace
@ RAOpenCargoToml: "open-cargo-toml",
/// Runs the test at the cursor
@ RARunTest: "run-test",
@@ -85,6 +113,10 @@ commands!(
// @ ViewChildModules: "child-modules",
/// GoTo line,
| GoTo(u32): "g",
+ /// 󰃅 Define bookmark
+ | DefineBookmark(String): "bookmark",
+ /// 󰃆 Remove bookmark
+ | RemoveBookmark: "remove-bookmark",
);
pub enum Cmds {}
@@ -104,24 +136,10 @@ impl MenuData for Cmds {
m: &GenericMenu<Self>,
x: Self::Element<'a>,
) -> Result<Self::Element<'a>, Self::E> {
- if let Cmd::GoTo(_) = x {
- if !m.tedit.to_string().starts_with(Cmd::GoTo(None).name()) {
- return Ok(Cmd::GoTo(None));
- }
- if let Some((_, x)) = m.tedit.to_string().split_once(" ")
- // && x.chars().all(|x| x.is_numeric())
- && let Ok(n) = x.parse()
- {
- Ok(Cmd::GoTo(Some(n)))
- } else {
- Err("supply number")
- }
- } else {
- Ok(x)
- }
+ x.map(&m.tedit)
}
- fn complete_or_accept<'a>(x: Self::Element<'a>) -> CorA {
- if let Cmd::GoTo(None) = x { CorA::Complete } else { CorA::Accept }
+ fn complete_or_accept<'a>(x: &Self::Element<'a>) -> CorA {
+ x.cora()
}
fn f(m: &GenericMenu<Self>) -> String {
m.tedit
@@ -203,16 +221,39 @@ impl Editor {
self.text.cursor.just(x, &self.text.rope);
self.text.scroll_to_cursor_centering();
},
- x if x.needs_lsp() => {}
+ Cmd::DefineBookmark(Some(x)) =>
+ self.text.bookmarks.push(Bookmark {
+ position: *self.text.cursor.first(),
+ text: x.clone(),
+ }),
+ Cmd::RemoveBookmark => {
+ let y = self.text.y(*self.text.cursor.first()).unwrap();
+ let r = self.text.line_to_char(y)
+ ..self.text.line_to_char(y + 1);
+ self.text
+ .bookmarks
+ .clone()
+ .iter()
+ .enumerate()
+ .filter(|(_, x)| r.contains(&x.position))
+ .map(ttools::fst)
+ .rev()
+ .for_each(|x| drop(self.text.bookmarks.remove(x)));
+ }
+ z if z.needs_lsp() => return self.handle_lsp_command(z, w),
x => unimplemented!("{x:?}"),
}
- if !z.needs_lsp() {
- return Ok(());
- }
+
+ Ok(())
+ }
+ pub fn handle_lsp_command(
+ &mut self,
+ z: Cmd,
+ w: Arc<dyn winit::window::Window>,
+ ) -> rootcause::Result<()> {
let Some((l, o)) = lsp_m!(self + p) else {
bail!("no lsp");
};
-
match z {
Cmd::RAMoveIU | Cmd::RAMoveID => {
let r = self
@@ -333,7 +374,6 @@ impl Editor {
}
_ => unimplemented!(),
}
-
Ok(())
}
}