A simple CPU rendered GUI IDE experience.
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/complete.rs | 6 | ||||
| -rw-r--r-- | src/edi.rs | 2 | ||||
| -rw-r--r-- | src/edi/input_handlers/click.rs | 2 | ||||
| -rw-r--r-- | src/edi/input_handlers/cursor.rs | 106 | ||||
| -rw-r--r-- | src/edi/input_handlers/keyboard.rs | 4 | ||||
| -rw-r--r-- | src/edi/lsp_impl.rs | 11 | ||||
| -rw-r--r-- | src/edi/st.rs | 25 | ||||
| -rw-r--r-- | src/lsp/rq.rs | 7 | ||||
| -rw-r--r-- | src/main.rs | 22 | ||||
| -rw-r--r-- | src/rnd.rs | 15 | ||||
| -rw-r--r-- | src/runnables.rs | 6 | ||||
| -rw-r--r-- | src/sym.rs | 7 | ||||
| -rw-r--r-- | src/text.rs | 12 | ||||
| -rw-r--r-- | src/text/semantic_tokens/theme.rs | 4 |
15 files changed, 139 insertions, 91 deletions
@@ -14,7 +14,6 @@ swash = "0.2.5" winit = "0.31.0-beta.2" tree-sitter = "0.25.0" -car = "0.1.2" memchr = "2.7.5" lower = "0.2.0" amap = "0.1.4" diff --git a/src/complete.rs b/src/complete.rs index ab39eb9..11ded6c 100644 --- a/src/complete.rs +++ b/src/complete.rs @@ -97,7 +97,7 @@ fn r( let d: Cell = Cell { letter: None, style: ds }; let mut b = vec![d; c]; const MAP: [([u8; 3], [u8; 3], &str); 26] = { - car::map!( + ( amap::amap! { const { CompletionItemKind::TEXT.0 as usize } => ("#9a9b9a", " "), const { CompletionItemKind::METHOD.0 as usize } | const { CompletionItemKind::FUNCTION.0 as usize } => ("#FFD173", "λ "), @@ -118,8 +118,8 @@ fn r( const { CompletionItemKind::TYPE_PARAMETER.0 as usize } => ("#9a9b9a", "T "), const { CompletionItemKind::KEYWORD.0 as usize } => ("#FFAD66", "as"), _ => ("#9a9b9a", " ") - }, - |(x, y)| (set_a(color_(x), 0.5), color_(x), y) + }).map(const + |(x, y)| (set_a(color_(x), 0.5), color_(x), y), ) }; let (bgt, col, ty) = @@ -387,7 +387,7 @@ impl Editor { } pub fn scroll(&mut self, rows: f32) { let rows = if alt() { rows * 8. } else { rows * 3. }; - let (vo, max) = lower::saturating::math! { if let Some(x)= &mut self.requests.hovering.result && shift() { + let (vo, max) = lower::saturating::math! { if let State::Hovering(Rq {result: Some(x), ..}) = &mut self.state && shift() { let n = x.item.l(); (&mut x.item.vo, n - 15) } else if let Some((_, ref mut vo, Some(max))) = self.requests.sig_help.result && shift(){ diff --git a/src/edi/input_handlers/click.rs b/src/edi/input_handlers/click.rs index 692be1a..2357376 100644 --- a/src/edi/input_handlers/click.rs +++ b/src/edi/input_handlers/click.rs @@ -19,7 +19,7 @@ impl Editor { .consume(CompletionAction::Click) .unwrap(); match self.state.consume(Action::M(bt)).unwrap() { - Some(Do::MoveCursor) => { + Some(Do::ClickedHover | Do::MoveCursor) => { text.cursor.just( text.mapped_index_at(cursor_position), &text.rope, diff --git a/src/edi/input_handlers/cursor.rs b/src/edi/input_handlers/cursor.rs index 4aeaf02..166de8b 100644 --- a/src/edi/input_handlers/cursor.rs +++ b/src/edi/input_handlers/cursor.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::ops::ControlFlow; use std::sync::Arc; use Default::default; @@ -9,7 +10,11 @@ use rust_fsm::StateMachine; use tokio::task::spawn_blocking; use tokio_util::task::AbortOnDropHandle as DropH; use winit::window::Window; - +enum Set<T> { + To(T), + Reset, + Ignore, +} use crate::edi::*; use crate::rnd::CellBuffer; impl Editor { @@ -40,34 +45,53 @@ impl Editor { .text .visual_index_at(cursor_position) .map(Mapping::own) - && let Some(_) = lsp!(self) => + && let Some(x) = lsp!(self) + && x.initialized.is_some() + && let Mapping::Char(e, ..) | Mapping::Fake(.., e) = + hover + && !e.is_whitespace() => 'out: { - let l = &mut self.requests.hovering.result; - if let Some(Hovr { - span: Some([(_x, _y), (_x2, _)]), .. - }) = &*l - && let Some(_y) = _y.checked_sub(self.text.vo) - && let Some(_x) = _x.checked_sub(self.text.ho) - && let Some(_x2) = _x2.checked_sub(self.text.ho) - && cursor_position.1 == _y - && (_x..=_x2).contains( - &&(cursor_position.0 - - self.text.line_number_offset() - - 1), - ) + match self + .state + .consume(Action::HOnSomething(cursor_position)) + .unwrap() { - break 'out; - } else { - // println!("span no longer below cursor; cancel hover {_x}..{_x2} {}", cursor_position.0 - text.line_number_offset() - 1); - *l = None; - w.request_redraw(); + Some(Do::SetHovering) => { + let State::Hovering(l) = &mut self.state else { + panic!() + }; + + let l2 = &mut l.result; + if let Some(Hovr { + span: Some([(_x, _y), (_x2, _)]), + .. + }) = &*l2 + && let Some(_y) = _y.checked_sub(self.text.vo) + && let Some(_x) = _x.checked_sub(self.text.ho) + && let Some(_x2) = + _x2.checked_sub(self.text.ho) + && cursor_position.1 == _y + && (_x..=_x2).contains( + &&(cursor_position.0 + - self.text.line_number_offset() + - 1), + ) + { + break 'out; + } else { + // println!("span no longer below cursor; cancel hover {_x}..{_x2} {}", cursor_position.0 - text.line_number_offset() - 1); + *l2 = None; + w.request_redraw(); + } + self.rq_hover(hover, cursor_position, c); + } + _ => {} } - self.rq_hover(hover, cursor_position, c); + // let l = &mut self.requests.hovering.result; } Some(Do::Hover) => { - self.requests.def.result = None; - self.requests.hovering.result = None; - w.request_redraw(); + self.state.consume(Action::HOnNothing).unwrap(); + // w.request_redraw(); } None => {} x => unreachable!("{x:?}"), @@ -117,7 +141,7 @@ impl Editor { } } }; - if ctrl() { + let x = if ctrl() { if self .requests .def @@ -136,8 +160,9 @@ impl Editor { .unwrap() .0, ); - self.requests.def.request = - Some((DropH::new(handle), cursor_position)); + Set::To((handle, cursor_position)) + // self.requests.def.request = + // Some((DropH::new(handle), cursor_position)); } else if self.requests.def.result.as_ref().is_some_and(|em| { let z = em.origin_selection_range.unwrap(); (z.start.character..z.end.character).contains( @@ -145,16 +170,20 @@ impl Editor { as _), ) }) { - self.requests.def.result = None; + Set::Reset + } else { + Set::Ignore } } else { - self.requests.def.result = None; - } - if let Some((_, c)) = self.requests.hovering.request - && c == cursor_position - { - return; - } + Set::Reset + }; + + // match self.state.consume(cursor_position) {} + // if let Some((_, c)) = hov.request + // && c == cursor_position + // { + // return; + // } // if !running.insert(hover) {return} let (rx, _) = lsp .request::<HoverRequest>(&HoverParams { @@ -235,8 +264,11 @@ impl Editor { .into(), )) }); - self.requests.hovering.request = - (DropH::new(handle), cursor_position).into(); + self.state + .consume(Action::SetHovering(handle, cursor_position)) + .unwrap(); + // self.requests.hovering.request = + // (DropH::new(handle), cursor_position).into(); // requests.hovering.result = None; // lsp!().map(|(cl, o)| { // let window = window.clone(); diff --git a/src/edi/input_handlers/keyboard.rs b/src/edi/input_handlers/keyboard.rs index 48f91d6..1fc1f00 100644 --- a/src/edi/input_handlers/keyboard.rs +++ b/src/edi/input_handlers/keyboard.rs @@ -325,7 +325,9 @@ impl Editor { | Do::MoveCursor | Do::ExtendSelectionToMouse | Do::Hover - | Do::InsertCursorAtMouse, + | Do::InsertCursorAtMouse + | Do::SetHovering + | Do::ClickedHover, ) => panic!(), Some(Do::Save) => match &self.origin { Some(_) => { diff --git a/src/edi/lsp_impl.rs b/src/edi/lsp_impl.rs index 19ad79b..d8f2898 100644 --- a/src/edi/lsp_impl.rs +++ b/src/edi/lsp_impl.rs @@ -16,8 +16,8 @@ use crate::{CompletionState, act, sig, sym}; #[derive(Default, Debug, Serialize, Deserialize)] pub struct Requests { - pub hovering: - Rq<Hovr, Option<Hovr>, (usize, usize), RequestError<HoverRequest>>, + // pub hovering: + // Rq<Hovr, Option<Hovr>, (usize, usize), RequestError<HoverRequest>>, pub document_highlights: Rq< Vec<DocumentHighlight>, Vec<DocumentHighlight>, @@ -149,6 +149,11 @@ impl crate::edi::Editor { }) }); } + State::Hovering(x) => { + if x.poll(|x, _| x.ok().flatten()) && x.result.is_none() { + self.state = State::Default; + } + } State::GoToL(z) => match &mut z.data.1 { Some(crate::gotolist::O::References(y)) => { y.poll(|x, _| { @@ -247,7 +252,7 @@ impl crate::edi::Editor { } }) }); - self.requests.hovering.poll(|x, _| x.ok().flatten()); + // self.requests.hovering.poll(|x, _| x.ok().flatten()); self.requests.git_diff.poll(|x, _| x.ok()); self.requests.document_symbols.poll(|x, _| { x.ok().flatten().map(|x| match x { diff --git a/src/edi/st.rs b/src/edi/st.rs index 859ce4f..17da088 100644 --- a/src/edi/st.rs +++ b/src/edi/st.rs @@ -1,6 +1,7 @@ -#![allow(dead_code, unused)] +#![allow(dead_code, unused, unexpected_cfgs)] use Default::default; use NamedKey::*; +use lsp_types::request::HoverRequest; use lsp_types::*; use regex::Regex; use rust_analyzer::lsp::ext::Runnable; @@ -10,7 +11,8 @@ use winit::keyboard::{Key, NamedKey, SmolStr}; use crate::commands::Commands; use crate::edi::handle2; use crate::gotolist::GoToList; -use crate::lsp::{AQErr, Rq, RqS}; +use crate::hov::Hovr; +use crate::lsp::{AQErr, RequestError, Rq, RqS}; use crate::menu::generic::{GenericMenu, MenuData}; use crate::sym::{Symbols, SymbolsList}; use crate::text::TextArea; @@ -72,10 +74,27 @@ Default => { C(((usize, usize)) => .. if unsafe { CLICKING }) => Selection [StartSelection], Changed => RequestBoolean(BoolRequest => BoolRequest::ReloadFile), K(Key::Named(Escape)) => _ [Escape], - C(_) => _ [Hover], + C(_) => Hovered [Hover], K(_) => _ [Edit], M(_) => _, }, +Hovered => { + HOnSomething(((usize, usize)) => pos) => Hovering(Rq<Hovr, Option<Hovr>, (usize, usize), RequestError<HoverRequest>> => default()) [SetHovering], + HOnNothing => Default, +}, +Hovering(x) => { + // now hovering over something else, cancel existing hover + HOnSomething(pos if let Some((_, c)) = x.request && dbg!(c != pos)) => _ [SetHovering], + HOnSomething(_) => _ [SetHovering], + HOnNothing => Default, + SetHovering((tokio::task::JoinHandle< + Result<Option<Hovr>, RequestError<HoverRequest>>, + >, (usize, usize)) => (h, d)) => Hovering({ let mut x = x; x.request_d(h, d); x }), + C(_) => _ [Hover], + MovedOut => Default, + K(_) => _, + M(_) => _ [ClickedHover], +}, Command(_) => K(Key::Named(Escape)) => Default, Command(t) => K(Key::Named(Enter) if let Some(Ok(x)) = t.sel()) => Default [ProcessCommand((Commands, crate::commands::Cmd) => (t, x))], Command(t) => K(Key::Named(Enter)) => _, diff --git a/src/lsp/rq.rs b/src/lsp/rq.rs index eb3ec7e..b9b2c7b 100644 --- a/src/lsp/rq.rs +++ b/src/lsp/rq.rs @@ -117,7 +117,12 @@ impl<T, R, E> Rq<T, R, (), E> { } } pub fn request(&mut self, f: task::JoinHandle<Result<R, E>>) { - self.request = Some((AbortOnDropHandle::new(f), ())); + self.request_d(f, ()); + } +} +impl<T, R, D, E> Rq<T, R, D, E> { + pub fn request_d(&mut self, f: task::JoinHandle<Result<R, E>>, d: D) { + self.request = Some((AbortOnDropHandle::new(f), d)); } } impl<T, R, D, E> Rq<T, R, D, E> { diff --git a/src/main.rs b/src/main.rs index 9dd235e..b8009d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ #![feature( - field_projections, - trim_prefix_suffix, - const_closures, yeet_expr, + const_array, + const_closures, adt_const_params, inherent_associated_types, never_type, @@ -10,43 +9,30 @@ btree_set_entry, associated_type_defaults, array_try_map, - tuple_trait, unboxed_closures, - fn_traits, - allocator_api, - type_alias_impl_trait, decl_macro, duration_millis_float, anonymous_lifetime_in_impl_trait, try_blocks_heterogeneous, current_thread_id, vec_try_remove, - iter_next_chunk, - iter_array_chunks, lazy_type_alias, const_convert, const_result_trait_fn, thread_local, - result_option_map_or_default, iter_intersperse, stmt_expr_attributes, - new_range_api, iter_collect_into, - mpmc_channel, - const_cmp, super_let, gen_blocks, - const_default, coroutines, iter_from_coroutine, coroutine_trait, - cell_get_cloned, import_trait_associated_functions, deref_patterns, generic_const_exprs, const_trait_impl, try_blocks, - portable_simd )] #![allow(incomplete_features, irrefutable_let_patterns, static_mut_refs)] mod act; @@ -231,8 +217,8 @@ pub(crate) fn entry(event_loop: EventLoop) { // let before = ed.state.name(); ed.poll(); // println!("{before} -> poll -> {}", ed.state.name()); - // let before = ed.state.name(); - // let ev = format!("{event:?}"); + let before = ed.state.name(); + let ev = format!("{event:?}"); // use WindowEvent as Event; match event { // Event::AboutToWait => {} @@ -20,6 +20,7 @@ use winit::window::{ImeRequestData, Window}; use crate::edi::st::State; use crate::edi::{Editor, lsp}; use crate::gotolist::{At, GoTo}; +use crate::hov::Hovr; use crate::lsp::Rq; use crate::sym::UsedSI; use crate::text::{CoerceOption, RopeExt, col, color_}; @@ -181,7 +182,7 @@ pub fn render( x.style.fg = col!("#FFD173"); }); } } - if let Some(crate::hov::Hovr{ range:Some(r),..} ) = &ed.requests.hovering.result { + if let State::Hovering(Rq{ result: Some(crate::hov::Hovr{ range:Some(r),..} ), ..}) = &ed.state { x.get_range(text.map_to_visual((r.start.character as _, r.start.line as _)), text.map_to_visual((r.end.character as usize, r.end.line as _))) .for_each(|x| { @@ -653,8 +654,11 @@ pub fn render( ); } }; - ed.requests.hovering.result.as_ref().filter(|_| pass).map(|x| { - x.span.clone().map(|[(_x, _y), (_x2, _)]| { + if let State::Hovering(Rq { result: Some(x@Hovr { span: Some([(_x, _y,), (_x2, _)]),.. }), ..}, .. ) = &ed.state && pass { + + // } + // ed.requests.hovering.result.as_ref().filter(|_| pass).map(|x| { + // x.span.clone().map(|[(_x, _y), (_x2, _)]| { // let [(_x, _y), (_x2, _)] = text.position(sp); // dbg!(x..=x2, cursor_position.0) // if !(_x..=_x2).contains(&&(cursor_position.0 .wrapping_sub( text.line_number_offset()+1))) { @@ -662,7 +666,7 @@ pub fn render( // } let [_x, _x2] = - [_x, _x2].add(text.line_number_offset() + 1); + [*_x, *_x2].add(text.line_number_offset() + 1); let Some(_y) = _y.checked_sub(text.vo) else { return; }; @@ -699,8 +703,7 @@ pub fn render( h as _, BORDER, ); - }) - }); + } let mut drawb = |cells, c| { // let ws = ed.workspace.as_deref().unwrap(); // let (_x, _y) = text.cursor_visual(); diff --git a/src/runnables.rs b/src/runnables.rs index a373881..62261f9 100644 --- a/src/runnables.rs +++ b/src/runnables.rs @@ -41,13 +41,13 @@ impl MenuData for Runb { let d: Cell = Cell { letter: None, style: ds }; let mut b = vec![d; columns]; const MAP: [([u8; 3], [u8; 3], &str); 70] = { - car::map!( + ( amap::amap! { const { RunnableKind::Cargo as usize } => ("#9a9b9a", " "), const { RunnableKind::Shell as usize } => ("#FFAD66", "$ "), _ => ("#9a9b9a", " "), - }, - |(x, y)| (set_a(color_(x), 0.5), color_(x), y) + }).map(const + |(x, y)| (set_a(color_(x), 0.5), color_(x), y), ) }; let (bgt, col, ty) = MAP[x.kind.clone() as usize]; @@ -195,7 +195,7 @@ fn r<'a>( let d: Cell = Cell { letter: None, style: ds }; let mut b = vec![d; c]; const MAP: [([u8; 3], [u8; 3], &str); 85] = { - car::map!( + ( amap::amap! { const { SymbolKind::FILE.0 as usize } => ("#9a9b9a", " "), const { SymbolKind::METHOD.0 as usize } | const { SymbolKind::FUNCTION.0 as usize } => ("#FFD173", "λ "), @@ -220,8 +220,9 @@ fn r<'a>( const { SymbolKind::PROC_MACRO.0 as usize } => ("#f28f74", "r!"), const { SymbolKind::BOOKMARK.0 as usize } => ("#73D0FF", " "), _ => ("#9a9b9a", " ") - }, - |(x, y)| (set_a(color_(x), 0.5), color_(x), y) + }) + .map( + const |(x, y)| (set_a(color_(x), 0.5), color_(x), y), ) }; let (bgt, col, ty) = MAP[x.kind.0 as usize]; diff --git a/src/text.rs b/src/text.rs index bc4da13..2ab60dc 100644 --- a/src/text.rs +++ b/src/text.rs @@ -52,12 +52,8 @@ pub const fn color_(x: &str) -> [u8; 3] { }; color(&x) } -pub const fn set_a([a, b, c]: [u8; 3], to: f32) -> [u8; 3] { - [ - (((a as f32 / 255.0) * to) * 255.0) as u8, - (((b as f32 / 255.0) * to) * 255.0) as u8, - (((c as f32 / 255.0) * to) * 255.0) as u8, - ] +pub const fn set_a(x: [u8; 3], to: f32) -> [u8; 3] { + x.map(const |x| (((x as f32 / 255.0) * to) * 255.0) as u8) } pub const fn color<const N: usize>(x: &[u8; N]) -> [u8; (N - 1) / 2] where @@ -65,8 +61,8 @@ where [(); (N - 1) % 2 + usize::MAX]:, { let x = x.tail(); - let parse = car::map!(x, |b| (b & 0xF) + 9 * (b >> 6)).chunked::<2>(); - car::map!(parse, |[a, b]| a * 16 + b) + let parse = x.map(const |b| (b & 0xF) + 9 * (b >> 6)).chunked::<2>(); + parse.map(const |[a, b]| a * 16 + b) } macro_rules! col { diff --git a/src/text/semantic_tokens/theme.rs b/src/text/semantic_tokens/theme.rs index 6be578c..f716f3d 100644 --- a/src/text/semantic_tokens/theme.rs +++ b/src/text/semantic_tokens/theme.rs @@ -5,7 +5,7 @@ macro_rules! theme { #[rustfmt::skip] pub const NAMES: [&str; [$($x),+].len()] = [$($x),+]; #[rustfmt::skip] - pub const COLORS: [[u8; 3]; NAMES.len()] = car::map!([$($color),+], |x| crate::text::color(x)); + pub const COLORS: [[u8; 3]; NAMES.len()] = ([$($color),+]).map(const |x| crate::text::color(x)); pub const STYLES: [u8; NAMES.len()] = [$( ($($style, )? 0, ).0 ),+]; @@ -17,7 +17,7 @@ macro_rules! modified { pub const MODIFIED: [(&str, &str); $count] = [ $(($x, $mod),)+ ]; - pub const MCOLORS: [[u8;3]; MODIFIED.len()] = car::map!([$($color),+], |x| crate::text::color(x)); + pub const MCOLORS: [[u8;3]; MODIFIED.len()] = ([$($color),+]).map(const |x| crate::text::color(x)); pub const MSTYLE: [u8; MODIFIED.len()] = [$(($($style, )? 0, ).0 ,)+]; } } |