A simple CPU rendered GUI IDE experience.
| -rw-r--r-- | Cargo.toml | 38 | ||||
| -rw-r--r-- | src/edi/input_handlers.rs | 10 | ||||
| -rw-r--r-- | src/edi/input_handlers/click.rs | 7 | ||||
| -rw-r--r-- | src/edi/input_handlers/cursor.rs | 18 | ||||
| -rw-r--r-- | src/edi/input_handlers/keyboard.rs | 151 | ||||
| -rw-r--r-- | src/edi/st.rs | 38 | ||||
| -rw-r--r-- | src/main.rs | 8 |
7 files changed, 126 insertions, 144 deletions
@@ -9,19 +9,19 @@ fimg = { git = "https://git.bendn.org/fimg" } pattypan = { git = "https://git.bendn.org/pattypan" } implicit-fn = "0.1.0" ropey = "1.6.1" -softbuffer = "0.4.6" -swash = "0.2.5" +softbuffer = "0.4.8" +swash = "0.2.7" winit = "0.31.0-beta.2" -tree-sitter = "0.25.0" -memchr = "2.7.5" -lower = "0.2.0" +tree-sitter = "0.25.10" +memchr = "2.8.1" +lower = "0.2.1" amap = "0.1.4" run_times = "0.1.0" array_chunks = "1.0.0" rust-fsm = { git = "https://git.bendn.org/rust-fsm", features = ["diagram"] } -clipp = "0.1.0" -regex = { version = "1.11.3", features = ["unstable", "use_std"] } +clipp = "0.1.1" +regex = { version = "1.12.3", features = ["unstable", "use_std"] } tree-house = { version = "0.3.0", features = ["fixtures"] } # for tree house grammar loading @@ -36,30 +36,30 @@ rust-analyzer = { git = "https://git.bendn.org/rust-analyzer" } # lsp-server = { path = "../rust-analyzer/lib/lsp-server" } # rust-analyzer = { path = "../rust-analyzer/crates/rust-analyzer" } -serde_json = "1.0.145" +serde_json = "1.0.150" serde = { version = "1.0.228", features = ["unstable"] } serde_derive = "1.0.228" -log = "0.4.28" +log = "0.4.30" crossbeam = { version = "0.8.4", features = ["nightly", "crossbeam-channel"] } -test-log = "0.2.18" -env_logger = "0.11.8" -url = "2.5.7" -tokio = { version = "1.47.1", features = ["rt-multi-thread", "sync", "time"] } +test-log = "0.2.20" +env_logger = "0.11.10" +url = "2.5.8" +tokio = { version = "1.52.3", features = ["rt-multi-thread", "sync", "time"] } regex-cursor = "0.1.5" -papaya = "0.2.3" +papaya = "0.2.4" markdown = "1.0.0" itertools = "0.14.0" -pin-project = "1.1.10" +pin-project = "1.1.13" replace_with = "0.1.8" nucleo = "0.5.0" -tokio-util = { version = "0.7.17", features = ["rt"] } +tokio-util = { version = "0.7.18", features = ["rt"] } scopeguard = "1.2.0" -arc-swap = "1.7.1" -atools = "0.1.10" +arc-swap = "1.9.1" +atools = "0.1.12" swizzle = "0.1.0" walkdir = "2.5.0" niri = { package = "niri-ipc", version = "25.11.0" } -libc = "0.2.180" +libc = "0.2.186" rustc-hash = "=2.1.1" bendy = { version = "0.6.1", features = ["serde"] } git2 = "0.20.4" diff --git a/src/edi/input_handlers.rs b/src/edi/input_handlers.rs index 6457787..e169edb 100644 --- a/src/edi/input_handlers.rs +++ b/src/edi/input_handlers.rs @@ -58,3 +58,13 @@ pub fn handle2<'a>( }; None } +impl Editor { + #[track_caller] + pub fn transition(&mut self, a: Action) -> Option<Do> { + self.state + .consume(a) + .inspect_err(|e| log::error!("transition failed: {e}")) + .ok() + .flatten() + } +} diff --git a/src/edi/input_handlers/click.rs b/src/edi/input_handlers/click.rs index d687c60..80e4065 100644 --- a/src/edi/input_handlers/click.rs +++ b/src/edi/input_handlers/click.rs @@ -12,13 +12,14 @@ impl Editor { cursor_position: (usize, usize), w: Arc<dyn Window>, ) { - let text = &mut self.text; _ = self .requests .complete .consume(CompletionAction::Click) - .unwrap(); - match self.state.consume(Action::M(bt)).unwrap() { + .inspect_err(|x| log::error!("transition comact {x:?}")); + let r = self.transition(Action::M(bt)); + let text = &mut self.text; + match r { Some(Do::ClickedHover | Do::MoveCursor) => { text.cursor.just( text.mapped_index_at(cursor_position), diff --git a/src/edi/input_handlers/cursor.rs b/src/edi/input_handlers/cursor.rs index 092bc5d..ce44657 100644 --- a/src/edi/input_handlers/cursor.rs +++ b/src/edi/input_handlers/cursor.rs @@ -26,7 +26,7 @@ impl Editor { w: Arc<dyn Window>, c: usize, ) { - match self.state.consume(Action::C(cursor_position)).unwrap() { + match self.transition(Action::C(cursor_position)) { Some(Do::ExtendSelectionToMouse) => { let p = self.text.mapped_index_at(cursor_position); self.text @@ -53,9 +53,7 @@ impl Editor { && !e.is_whitespace() => 'out: { match self - .state - .consume(Action::HOnSomething(cursor_position)) - .unwrap() + .transition(Action::HOnSomething(cursor_position)) { Some(Do::SetHovering) => { let State::Hovering(l) = &mut self.state else { @@ -358,13 +356,11 @@ impl Editor { }); let diags = self.find_diags(cursor_position, &w); println!("requesting hover"); - self.state - .consume(Action::SetHovering( - diags.map(|of| Hovring { of, ..default() }), - handle, - (cursor_position, tdpp), - )) - .unwrap(); + self.transition(Action::SetHovering( + diags.map(|of| Hovring { of, ..default() }), + handle, + (cursor_position, tdpp), + )); // self.requests.hovering.request = // (DropH::new(handle), cursor_position).into(); // requests.hovering.result = None; diff --git a/src/edi/input_handlers/keyboard.rs b/src/edi/input_handlers/keyboard.rs index f61a338..8250068 100644 --- a/src/edi/input_handlers/keyboard.rs +++ b/src/edi/input_handlers/keyboard.rs @@ -27,26 +27,27 @@ impl Editor { window: &mut Arc<dyn Window>, freq: &mut Freq, ) -> ControlFlow<()> { - let mut o: Option<Do> = self - .state - .consume(Action::K(event.logical_key.clone())) - .unwrap(); + let Some(mut o) = + self.transition(Action::K(event.logical_key.clone())) + else { + return ControlFlow::Continue(()); + }; + if let Do::Reinsert = o { + let Some(o2) = + self.transition(Action::K(event.logical_key.clone())) + else { + return ControlFlow::Continue(()); + }; + o = o2; + }; match o { - Some(Do::Reinsert) => - o = self - .state - .consume(Action::K(event.logical_key.clone())) - .unwrap(), - _ => {} - } - match o { - Some(Do::Escape) => { + Do::Escape => { take(&mut self.requests.complete); take(&mut self.requests.sig_help); self.text.cursor.alone(); } - Some(Do::Comment(p)) => { + Do::Comment(p) => { ceach!(self.text.cursor, |cursor| { Some( if let Some(x) = cursor.sel @@ -62,7 +63,7 @@ impl Editor { self.text.cursor.clear_selections(); change!(self, window.clone()); } - Some(Do::SpawnTerminal) => { + Do::SpawnTerminal => { if let Err(e) = trm::toggle( self.workspace .as_deref() @@ -71,12 +72,12 @@ impl Editor { log::error!("opening terminal failed {e}"); } } - Some(Do::MatchingBrace) => + Do::MatchingBrace => if let Some((l, f)) = lsp!(self + p) { l.matching_brace(f, &mut self.text) }, - Some(Do::DeleteBracketPair) => self.delete_bracket_pair(), - Some(Do::Symbols) => + Do::DeleteBracketPair => self.delete_bracket_pair(), + Do::Symbols => if let Some((lsp, o)) = lsp!(self + p) && let Ok(syms) = lsp.workspace_symbols("".into()) { @@ -92,7 +93,7 @@ impl Editor { )); self.state = State::Symbols(q); }, - Some(Do::SwitchType) => + Do::SwitchType => if let Some((lsp, p)) = lsp!(self + p) { let State::Symbols(Rq { result: Some(x), request }) = &mut self.state @@ -113,7 +114,7 @@ impl Editor { )); } }, - Some(Do::ProcessCommand(mut x, z)) => + Do::ProcessCommand(mut x, z) => match Cmds::complete_or_accept(&z) { crate::menu::generic::CorA::Complete => { x.tedit.rope = @@ -129,7 +130,7 @@ impl Editor { } } }, - Some(Do::CmdTyped) => { + Do::CmdTyped => { let State::Command(x) = &self.state else { unreachable!() }; @@ -139,7 +140,7 @@ impl Editor { self.text.scroll_to_ln_centering(x as _); } } - Some(Do::SymbolsHandleKey) => { + Do::SymbolsHandleKey => { if let Some(lsp) = lsp!(self) { let State::Symbols(Rq { result: Some(x), request }) = &mut self.state @@ -183,7 +184,7 @@ impl Editor { } } } - Some(Do::SymbolsSelectNext) => { + Do::SymbolsSelectNext => { let State::Symbols(Rq { result: Some(x), .. }) = &mut self.state else { @@ -203,7 +204,7 @@ impl Editor { } } } - Some(Do::SymbolsSelectPrev) => { + Do::SymbolsSelectPrev => { let State::Symbols(Rq { result: Some(x), .. }) = &mut self.state else { @@ -223,15 +224,15 @@ impl Editor { } } } - Some(Do::SymbolsSelect(x)) => + Do::SymbolsSelect(x) => if let Some(Ok(x)) = x.sel(Some(freq)) && let Err(e) = self.go(x.at, window.clone()) { log::error!("alas! {e}") }, - Some(Do::RenameSymbol(to)) => self.rename_symbol(to), - Some(Do::CodeAction) => self.request_code_actions(), - Some(Do::CASelectLeft) => { + Do::RenameSymbol(to) => self.rename_symbol(to), + Do::CodeAction => self.request_code_actions(), + Do::CASelectLeft => { let State::CodeAction(Rq { result: Some(c), .. }) = &mut self.state else { @@ -239,7 +240,7 @@ impl Editor { }; c.left(); } - Some(Do::CASelectRight) => 'out: { + Do::CASelectRight => 'out: { let Some(lsp) = lsp!(self) else { unreachable!() }; let State::CodeAction(Rq { result: Some(c), .. }) = &mut self.state @@ -260,7 +261,7 @@ impl Editor { log::error!("{e}"); } } - Some(Do::CASelectNext) => { + Do::CASelectNext => { let State::CodeAction(Rq { result: Some(c), .. }) = &mut self.state else { @@ -268,7 +269,7 @@ impl Editor { }; c.down(); } - Some(Do::CASelectPrev) => { + Do::CASelectPrev => { let State::CodeAction(Rq { result: Some(c), .. }) = &mut self.state else { @@ -276,7 +277,7 @@ impl Editor { }; c.up(); } - Some(Do::GoToMatch) + Do::GoToMatch if let Some(x) = &self.requests.document_highlights.result => 'out: { @@ -314,37 +315,36 @@ impl Editor { } } } - Some(Do::GoToMatch) => + Do::GoToMatch => if self.requests.document_highlights.request.is_none() { self.refresh_document_highlights(); }, - Some(Do::NavBack) => self.nav_back(), - Some(Do::NavForward) => self.nav_forward(), - Some( - Do::Reinsert - | Do::GoToDefinition(_) - | Do::MoveCursor - | Do::ExtendSelectionToMouse - | Do::Hover - | Do::InsertCursorAtMouse - | Do::SetHovering - | Do::ClickedHover, - ) => panic!(), - Some(Do::Save) => match &self.origin { + Do::NavBack => self.nav_back(), + Do::NavForward => self.nav_forward(), + + Do::Reinsert + | Do::GoToDefinition(_) + | Do::MoveCursor + | Do::ExtendSelectionToMouse + | Do::Hover + | Do::InsertCursorAtMouse + | Do::SetHovering + | Do::ClickedHover => panic!(), + Do::Save => match &self.origin { Some(_) => { - self.state.consume(Action::Saved).unwrap(); + self.transition(Action::Saved); self.save(); } None => { - self.state.consume(Action::RequireFilename).unwrap(); + self.transition(Action::RequireFilename); } }, - Some(Do::SaveTo(x)) => { + Do::SaveTo(x) => { self.origin = Some(PathBuf::try_from(x).unwrap()); self.save(); } - Some(Do::Edit) => self.handle_edit(event), - Some(Do::Undo) => { + Do::Edit => self.handle_edit(event), + Do::Undo => { self.hist.test_push(&mut self.text); if let Err(e) = self.hist.undo(&mut self.text) { eprintln!("undo failed: {e}"); @@ -353,14 +353,14 @@ impl Editor { change!(self, window.clone()); } - Some(Do::Redo) => { + Do::Redo => { self.hist.test_push(&mut self.text); self.hist.redo(&mut self.text).unwrap(); self.bar.last_action = "redid".to_string(); change!(self, window.clone()); } - Some(Do::Quit) => return ControlFlow::Break(()), - Some(Do::SetCursor(x)) => { + Do::Quit => return ControlFlow::Break(()), + Do::SetCursor(x) => { self.text.cursor.each(|c| { let Some(r) = c.sel else { return }; match x { @@ -370,7 +370,7 @@ impl Editor { }); self.text.cursor.clear_selections(); } - Some(Do::StartSelection) => { + Do::StartSelection => { let Key::Named(y) = event.logical_key else { panic!() }; // let mut z = vec![]; self.text.cursor.each(|x| { @@ -385,7 +385,7 @@ impl Editor { }); // *self.state.sel() = z; } - Some(Do::UpdateSelection) => { + Do::UpdateSelection => { let Key::Named(y) = event.logical_key else { panic!() }; self.text.cursor.each(|x| { x.extend_selection( @@ -400,7 +400,7 @@ impl Editor { self.text.scroll_to_cursor(); inlay!(self); } - Some(Do::Insert(c)) => { + Do::Insert(c) => { // self.text.cursor.inner.clear(); self.hist.push_if_changed(&mut self.text); ceach!(self.text.cursor, |cursor| { @@ -413,7 +413,7 @@ impl Editor { self.hist.push_if_changed(&mut self.text); change!(self, window.clone()); } - Some(Do::Delete) => { + Do::Delete => { self.hist.push_if_changed(&mut self.text); ceach!(self.text.cursor, |cursor| { let Some(r) = cursor.sel else { return }; @@ -424,7 +424,7 @@ impl Editor { change!(self, window.clone()); } - Some(Do::Copy) => { + Do::Copy => { self.hist.push_if_changed(&mut self.text); unsafe { take(&mut META) }; let mut clip = String::new(); @@ -446,7 +446,7 @@ impl Editor { self.hist.push_if_changed(&mut self.text); change!(self, window.clone()); } - Some(Do::Cut) => { + Do::Cut => { self.hist.push_if_changed(&mut self.text); unsafe { take(&mut META) }; let mut clip = String::new(); @@ -473,7 +473,7 @@ impl Editor { self.hist.push_if_changed(&mut self.text); change!(self, window.clone()); } - Some(Do::PasteOver) => { + Do::PasteOver => { self.hist.push_if_changed(&mut self.text); ceach!(self.text.cursor, |cursor| { let Some(r) = cursor.sel else { return }; @@ -483,11 +483,11 @@ impl Editor { self.paste(); // self.hist.push_if_changed(&mut self.text); } - Some(Do::Paste) => self.paste(), - Some(Do::OpenFile(x)) => { + Do::Paste => self.paste(), + Do::OpenFile(x) => { _ = self.open(Path::new(&x), window.clone()); } - Some(Do::StartSearch(x)) => { + Do::StartSearch(x) => { let s = Regex::new(&x).unwrap(); let n = s .find_iter(&self.text.rope.to_string()) @@ -510,7 +510,7 @@ impl Editor { self.bar.last_action = "no matches".into() }); } - Some(Do::SearchChanged) => { + Do::SearchChanged => { let (re, index, _) = self.state.search(); let s = self.text.rope.to_string(); let m = re.find_iter(&s).nth(*index).unwrap(); @@ -521,7 +521,7 @@ impl Editor { self.text.scroll_to_cursor_centering(); inlay!(self); } - Some(Do::Boolean(BoolRequest::ReloadFile, true)) => { + Do::Boolean(BoolRequest::ReloadFile, true) => { self.hist.push_if_changed(&mut self.text); self.text.rope = Rope::from_str( &std::fs::read_to_string( @@ -540,8 +540,8 @@ impl Editor { self.bar.last_action = "reloaded".into(); self.hist.push(&mut self.text) } - Some(Do::Boolean(BoolRequest::ReloadFile, false)) => {} - Some(Do::InsertCursor(dir)) => { + Do::Boolean(BoolRequest::ReloadFile, false) => {} + Do::InsertCursor(dir) => { let (x, y) = match dir { Direction::Above => self.text.cursor.min(), Direction::Below => self.text.cursor.max(), @@ -554,7 +554,7 @@ impl Editor { let position = self.text.line_to_char(y); self.text.cursor.add(position + x, &self.text.rope); } - Some(Do::Run(x)) => + Do::Run(x) => if let Some((l, ws)) = lsp!(self).zip(self.workspace.as_deref()) { @@ -562,7 +562,7 @@ impl Editor { .block_on(crate::runnables::run(x, ws)) .unwrap(); }, - Some(Do::GoToImplementations) => { + Do::GoToImplementations => { let State::GoToL(x) = &mut self.state else { unreachable!() }; @@ -574,13 +574,13 @@ impl Editor { ))); } } - Some(Do::GTLSelect(x)) => + Do::GTLSelect(x) => if let Some(Ok((g, _))) = x.sel(None) && let Err(e) = self.go(g, window.clone()) { eprintln!("go-to-list select fail: {e}"); }, - Some(Do::GT) => { + Do::GT => { let State::GoToL(x) = &mut self.state else { unreachable!() }; @@ -593,7 +593,6 @@ impl Editor { // self.text.vo = self.text.char_to_line(x.start); } } - None => {} } ControlFlow::Continue(()) } @@ -699,7 +698,11 @@ impl Editor { .requests .complete .consume(CompletionAction::K(event.logical_key.as_ref())) - .unwrap() + .inspect_err(|e| { + log::error!("failure: {e}"); + }) + .ok() + .flatten() { Some(CDo::Request(ctx)) => { if let Ok(fut) = lsp.request_complete( diff --git a/src/edi/st.rs b/src/edi/st.rs index 3fe6b31..c145f21 100644 --- a/src/edi/st.rs +++ b/src/edi/st.rs @@ -93,43 +93,7 @@ Hovering(x) => { C(_) => _ [Hover], MovedOut => Default, Scrolled => Default, - // reconsidering - K(Key::Character("s") if ctrl()) => Save [Save], - K(Key::Character("q") if ctrl()) => Dead [Quit], - K(Key::Character("v") if ctrl()) => Default [Paste], - K(Key::Character("z") if ctrl()) => Default [Undo], - K(Key::Character("d") if ctrl()) => Default [GoToMatch], - K(Key::Character("y") if ctrl()) => Default [Redo], - K(Key::Character("f") if ctrl()) => Procure((default(), InputRequest::Search)), - K(Key::Character("o") if ctrl()) => Procure((default(), InputRequest::OpenFile)), - K(Key::Character("c") if ctrl()) => Default , - K(Key::Character("l") if ctrl()) => Default [Symbols], - K(Key::Character(".") if ctrl()) => Default [CodeAction], - K(Key::Character("0") if ctrl()) => Default [MatchingBrace], - K(Key::Character("`") if ctrl()) => Default [SpawnTerminal], - K(Key::Character("/") if ctrl()) => Default [Comment(State => State::Default)], - K(Key::Character("p") if ctrl()) => Command(Commands => default()), - K(Key::Named(Backspace) if alt()) => Default [DeleteBracketPair], - K(Key::Named(F1)) => Procure((default(), InputRequest::RenameSymbol)), - K(Key::Named(F10)) => GoToL(GoToList => default()) [GoToImplementations], - K(Key::Named(k @ (ArrowUp | ArrowDown)) if alt()) => Default [InsertCursor(Direction => { - if k == ArrowUp {Direction::Above} else { Direction::Below } - })], - K(Key::Named(ArrowUp | ArrowLeft | ArrowDown | ArrowRight | Home | End) if shift()) => Selection [StartSelection], - M(MouseButton::Left if shift()) => Selection [StartSelection], - M(MouseButton::Left if alt()) => Default [InsertCursorAtMouse], - M(MouseButton::Left if ctrl()) => Default [GoToDefinition(Option<TextDocumentPositionParams> => None)], - M(MouseButton::Left) => Default [MoveCursor], - K(Key::Character("=") if ctrl()) => Default [NavForward], - K(Key::Character("-") if ctrl()) => Default [NavBack], - M(MouseButton::Back) => Default [NavBack], - M(MouseButton::Forward) => _ [NavForward], - C(((usize, usize)) => .. if unsafe { CLICKING }) => Selection [StartSelection], - Changed => RequestBoolean(BoolRequest => BoolRequest::ReloadFile), - K(Key::Named(Escape)) => Default [Escape], - K(_) => Default [Edit], - // duplicate zone - + K(_) => Default [Reinsert], M(MouseButton::Left if ctrl()) => Default [GoToDefinition(x.request.map(|x| x.1.1).or(x.result.and_then(|x| x.of.iter().find_map(|x| x.tdpp()))))], M(_) => _ [ClickedHover], diff --git a/src/main.rs b/src/main.rs index 95d2c5e..9f46bc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -322,6 +322,14 @@ pub(crate) fn entry(event_loop: EventLoop) { ed.scroll(rows); window.request_redraw(); } + WindowEvent::MouseWheel { + device_id: _, + delta: MouseScrollDelta::PixelDelta(PhysicalPosition { x:_, y }), + phase: _, + } => { + ed.scroll(y as f32 *5.0); + window.request_redraw(); + } WindowEvent::ModifiersChanged(modifiers) => { unsafe { MODIFIERS = modifiers.state() }; window.request_redraw(); |