A simple CPU rendered GUI IDE experience.
scaffold & fix sizing issue
| -rw-r--r-- | src/lsp.rs | 9 | ||||
| -rw-r--r-- | src/main.rs | 15 | ||||
| -rw-r--r-- | src/text.rs | 58 |
3 files changed, 59 insertions, 23 deletions
@@ -355,6 +355,14 @@ impl Client { } } } + pub fn document_highlights(&'static self, f: &Path, cursor: Position) { + self.request::<lsp_request!("textDocument/documentHighlight")>(&DocumentHighlightParams { + text_document_position_params: TextDocumentPositionParams { text_document: f.tid(), position: cursor }, + + work_done_progress_params: default(), + partial_result_params: default(), + }).unwrap(); + } pub fn symbols( &'static self, f: String, @@ -545,6 +553,7 @@ pub fn run( ..default() }), text_document: Some(TextDocumentClientCapabilities { + document_highlight: Some(default()), formatting: Some(DynamicRegistrationClientCapabilities { dynamic_registration: Some(false) }), inlay_hint: Some(InlayHintClientCapabilities { dynamic_registration: None, resolve_support: Some(InlayHintResolveClientCapabilities { properties: vec!["textEdits".into(), "tooltip".into(), "label.tooltip".into(), "label.command".into()], }) diff --git a/src/main.rs b/src/main.rs index c3e262e..64f8eed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ // this looks pretty good though #![feature(tuple_trait, unboxed_closures, fn_traits)] #![feature( + anonymous_lifetime_in_impl_trait, try_blocks_heterogeneous, current_thread_id, vec_try_remove, @@ -757,8 +758,10 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { let (w, h) = dsb::size(&fonts.regular, ppem, ls, (columns, r)); // std::fs::write("cells", Cell::store(c)); - if w >= window.inner_size().width as usize - // || position.1 + h >= window.inner_size().height as usize + if w >= size.width as usize + || (position.1 + h >= size.height as usize && !position.1.checked_sub(h).is_some()) + || position.1 >= size.height as usize + || position.0 >= size.width as usize { unsafe { dsb::render_owned(c, (columns, c.len() / columns), ppem, fonts, ls, true).save("fail.png") }; return Err(()); @@ -1038,8 +1041,8 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { break 'out; }; let (x, y) = text.xy(abspos).unwrap(); - let Some(begin) = text.reverse_source_map(y) else { break 'out }; - let start = begin[x - 1] + 1; + let Some(mut begin) = text.reverse_source_map(y) else { break 'out }; + let start = begin.nth(x - 1).unwrap() + 1; let left = mark.l[..relpos].iter().rev().take_while(_.1.as_ref() == Some(loc)).count(); let start = start + relpos - left; let length = mark.l[relpos..].iter().take_while(_.1.as_ref() == Some(loc)).count() + left; @@ -1100,8 +1103,8 @@ let handle: tokio::task::JoinHandle<Result<Option<Hovr>, anyhow::Error>> = cl.ru let span = rang.or_else(|| x.range.and_then(|range| try { let (startx, starty) = text.l_pos_to_char(range.start)?; let (endx, endy) = text.l_pos_to_char(range.end)?; - let x1 = text.reverse_source_map(starty)?[startx]; - let x2 = text.reverse_source_map(endy)?[endx]; + let x1 = text.reverse_source_map(starty)?.nth(startx)?; + let x2 = text.reverse_source_map(endy)?.nth(endx)?; [(x1, range.start.line as _), (x2, range.start.line as _)] })); anyhow::Ok(Some( hov::Hovr { span, item: text::CellBuffer { c: w, vo: 0, cells: cells.into() }}.into())) diff --git a/src/text.rs b/src/text.rs index a2547b9..91c9a61 100644 --- a/src/text.rs +++ b/src/text.rs @@ -350,7 +350,7 @@ impl TextArea { pub fn map_to_visual(&self, (x, y): (usize, usize)) -> (usize, usize) { ( self.reverse_source_map(y) - .and_then(|v| v.get(x).copied()) + .and_then(|mut v| v.nth(x)) .unwrap_or(x), y, ) @@ -379,16 +379,25 @@ impl TextArea { } }) } - pub fn reverse_source_map(&'_ self, l: usize) -> Option<Vec<usize>> { - let mut to = vec![]; - let mut off = 0; - for elem in self.source_map(l)? { - match elem { - Mapping::Fake(..) => off += 1, - Mapping::Char(_, i, _) => to.push(i + off), + pub fn reverse_source_map_w( + &'_ self, + w: impl Iterator<Item = Mapping<'_>>, + ) -> Option<impl Iterator<Item = usize>> { + w.scan(0, |off, x| match x { + Mapping::Fake(..) => { + *off += 1; + Some(None) } - } - Some(to) + Mapping::Char(_, i, _) => Some(Some(i + *off)), + }) + .flatten() + .into() + } + pub fn reverse_source_map( + &'_ self, + l: usize, + ) -> Option<impl Iterator<Item = usize>> { + self.reverse_source_map_w(self.source_map(l)?) } pub fn visual_eol(&self, li: usize) -> Option<usize> { @@ -539,8 +548,8 @@ impl TextArea { } pub fn cursor_visual(&self) -> (usize, usize) { let (x, y) = self.cursor(); - let z = self.reverse_source_map(y).unwrap(); - (z.get(x).copied().unwrap_or(x), y) + let mut z = self.reverse_source_map(y).unwrap(); + (z.nth(x).unwrap_or(x), y) } pub fn visible_(&self) -> Range<usize> { self.rope.line_to_char(self.vo) @@ -1037,12 +1046,27 @@ impl TextArea { { let mut ln = 0; let mut ch = 0; + let mut src_map = + self.source_map(ln as _).coerce().collect::<Vec<_>>(); + let mut mapping = self + .reverse_source_map(ln as _) + .coerce() + .collect::<Vec<_>>(); + for t in t { + let pl = ln; ln += t.delta_line; - let src_map = - self.source_map(ln as _).coerce().collect::<Vec<_>>(); - let mapping = - self.reverse_source_map(ln as _).unwrap_or_default(); + if pl != ln { + src_map = self + .source_map(ln as _) + .coerce() + .collect::<Vec<_>>(); + mapping = self + .reverse_source_map_w(src_map.iter().cloned()) + .coerce() + .collect::<Vec<_>>(); + } + // dbg!( // &mapping, // self.source_map(ln as _).coerce().collect::<Vec<_>>(), @@ -1790,7 +1814,7 @@ impl<I: IntoIterator<Item = T>, T> CoerceOption<T> for Option<I> { } // #[test] pub(crate) use col; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum Mapping<'a> { Fake( &'a Mark, |