A simple CPU rendered GUI IDE experience.
onEnter
| -rw-r--r-- | src/lsp.rs | 31 | ||||
| -rw-r--r-- | src/main.rs | 24 | ||||
| -rw-r--r-- | src/text.rs | 15 |
3 files changed, 50 insertions, 20 deletions
@@ -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) |