diff options
Diffstat (limited to 'helix-term/src')
-rw-r--r-- | helix-term/src/editor.rs | 70 | ||||
-rw-r--r-- | helix-term/src/theme.rs | 4 |
2 files changed, 53 insertions, 21 deletions
diff --git a/helix-term/src/editor.rs b/helix-term/src/editor.rs index 7352b142..ed2d3a13 100644 --- a/helix-term/src/editor.rs +++ b/helix-term/src/editor.rs @@ -80,6 +80,8 @@ impl Editor { } fn render(&mut self) { + use tui::backend::Backend; + use tui::style::Color; // TODO: ideally not mut but highlights require it because of cursor cache match &mut self.state { Some(state) => { @@ -87,9 +89,21 @@ impl Editor { let mut stdout = stdout(); self.surface.reset(); // reset is faster than allocating new empty surface + // clear with background color + self.surface + .set_style(area, self.theme.get("ui.background")); + + let offset = 5 + 1; // 5 linenr + 1 gutter + let viewport = Rect::new(offset, 0, self.size.0, self.size.1 - 1); // - 1 for statusline + // TODO: inefficient, should feed chunks.iter() to tree_sitter.parse_with(|offset, pos|) let source_code = state.doc().to_string(); + let last_line = std::cmp::min( + (self.first_line + viewport.height - 1) as usize, + state.doc().len_lines() - 1, + ); + // TODO: cache highlight results // TODO: only recalculate when state.doc is actually modified let highlights: Vec<_> = state @@ -102,12 +116,10 @@ impl Editor { let mut spans = Vec::new(); - let offset = 2; - let mut visual_x = 0; - let mut line = 0; + let mut line = 0u16; - for event in highlights { + 'outer: for event in highlights { match event.unwrap() { HighlightEvent::HighlightStart(span) => { spans.push(span); @@ -125,8 +137,6 @@ impl Editor { use helix_core::graphemes::{grapheme_width, RopeGraphemes}; - use tui::style::Color; - let style = match spans.first() { Some(span) => self.theme.get(self.theme.scopes()[span.0].as_str()), None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender @@ -143,6 +153,11 @@ impl Editor { if grapheme == "\n" { visual_x = 0; line += 1; + + // TODO: with proper iter this shouldn't be necessary + if line >= viewport.height { + break 'outer; + } } else { // Cow will prevent allocations if span contained in a single slice // which should really be the majority case @@ -163,7 +178,13 @@ impl Editor { } } - // + let mut line = 0; + let style = self.theme.get("ui.linenr"); + for i in self.first_line..(last_line as u16) { + self.surface + .set_stringn(0, line, format!("{:>5}", i + 1), 5, style); // lavender + line += 1; + } // let lines = state // .doc @@ -190,19 +211,23 @@ impl Editor { // // TODO: don't highlight next char in append mode // } - // let mode = match state.mode { - // Mode::Insert => "INS", - // Mode::Normal => "NOR", - // }; - - // execute!( - // stdout, - // SetForegroundColor(Color::Reset), - // cursor::MoveTo(0, self.size.1), - // Print(mode) - // ); - - use tui::backend::Backend; + // statusline + let mode = match state.mode() { + Mode::Insert => "INS", + Mode::Normal => "NOR", + }; + self.surface.set_style( + Rect::new(0, self.size.1 - 1, self.size.0, 1), + self.theme.get("ui.statusline"), + ); + // TODO: unfocused one with different color + let text_color = Style::default().fg(Color::Rgb(219, 191, 239)); // lilac + self.surface + .set_string(1, self.size.1 - 1, mode, text_color); + if let Some(path) = state.path() { + self.surface + .set_string(6, self.size.1 - 1, path.to_string_lossy(), text_color); + } self.terminal .backend_mut() @@ -221,7 +246,10 @@ impl Editor { let coords = coords_at_pos(&state.doc().slice(..), pos); execute!( stdout, - cursor::MoveTo((coords.col + 2) as u16, coords.row as u16) + cursor::MoveTo( + coords.col as u16 + viewport.x, + coords.row as u16 - self.first_line + viewport.y, + ) ); } None => (), diff --git a/helix-term/src/theme.rs b/helix-term/src/theme.rs index 5b6eb7de..4b2f102e 100644 --- a/helix-term/src/theme.rs +++ b/helix-term/src/theme.rs @@ -72,6 +72,10 @@ impl Default for Theme { "module" => Style::default().fg(Color::Rgb(255, 0, 0)), // white "variable" => Style::default().fg(Color::Rgb(255, 0, 0)), // white "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white + + "ui.background" => Style::default().bg(Color::Rgb(59, 34, 76)), // midnight + "ui.linenr" => Style::default().fg(Color::Rgb(90, 89, 119)), // comet + "ui.statusline" => Style::default().bg(Color::Rgb(40, 23, 51)), // revolver }; let scopes = mapping.keys().map(ToString::to_string).collect(); |