A simple CPU rendered GUI IDE experience.
| -rw-r--r-- | src/edi.rs | 3 | ||||
| -rw-r--r-- | src/edi/input_handlers/click.rs | 23 | ||||
| -rw-r--r-- | src/edi/input_handlers/keyboard.rs | 72 | ||||
| -rw-r--r-- | src/edi/st.rs | 6 | ||||
| -rw-r--r-- | src/lsp/client.rs | 12 | ||||
| -rw-r--r-- | src/lsp/communication.rs | 15 | ||||
| -rw-r--r-- | src/text.rs | 10 | ||||
| -rw-r--r-- | src/text/cursor.rs | 7 | ||||
| -rw-r--r-- | src/text/hist.rs | 2 |
9 files changed, 98 insertions, 52 deletions
@@ -98,6 +98,7 @@ pub struct Editor { // pub git_diff: // Option<std::rc::Rc<std::cell::RefCell<imara_diff::Diff>>>, } + macro_rules! lsp { ($self:ident) => { $self.lsp.as_ref().map(|(x, ..)| *x) @@ -490,7 +491,7 @@ impl Editor { }); if unsafe { META.count } == self.text.cursor.iter().len() { for (piece, cursor) in - pieces.zip(0..self.text.cursor.iter().count()) + pieces.rev().zip(0..self.text.cursor.iter().count()) { let c = self.text.cursor.iter().nth(cursor).unwrap(); self.text.insert_at(*c, piece).unwrap(); diff --git a/src/edi/input_handlers/click.rs b/src/edi/input_handlers/click.rs index 4b0857d..d89552f 100644 --- a/src/edi/input_handlers/click.rs +++ b/src/edi/input_handlers/click.rs @@ -79,13 +79,22 @@ impl Editor { } } Do::InsertCursorAtMouse => { - text.cursor.add( - text.mapped_index_at(cursor_position), - &text.rope, - ); - self.hist.lc = text.cursor.clone(); - self.chist.push(text.primary_cursor()); - text.cursor.first().setc(&text.rope); + let p = text.mapped_index_at(cursor_position); + + let v = (text.cursor.inner.len() != 1) + .then(|| { + text.cursor + .inner + .extract_if(.., |x| *x == p) + .next() + }) + .flatten(); + if let None = v { + text.cursor.add(p, &text.rope); + self.hist.lc = text.cursor.clone(); + self.chist.push(text.primary_cursor()); + text.cursor.first().setc(&text.rope); + } } _ => unreachable!(), diff --git a/src/edi/input_handlers/keyboard.rs b/src/edi/input_handlers/keyboard.rs index 6001c60..e84f5c2 100644 --- a/src/edi/input_handlers/keyboard.rs +++ b/src/edi/input_handlers/keyboard.rs @@ -19,6 +19,7 @@ use winit::window::Window; use crate::Freq; use crate::edi::*; +use crate::lsp::acceptable_duration; impl Editor { pub fn keyboard( @@ -295,8 +296,10 @@ impl Editor { })) .max_by_key(|x| x.0.start) else { - self.bar.last_action = - "couldnt get symbol here".into(); + self.requests.document_highlights.result = None; + self.refresh_document_highlights(); + // self.bar.last_action = + // "couldnt get symbol here".into(); break 'out; }; if self.text.cursor.inner.len() == 1 @@ -540,17 +543,25 @@ impl Editor { } 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(), - } - .cursor(&self.text.rope); - let y = match dir { - Direction::Above => y - 1, - Direction::Below => y + 1, - }; - let position = self.text.line_to_char(y); - self.text.cursor.add(position + x, &self.text.rope); + self.text + .cursor + .inner + .iter() + .map(|cursor| { + let (x, y) = cursor.cursor(&self.text.rope); + let y = match dir { + Direction::Above => y - 1, + Direction::Below => y + 1, + }; + let position = self.text.line_to_char(y) + x; + position + }) + .filter(|&p| self.text.cursor.iter().all(|x| x != p)) + .collect::<Vec<_>>() + .into_iter() + .for_each(|x| { + self.text.cursor.add(x, &self.text.rope); + }); } Do::Run(x) => if let Some((l, ws)) = @@ -625,26 +636,23 @@ impl Editor { || t.iter().any(|y| y == x)) && self.text.cursor.inner.len() == 1 && change!(just self).is_some() - && let Ok(Some(mut x)) = l - .request_immediate::<OnTypeFormatting>( - &DocumentOnTypeFormattingParams { - text_document_position: - TextDocumentPositionParams { - text_document: p.tid(), - position: self - .text - .to_l_position( - *self.text.cursor.first(), - ) - .unwrap(), - }, - ch: x.into(), - options: FormattingOptions { - tab_size: 4, - ..default() - }, + && let Ok(Ok(Some(mut x))) = l.request_by::<OnTypeFormatting>( + &DocumentOnTypeFormattingParams { + text_document_position: TextDocumentPositionParams { + text_document: p.tid(), + position: self + .text + .to_l_position(*self.text.cursor.first()) + .unwrap(), }, - ) + ch: x.into(), + options: FormattingOptions { + tab_size: 4, + ..default() + }, + }, + acceptable_duration(), + ) { x.sort_tedits(); for x in x { diff --git a/src/edi/st.rs b/src/edi/st.rs index 673d652..efe6de9 100644 --- a/src/edi/st.rs +++ b/src/edi/st.rs @@ -78,6 +78,12 @@ Default => { K(_) => _ [Edit], M(_) => _, }, +// Matches(x) => { + // K(Key::Character("d") if ctrl()) => _ [GoToMatch], + // C(_) => Default [Reinsert], + // K(_) => Default [Reinsert], + // K(_) => Default [Reinsert], +// }, Hovered => { HOnSomething(((usize, usize)) => pos) => Hovering(Rq<Hovring, Option<Hovr>, ((usize, usize), TextDocumentPositionParams), RequestError<HoverRequest>> => default()) [SetHovering], HOnNothing => Default, diff --git a/src/lsp/client.rs b/src/lsp/client.rs index 9bc85b5..ff8d610 100644 --- a/src/lsp/client.rs +++ b/src/lsp/client.rs @@ -537,15 +537,17 @@ impl Client { ) -> rootcause::Result<()> { ceach!(t.cursor, |c| try bikeshed rootcause::Result<()> { let r = self - .request_immediate::<OnEnter>( + .request_by::<OnEnter>( &TextDocumentPositionParams { text_document: f.tid(), position: t.to_l_position(*c).unwrap(), }, + acceptable_duration(), ); match r { - Ok(None) | Err(_) => t.enter(), - Ok(Some(mut r)) => { + Ok(Ok(None)) | Err(_) | Ok(Err(_)) => { println!("hmm") ;t.enter() }, + Ok(Ok(Some(mut r))) => { + println!("applying"); r.sort_tedits(); for f in r { t.apply_snippet_tedit(&f)?; @@ -716,3 +718,7 @@ pub macro tdpp($e:expr) { position: $e.text.to_l_position(*$e.text.cursor.first()).unwrap(), } } + +pub fn acceptable_duration() -> tokio::time::Duration { + tokio::time::Duration::from_millis(50) +} diff --git a/src/lsp/communication.rs b/src/lsp/communication.rs index 7bc6b7c..30764a2 100644 --- a/src/lsp/communication.rs +++ b/src/lsp/communication.rs @@ -14,6 +14,7 @@ use lsp_types::notification::*; use lsp_types::request::*; use lsp_types::*; use tokio::sync::oneshot; +use tokio::time::error::Elapsed; use winit::window::Window; use crate::lsp::BehaviourAfter::{self, *}; @@ -148,6 +149,20 @@ impl super::Client { ) -> Result<X::Result, RequestError<X>> { self.runtime.block_on(self.request_::<X, { Nil }>(y)?.0) } + pub fn request_by<'me, X: Request>( + &'me self, + y: &X::Params, + d: tokio::time::Duration, + ) -> Result<Result<X::Result, RequestError<X>>, Elapsed> { + let _guard = self.runtime.enter(); + self.runtime.block_on(tokio::time::timeout( + d, + match self.request_::<X, { Nil }>(y) { + Err(e) => return Ok(Err(e.into())), + Ok((x, _)) => x, + }, + )) + } pub fn request<'me, X: Request>( &'me self, diff --git a/src/text.rs b/src/text.rs index 4c56712..dac9e52 100644 --- a/src/text.rs +++ b/src/text.rs @@ -275,16 +275,14 @@ impl TextArea { self.changes .inner .push(Action::Inserted { at: c, insert: with.to_string() }); + let cc = with.chars().count(); let manip = |x| { - if x < c { - Manip::Unmoved(x) - } else { - Manip::Moved(x + with.chars().count()) - } + if x < c { Manip::Unmoved(x) } else { Manip::Moved(x + cc) } }; self.tabstops.as_mut().map(|x| x.manipulate(manip)); self.cursor.manipulate(manip); self.bookmarks.manipulate(manip); + for m in self .inlays .range(Marking::idx(c as _)..) @@ -297,7 +295,7 @@ impl TextArea { std::collections::btree_set::Entry::Vacant(_) => unreachable!(), }; - m.position += with.chars().count() as u32; + m.position += cc as u32; self.inlays.insert(m); } self.tokens.iter_mut().for_each(|d| d.manip(manip)); diff --git a/src/text/cursor.rs b/src/text/cursor.rs index 32b33a7..2594ba5 100644 --- a/src/text/cursor.rs +++ b/src/text/cursor.rs @@ -93,8 +93,11 @@ pub fn caster<T, U>(x: impl FnMut(T) -> U) -> impl FnMut(T) -> U { } pub macro ceach($cursor: expr, $f:expr $( => $q:tt)?) { for i in (0..$cursor.inner.len()) { - let c = *$cursor.inner.get(i).expect("aw dangit"); - caster::<Cursor, _>($f)(c) $($q)?; + if let Some(&c) = $cursor.inner.get(i) { + caster::<Cursor, _>($f)(c) $($q)?; + } else { + log::error!("for some reason the number of cursors has changed."); + } } $cursor.coalesce(); } diff --git a/src/text/hist.rs b/src/text/hist.rs index 97a05c7..6edb771 100644 --- a/src/text/hist.rs +++ b/src/text/hist.rs @@ -197,7 +197,7 @@ impl Hist { let c = take(&mut x.changes); self.history.push(Diff(c, [take(&mut self.lc), x.cursor.clone()])); self.lc = x.cursor.clone(); - println!("push {}", self.history.last().unwrap()); + // println!("push {}", self.history.last().unwrap()); self.redo_history.clear(); take(&mut self.last); self.last_edit = Instant::now(); |