A simple CPU rendered GUI IDE experience.
minor changes
| -rw-r--r-- | src/lsp.rs | 5 | ||||
| -rw-r--r-- | src/main.rs | 27 | ||||
| -rw-r--r-- | src/text.rs | 43 |
3 files changed, 40 insertions, 35 deletions
@@ -596,11 +596,6 @@ pub fn run( "genericParameterHints": { "type": { "enable": true } }, "rangeExclusiveHints": { "enable": true }, "closureCaptureHints": { "enable": true }, - "expressionAdjustmentHints": { - "hideOutsideUnsafe": true, - "enable": "reborrow", - "mode": "prefer_prefix" - } }, "checkOnSave": true, "diagnostics": { "enable": true }, diff --git a/src/main.rs b/src/main.rs index 084ec66..a9227e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ iter_next_chunk, iter_array_chunks, array_windows, - str_as_str, lazy_type_alias, const_convert, const_result_trait_fn, @@ -497,7 +496,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { once((diag.range, &*diag.message, sev_)).chain(diag.related_information.iter().flatten().filter(|sp| sp.location.uri == uri).map(move |x| { (x.location.range, &*x.message, EType::Related(sev)) })) - }).for_each(|(mut r, m, sev)| { + }).for_each(|(mut r, m, sev)| _ = try { let p = r.start.line; while occupied.contains(&r.start.line) { r.start.line+=1; @@ -512,10 +511,10 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { }); }; if r.start == r.end { - x.get(text.map_to_visual((r.start.character as _, p as _)).unwrap()).map(f); + x.get(text.map_to_visual((r.start.character as _, p as _))?).map(f); } else { - x.get_range(text.map_to_visual((r.start.character as _, p as _)).unwrap(), - text.map_to_visual((r.end.character as usize, r.end.line as _)).unwrap()) + x.get_range(text.map_to_visual((r.start.character as _, p as _))?, + text.map_to_visual((r.end.character as usize, r.end.line as _))?) .for_each(f) } let l = r.start.line as usize; @@ -607,6 +606,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { (((_x) as f32 * fw).round() + ox) as usize, (((_y) as f32 * (fh + ls * fac)).round() + oy) as usize, ); + dbg!(position); assert!(position.0 < 8000 && position.1 < 8000, "{position:?} {_x} {_y}"); let ppem = ppem_; let ls = ls_; @@ -639,11 +639,11 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { }; let mut pass = true; if let Some((lsp, p)) = lsp!() && let Some(diag) = lsp.diagnostics.get(&Url::from_file_path(p).unwrap(), &lsp.diagnostics.guard()) { - let dawg = diag.iter().filter(|diag| text.l_range(diag.range).is_ok_and(|x| x.contains(&text.mapped_index_at(cursor_position)) && (text.vo..text.vo+r).contains(&(diag.range.start.line as _)))); + let dawg = diag.iter().filter(|diag| text.l_range(diag.range).is_some_and(|x| x.contains(&text.mapped_index_at(cursor_position)) && (text.vo..text.vo+r).contains(&(diag.range.start.line as _)))); for diag in dawg { match diag.data.as_ref().unwrap_or_default().get("rendered") { - Some(x) if let Some(x) = x.as_str() => { - let mut t = pattypan::term::Terminal::new((90, 20), false); + Some(x) if let Some(x) = x.as_str() => { _ = try { + let mut t = pattypan::term::Terminal::new((90, (r.saturating_sub(5)) as _), false); for b in x.replace('\n', "\r\n").bytes(){ t.rx(b,std::fs::File::open("/dev/null").unwrap().as_fd()); } let y_lim = t.cells.rows().position(|x| x.iter().all(_.letter.is_none())).unwrap_or(20); let c =t.cells.c() as usize; @@ -652,16 +652,15 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { let n = t.cells.rows().take(y_lim).flat_map(|x| &x[..x_lim]).copied().collect::<Vec<_>>(); let (_,left, top, w, h) = place_around_cursor( text.map_to_visual((diag.range.start.character as _, diag.range.start.line as usize)) - .map(|(x, y)| (x + text.line_number_offset() + 1, y - text.vo)) - .unwrap_or((diag.range.start.character as _, diag.range.start.line as usize - text.vo)), + .map(|(x, y)| (x + text.line_number_offset() + 1, y - text.vo))?, &mut fonts, i.as_mut(), &n, x_lim, - 17.0, -400., 0., 0., 0. + 17.0, 0., 0., 0., 0. ); pass=false; i.r#box((left .saturating_sub(1) as _, top.saturating_sub(1) as _), w as _,h as _, BORDER); - }, + } }, _ => {} } } @@ -1293,7 +1292,7 @@ fn handle2<'a>(key: &'a Key, text: &mut TextArea) -> Option<&'a str> { } Named(End) if ctrl() => { text.cursor = text.rope.len_chars(); - text.vo = text.l() - text.r; + text.vo = text.l().saturating_sub(text.r); } Named(Home) => text.home(), Named(End) => text.end(), @@ -1524,7 +1523,7 @@ impl Default for CompletionState { } } fn filter(text: &TextArea) -> String { - if matches!(text.rope.get_char(text.cursor - 1), Some('.' | ':')) { + if text.cursor.checked_sub(1).is_none_or(|x| matches!(text.rope.get_char(x), Some('.' | ':'))) { "".to_string() } else { text.rope diff --git a/src/text.rs b/src/text.rs index 43cb8d6..d17676c 100644 --- a/src/text.rs +++ b/src/text.rs @@ -318,6 +318,13 @@ 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, @@ -387,6 +394,7 @@ impl TextArea { } /// or eof + #[lower::apply(saturating)] pub fn eol(&self, li: usize) -> usize { self.rope .try_line_to_char(li) @@ -451,16 +459,20 @@ impl TextArea { self.set_ho(); } - pub fn apply(&mut self, x: &TextEdit) -> Result<(), ropey::Error> { - let begin = self.l_position(x.range.start)?; - let end = self.l_position(x.range.end)?; - self.rope.try_remove(begin..end)?; - self.rope.try_insert(begin, &x.new_text)?; + pub fn apply(&mut self, x: &TextEdit) -> Result<(), ()> { + let begin = self.l_position(x.range.start).ok_or(())?; + let end = self.l_position(x.range.end).ok_or(())?; + self.rope.try_remove(begin..end).map_err(|_| ())?; + self.rope.try_insert(begin, &x.new_text).map_err(|_| ())?; Ok(()) } pub fn apply_snippet(&mut self, x: &TextEdit) -> anyhow::Result<()> { - let begin = self.l_position(x.range.start)?; - let end = self.l_position(x.range.end)?; + let begin = self + .l_position(x.range.start) + .ok_or(anyhow!("couldnt get start"))?; + let end = self + .l_position(x.range.end) + .ok_or(anyhow!("couldnt get end"))?; self.rope.try_remove(begin..end)?; let (mut sni, tex) = crate::sni::Snippet::parse(&x.new_text, begin) @@ -861,19 +873,18 @@ impl TextArea { &mut cell[y1 * c + x1..y2 * c + x2] } - pub fn l_position(&self, p: Position) -> Result<usize, ropey::Error> { - Ok(self.rope.try_line_to_char(p.line as _)? - + (p.character as usize) - .min(self.rope.line(p.line as _).len_chars())) + 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()), + ) } pub fn to_l_position(&self, l: usize) -> lsp_types::Position { Position { line: self.y(l) as _, character: self.x(l) as _ } } - pub fn l_range( - &self, - r: lsp_types::Range, - ) -> Result<Range<usize>, ropey::Error> { - Ok(self.l_position(r.start)?..self.l_position(r.end)?) + 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 { |