A simple CPU rendered GUI IDE experience.
onEnter
bendn 8 weeks ago
parent c664558 · commit 51a5832
-rw-r--r--src/lsp.rs31
-rw-r--r--src/main.rs24
-rw-r--r--src/text.rs15
3 files changed, 50 insertions, 20 deletions
diff --git a/src/lsp.rs b/src/lsp.rs
index d71c689..3ba8e6e 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -50,7 +50,6 @@ impl Drop for Client {
panic!("please dont")
}
}
-#[derive(Debug)]
pub enum RequestError<X> {
Rx(PhantomData<X>),
Failure(Re, Backtrace),
@@ -139,9 +138,11 @@ impl Client {
}
} else {
Ok(serde_json::from_value::<X::Result>(
- x.result.unwrap_or_default(),
+ x.result.clone().unwrap_or_default(),
)
- .expect("lsp badg"))
+ .unwrap_or_else(|_| {
+ panic!("lsp failure for {x:?}\ndidnt follow spec for {}\npossibly spec issue", X::METHOD)
+ }))
}
},
id,
@@ -467,6 +468,21 @@ impl Client {
Ok(())
}
+
+ pub fn enter<'a>(&self, f: &Path, t: &'a mut TextArea) {
+ let r = self.runtime.block_on(self.request::<lsp_request!("experimental/onEnter")>(&TextDocumentPositionParams {
+ text_document: f.tid(),
+ position: t.to_l_position(t.cursor).unwrap(),
+ }).unwrap().0).unwrap();
+ match r {
+ None => t.enter(),
+ Some(r) => {
+ for f in r {
+ t.apply_snippet_tedit(&f).unwrap();
+ }
+ }
+ }
+ }
}
pub fn run(
(tx, rx): (Sender<Message>, Receiver<Message>),
@@ -677,6 +693,7 @@ pub fn run(
"serverStatusNotification": true,
"hoverActions": true,
"workspaceSymbolScopeKindFiltering": true,
+ "onEnter": true,
}}),
..default()
},
@@ -951,7 +968,7 @@ impl<T, U, F: FnMut(T) -> U, Fu: Future<Output = T>> Map_<T, U, F> for Fu {
}
use tokio::task;
-use crate::text::TextArea;
+use crate::text::{CoerceOption, TextArea};
#[derive(Debug)]
pub enum OnceOff<T> {
Waiting(task::JoinHandle<Result<T, oneshot::error::RecvError>>),
@@ -972,6 +989,12 @@ impl<T> OnceOff<T> {
}
}
+impl<R:Request> std::fmt::Debug for RequestError<R> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(&self, f)
+ }
+}
+
#[derive(Debug)]
pub struct Rq<T, R, D = (), E = RequestError<R>> {
pub result: Option<T>,
diff --git a/src/main.rs b/src/main.rs
index 362762b..93d43f6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -75,7 +75,7 @@ use winit::window::Icon;
use crate::bar::Bar;
use crate::hov::Hovr;
-use crate::lsp::{RedrawAfter, RequestError, RqS};
+use crate::lsp::{Client, RedrawAfter, RequestError, RqS};
use crate::sym::Symbols;
use crate::text::{Diff, Mapping, TextArea, col, is_word};
mod bar;
@@ -1265,7 +1265,7 @@ hovering.request = (DropH::new(handle), cursor_position).into();
if let Some(lsp) = lsp {
let State::Symbols(Rq { result :Some(x), request}) = &mut state else {unreachable!()};
let ptedit = x.tedit.rope.clone();
- if handle2(&event.logical_key, &mut x.tedit).is_some() || ptedit != x.tedit.rope {
+ if handle2(&event.logical_key, &mut x.tedit, lsp!()).is_some() || ptedit != x.tedit.rope {
*request = Some((DropH::new(lsp.runtime.spawn(window.redraw_after(lsp.symbols(x.tedit.rope.to_string())))), ()));
// state = State::Symbols(Rq::new(lsp.runtime.spawn(lsp.symbols("".into()))));
}
@@ -1351,15 +1351,8 @@ hovering.request = (DropH::new(handle), cursor_position).into();
).unwrap();
let mut f_ = |edits: &[SnippetTextEdit]|{
// let mut first = false;
- for SnippetTextEdit { text_edit, insert_text_format ,..}in edits {
- match insert_text_format {
- Some(InsertTextFormat::SNIPPET) => {
- text.apply_snippet(&text_edit).unwrap()
- },
- _ => {
- text.apply_adjusting(text_edit).unwrap();
- }
- }
+ for edit in edits {
+ text.apply_snippet_tedit(edit).unwrap();
}
};
match act.edit {
@@ -1427,7 +1420,7 @@ hovering.request = (DropH::new(handle), cursor_position).into();
let cb4 = text.cursor;
if let Key::Named(Enter | ArrowUp | ArrowDown | Tab) = event.logical_key && let CompletionState::Complete(..) = complete{
} else {
- handle2(&event.logical_key, &mut text);
+ handle2(&event.logical_key, &mut text, lsp!());
}
text.scroll_to_cursor();
inlay!();
@@ -1646,7 +1639,7 @@ hovering.request = (DropH::new(handle), cursor_position).into();
winit_app::run_app(event_loop, app);
}
-fn handle2<'a>(key: &'a Key, text: &mut TextArea) -> Option<&'a str> {
+fn handle2<'a>(key: &'a Key, text: &mut TextArea, l: Option<(&Client, &Path)>) -> Option<&'a str> {
use Key::*;
match key {
@@ -1676,6 +1669,7 @@ fn handle2<'a>(key: &'a Key, text: &mut TextArea) -> Option<&'a str> {
Named(ArrowDown) => text.down(),
Named(PageDown) => text.page_down(),
Named(PageUp) => text.page_up(),
+ Named(Enter) if let Some((l, p)) = l => l.enter(p, text),
Named(Enter) => text.enter(),
Character(x) => {
text.insert(&x);
@@ -1685,8 +1679,8 @@ fn handle2<'a>(key: &'a Key, text: &mut TextArea) -> Option<&'a str> {
};
None
}
-fn handle(key: Key, mut text: TextArea) -> TextArea {
- handle2(&key, &mut text);
+fn handle(key: Key, mut text: TextArea,) -> TextArea {
+ handle2(&key, &mut text,None);
text
}
pub static FONT: LazyLock<FontRef<'static>> = LazyLock::new(|| {
diff --git a/src/text.rs b/src/text.rs
index 8dec0ae..a2547b9 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -18,7 +18,7 @@ use itertools::Itertools;
use log::error;
use lsp_types::{
InlayHint, InlayHintLabel, Location, Position, SemanticToken,
- SemanticTokensLegend, TextEdit,
+ SemanticTokensLegend, SnippetTextEdit, TextEdit,
};
use ropey::{Rope, RopeSlice};
use tree_house::Language;
@@ -495,6 +495,19 @@ impl TextArea {
}
Ok(())
}
+ pub fn apply_snippet_tedit(
+ &mut self,
+ SnippetTextEdit { text_edit, insert_text_format, .. }: &SnippetTextEdit,
+ ) -> anyhow::Result<()> {
+ match insert_text_format {
+ Some(lsp_types::InsertTextFormat::SNIPPET) =>
+ self.apply_snippet(&text_edit).unwrap(),
+ _ => {
+ self.apply_adjusting(text_edit).unwrap();
+ }
+ }
+ Ok(())
+ }
pub fn apply_snippet(&mut self, x: &TextEdit) -> anyhow::Result<()> {
let begin = self
.l_position(x.range.start)