A simple CPU rendered GUI IDE experience.
im not sure if it'll work but its worth a shot
| -rw-r--r-- | src/edi/input_handlers/click.rs | 12 | ||||
| -rw-r--r-- | src/edi/input_handlers/keyboard.rs | 48 | ||||
| -rw-r--r-- | src/edi/st.rs | 1 | ||||
| -rw-r--r-- | src/rnd.rs | 208 | ||||
| -rw-r--r-- | src/text.rs | 8 |
5 files changed, 159 insertions, 118 deletions
diff --git a/src/edi/input_handlers/click.rs b/src/edi/input_handlers/click.rs index 0998d46..692be1a 100644 --- a/src/edi/input_handlers/click.rs +++ b/src/edi/input_handlers/click.rs @@ -33,21 +33,11 @@ impl Editor { ), )); } - self.requests.document_highlights.request( - lsp.runtime.spawn( - lsp.document_highlights( - path, - text.to_l_position( - text.cursor.first().position, - ) - .unwrap(), - ), - ), - ); } self.hist.lc = text.cursor.clone(); self.chist.push(text.primary_cursor()); text.cursor.first().setc(&text.rope); + self.refresh_document_highlights(); } Some(Do::NavForward) => self.nav_forward(), Some(Do::NavBack) => self.nav_back(), diff --git a/src/edi/input_handlers/keyboard.rs b/src/edi/input_handlers/keyboard.rs index f9c8ee6..a2c76f8 100644 --- a/src/edi/input_handlers/keyboard.rs +++ b/src/edi/input_handlers/keyboard.rs @@ -12,6 +12,7 @@ use ropey::Rope; use rust_analyzer::lsp::ext::OnTypeFormatting; use rust_fsm::StateMachine; use tokio_util::task::AbortOnDropHandle as DropH; +use ttools::{IteratorOfTuples, IteratorOfTuplesWithF, fns, hrf}; use winit::event::KeyEvent; use winit::keyboard::Key; use winit::window::Window; @@ -274,6 +275,40 @@ impl Editor { }; c.up(); } + Some(Do::GoToMatch) + if let Some(x) = + &self.requests.document_highlights.result => + { + let lc = &self + .text + .cursor + .iter() + .max_by_key(|x| x.position) + .unwrap(); + let n = x + .iter() + .zip(0..) + .filter_map_at::<0>(|x| self.text.l_range(x.range)) + .filter_on::<0>(hrf(|x: &std::ops::Range<usize>| { + x.contains(lc) + })) + .max_by_key(|x| x.0.start) + .unwrap() + .1; + + let p = self + .text + .l_position(x[(n + 1) % x.len()].range.start) + .unwrap(); + self.text.scroll_to(p); + if !self.text.cursor.iter().any(|x| *x == p) { + self.text.cursor.add(p, &self.text.rope); + } + } + Some(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( @@ -792,4 +827,17 @@ impl Editor { self.state = State::CodeAction(Rq::new(lsp.runtime.spawn(r))); } + pub fn refresh_document_highlights(&mut self) { + lsp!(let lsp, path = self); + self.requests.document_highlights.request( + lsp.runtime.spawn( + lsp.document_highlights( + path, + self.text + .to_l_position(self.text.cursor.first().position) + .unwrap(), + ), + ), + ); + } } diff --git a/src/edi/st.rs b/src/edi/st.rs index cf6c243..859ce4f 100644 --- a/src/edi/st.rs +++ b/src/edi/st.rs @@ -43,6 +43,7 @@ Default => { K(Key::Character("q") if ctrl()) => Dead [Quit], K(Key::Character("v") if ctrl()) => _ [Paste], K(Key::Character("z") if ctrl()) => _ [Undo], + K(Key::Character("d") if ctrl()) => _ [GoToMatch], K(Key::Character("y") if ctrl()) => _ [Redo], K(Key::Character("f") if ctrl()) => Procure((default(), InputRequest::Search)), K(Key::Character("o") if ctrl()) => Procure((default(), InputRequest::OpenFile)), @@ -4,6 +4,7 @@ use std::sync::{Arc, LazyLock}; use std::time::Instant; use atools::prelude::*; +pub use cell_buffer::CellBuffer; use dsb::Cell; use dsb::cell::Style; use fimg::pixels::Blend; @@ -20,16 +21,14 @@ use crate::edi::st::State; use crate::edi::{Editor, lsp}; use crate::gotolist::{At, GoTo}; use crate::lsp::Rq; -use crate::sym::{UsedSI}; +use crate::sym::UsedSI; use crate::text::{CoerceOption, RopeExt, col, color_}; use crate::{ BG, BORDER, CompletionAction, CompletionState, FG, FONT, complete, filter, lsp, sig, }; -pub use cell_buffer::CellBuffer; mod cell_buffer; - #[implicit_fn::implicit_fn] pub fn render( ed: &mut Editor, @@ -84,10 +83,12 @@ pub fn render( style: Style { fg: BG, secondary_color: BG, bg: BG, flags: 0 }, letter: None, }); - let bmks = text.bookmarks .iter().filter_map(|x| { - text.try_char_to_line(x.position).ok() - }).collect::<Vec<_>>(); - + let bmks = text + .bookmarks + .iter() + .filter_map(|x| text.try_char_to_line(x.position).ok()) + .collect::<Vec<_>>(); + let z = match &ed.state { State::Selection => Some( text.cursor @@ -98,7 +99,7 @@ pub fn render( ), _ => None, }; - + text.line_numbers( (c, r - 1), [67, 76, 87], @@ -107,17 +108,20 @@ pub fn render( (1, 0), |_text, mut f, y| { if let State::GoToL(menu) = &ed.state - && let Some(Ok(( GoTo{ at: At::R(r),path}, _))) = menu.sel() + && let Some(Ok((GoTo { at: At::R(r), path }, _))) = + menu.sel() && Some(&*path) == ed.origin.as_deref() - { + { if (r.start.line..=r.end.line).contains(&(y as _)) { f.style.fg = col!("#FFCC66"); } } if let State::Symbols(Rq { result: Some(menu), .. }) = &ed.state - && let Some(Ok(UsedSI { at: GoTo{ at: At::R(x),..}, .. })) = - menu.sel() + && let Some(Ok(UsedSI { + at: GoTo { at: At::R(x), .. }, + .. + })) = menu.sel() { if (x.start.line..=x.end.line).contains(&(y as _)) { f.style.fg = col!("#FFCC66"); @@ -553,100 +557,96 @@ pub fn render( &lsp.diagnostics.guard(), ) { - let dawg = diag.iter().filter(|diag| { - text.l_range(diag.range).is_some_and(|x| { - x.contains(&text.mapped_index_at(cursor_position)) - && (text.vo..text.vo + r) - .contains(&(diag.range.start.line as _)) - }) - }); - for diag in dawg { - match diag - .data - .as_ref() - .unwrap_or_default() - .get("rendered") + 'out: { + let dawgs = diag.iter().filter(|diag| { + text.l_range(diag.range).is_some_and(|x| { + x.contains(&text.mapped_index_at(cursor_position)) + && (text.vo..text.vo + r) + .contains(&(diag.range.start.line as _)) + }) + }); + let Some(diag) = dawgs.clone().next() else { break 'out }; + let dawg = dawgs + .filter_map(|x| { + x.data + .as_ref() + .unwrap_or_default() + .get("rendered") + .and_then(serde_json::Value::as_str) + }) + .collect::<String>(); + + let mut t = pattypan::term::Terminal::new( + (95, (r.saturating_sub(5)) as _), + false, + ); + for b in simplify_path( + &dawg.replace('\n', "\r\n").replace("⸬", ":"), + ) + .bytes() { - Some(x) if let Some(x) = x.as_str() => { - let mut t = pattypan::term::Terminal::new( - (95, (r.saturating_sub(5)) as _), - false, - ); - for b in simplify_path( - &x.replace('\n', "\r\n").replace("⸬", ":"), - ) - .bytes() - { - t.rx( - b, - std::fs::File::open("/dev/null") - .unwrap() - .as_fd(), - ); - } - let y_lim = t - .cells - .rows() - .position(|x| x.iter().all(_.letter.is_none())) - .unwrap_or(20); - let c = t.cells.c() as usize; - let Some(x_lim) = t - .cells - .rows() - .map( - _.iter() - .rev() - .take_while(_.letter.is_none()) - .count(), - ) - .map(|x| c - x) - .max() - else { - continue; - }; - let n = t - .cells - .rows() - .take(y_lim) - .flat_map(|x| &x[..x_lim]) - .copied() - .collect::<Vec<_>>(); - let Ok((_, left, top, w, h)) = place_around( - { - let (x, y) = text.map_to_visual(( - diag.range.start.character as _, - diag.range.start.line as usize, - )); - ( - x + text.line_number_offset() + 1, - y - text.vo, - ) - }, - i.copy(), - &*n, - x_lim, - 17.0, - 0., - 0., - 0., - 0., - true, - ) else { - continue; - }; - pass = false; - i.r#box( - ( - left.saturating_sub(1) as _, - top.saturating_sub(1) as _, - ), - w as _, - h as _, - BORDER, - ); - } - _ => {} + t.rx( + b, + std::fs::File::open("/dev/null").unwrap().as_fd(), + ); } + let y_lim = t + .cells + .rows() + .position(|x| x.iter().all(_.letter.is_none())) + .unwrap_or(20); + let c = t.cells.c() as usize; + let Some(x_lim) = t + .cells + .rows() + .map( + _.iter() + .rev() + .take_while(_.letter.is_none()) + .count(), + ) + .map(|x| c - x) + .max() + else { + break 'out; + }; + let n = t + .cells + .rows() + .take(y_lim) + .flat_map(|x| &x[..x_lim]) + .copied() + .collect::<Vec<_>>(); + let Ok((_, left, top, w, h)) = place_around( + { + let (x, y) = text.map_to_visual(( + diag.range.start.character as _, + diag.range.start.line as usize, + )); + (x + text.line_number_offset() + 1, y - text.vo) + }, + i.copy(), + &*n, + x_lim, + 17.0, + 0., + 0., + 0., + 0., + true, + ) else { + break 'out; + }; + pass = false; + i.r#box( + ( + left.saturating_sub(1) as _, + top.saturating_sub(1) as _, + ), + w as _, + h as _, + BORDER, + ); } }; ed.requests.hovering.result.as_ref().filter(|_| pass).map(|x| { diff --git a/src/text.rs b/src/text.rs index 912feae..a38ddb2 100644 --- a/src/text.rs +++ b/src/text.rs @@ -727,10 +727,12 @@ impl TextArea { self.set_ho(); } } - - #[lower::apply(saturating)] pub fn scroll_to_cursor(&mut self) { - let (_, y) = self.primary_cursor(); + self.scroll_to(*self.cursor.first()); + } + #[lower::apply(saturating)] + pub fn scroll_to(&mut self, c: usize) { + let y = self.y(c).unwrap(); if !(self.vo..self.vo + self.r).contains(&y) { if self.vo > y { |