A simple CPU rendered GUI IDE experience.
utf8
| -rw-r--r-- | src/lsp.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 11 | ||||
| -rw-r--r-- | src/text.rs | 54 |
3 files changed, 40 insertions, 27 deletions
@@ -339,7 +339,7 @@ impl Client { text_document: f.tid(), range: t.to_l_range(lower::saturating::math!{ t.rope.try_line_to_char(t.vo-t.r).unwrap_or(0)..t.rope.try_line_to_char(t.vo + t.r + t.r).unwrap_or(t.rope.len_chars()) - }) + }).unwrap() }).unwrap().0.map(|x| x.map(Option::unwrap_or_default)) // async { // if let Ok(z) = z.await { diff --git a/src/main.rs b/src/main.rs index c366a36..5f74618 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,8 +32,7 @@ )] #![allow(incomplete_features, redundant_semicolons)] use std::borrow::Cow; -use std::iter::{Take, once}; -use std::mem::transmute; +use std::iter::{once}; use std::num::NonZeroU32; use std::os::fd::AsFd; use std::path::{Path, PathBuf}; @@ -856,7 +855,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { let mut rang = None; let z = match hover { Mapping::Char(_, _, i) => { - TextDocumentPositionParams { position: text.to_l_position(i), text_document: o.tid() } + TextDocumentPositionParams { position: text.to_l_position(i).unwrap(), text_document: o.tid() } }, Mapping::Fake(mark, index, _) => { let Some(ref loc) = mark.l[index].1 else { @@ -906,8 +905,10 @@ let handle: tokio::task::JoinHandle<Result<Option<Hovr>, anyhow::Error>> = cl.ru (m, hov::markdown2(m, &x)) }).await.unwrap(); let span = rang.or_else(|| x.range.and_then(|range| try { - let x1 = text.reverse_source_map(range.start.line as _)?[range.start.character as usize]; - let x2 = text.reverse_source_map(range.end.line as _)?[range.end.character as usize]; + 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]; [(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 d17676c..d8e4787 100644 --- a/src/text.rs +++ b/src/text.rs @@ -135,7 +135,7 @@ mod semantic { // "unresolvedReference" b"#cccac2", } modified! { 2 - "function" . "library" b"#F28779", + "function" . "unsafe" b"#F28779", "variable" . "mutable" b"#e6dab6", } } @@ -318,13 +318,6 @@ impl TextArea { if i.padding_right == Some(true) { label.push((' ', None)); } - let mut i = i.clone(); - i.position.character = (self.rope.byte_to_char( - self.rope.line_to_byte(i.position.line as _) - + i.position.character as usize, - ) as usize - - self.rope.line_to_char(i.position.line as _)) - as _; Mark { start: self.l_position(i.position).unwrap(), ty: INLAY, @@ -508,13 +501,23 @@ impl TextArea { pub fn x(&self, c: usize) -> usize { self.xy(c).unwrap().0 } + // input: char, output: utf8 + pub fn x_bytes(&self, c: usize) -> Option<usize> { + let y = self.rope.try_char_to_line(c).ok()?; + let x = self + .rope + .try_char_to_byte(c) + .ok()? + .checked_sub(self.rope.try_line_to_byte(y).ok()?)?; + Some(x) + } pub fn y(&self, c: usize) -> usize { self.rope.char_to_line(c) } pub fn xy(&self, c: usize) -> Option<(usize, usize)> { let y = self.rope.try_char_to_line(c).ok()?; - let x = c - self.rope.try_line_to_char(y).ok()?; + let x = c.checked_sub(self.rope.try_line_to_char(y).ok()?)?; Some((x, y)) } @@ -873,24 +876,33 @@ impl TextArea { &mut cell[y1 * c + x1..y2 * c + x2] } + pub fn l_pos_to_char(&self, p: Position) -> Option<(usize, usize)> { + self.l_position(p).and_then(|x| self.xy(x)) + } + pub fn l_position(&self, p: Position) -> Option<usize> { - Some( - self.rope.try_line_to_char(p.line as _).ok()? - + (p.character as usize) - .min(self.rope.get_line(p.line as _)?.len_chars()), - ) + self.rope + .try_byte_to_char( + self.rope.try_line_to_byte(p.line as _).ok()? + + (p.character as usize) + .min(self.rope.get_line(p.line as _)?.len_bytes()), + ) + .ok() } - pub fn to_l_position(&self, l: usize) -> lsp_types::Position { - Position { line: self.y(l) as _, character: self.x(l) as _ } + pub fn to_l_position(&self, l: usize) -> Option<lsp_types::Position> { + Some(Position { + line: self.y(l) as _, + character: self.x_bytes(l)? as _, + }) } pub fn l_range(&self, r: lsp_types::Range) -> Option<Range<usize>> { Some(self.l_position(r.start)?..self.l_position(r.end)?) } - pub fn to_l_range(&self, r: Range<usize>) -> lsp_types::Range { - lsp_types::Range { - start: self.to_l_position(r.start), - end: self.to_l_position(r.end), - } + pub fn to_l_range(&self, r: Range<usize>) -> Option<lsp_types::Range> { + Some(lsp_types::Range { + start: self.to_l_position(r.start)?, + end: self.to_l_position(r.end)?, + }) } #[implicit_fn] |