A simple CPU rendered GUI IDE experience.
-rw-r--r--src/edi.rs3
-rw-r--r--src/edi/input_handlers/click.rs23
-rw-r--r--src/edi/input_handlers/keyboard.rs72
-rw-r--r--src/edi/st.rs6
-rw-r--r--src/lsp/client.rs12
-rw-r--r--src/lsp/communication.rs15
-rw-r--r--src/text.rs10
-rw-r--r--src/text/cursor.rs7
-rw-r--r--src/text/hist.rs2
9 files changed, 98 insertions, 52 deletions
diff --git a/src/edi.rs b/src/edi.rs
index fabe5d1..f2ef7b0 100644
--- a/src/edi.rs
+++ b/src/edi.rs
@@ -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();