diff options
author | Omnikar | 2021-12-01 22:59:23 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2022-04-20 02:37:23 +0000 |
commit | e6b865ed0b1b77934733d86b59d60870e9f5881f (patch) | |
tree | f090ee3a7078b3109102abb3f555acb241ef4cd5 /helix-term/src/ui | |
parent | 94eba0e66aa193c093b1d7eefc0e21391cb2485f (diff) |
allow whitespace to be rendered
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r-- | helix-term/src/ui/editor.rs | 55 | ||||
-rw-r--r-- | helix-term/src/ui/picker.rs | 1 |
2 files changed, 50 insertions, 6 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 318180d7..798b8ac8 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -124,7 +124,15 @@ impl EditorView { Box::new(highlights) }; - Self::render_text_highlights(doc, view.offset, inner, surface, theme, highlights); + Self::render_text_highlights( + doc, + view.offset, + inner, + surface, + theme, + highlights, + &editor.config().whitespace, + ); Self::render_gutter(editor, doc, view, view.area, surface, theme, is_focused); Self::render_rulers(editor, doc, view, inner, surface, theme); @@ -344,7 +352,10 @@ impl EditorView { surface: &mut Surface, theme: &Theme, highlights: H, + whitespace: &helix_view::editor::WhitespaceConfig, ) { + use helix_view::editor::WhitespaceRenderValue; + // It's slightly more efficient to produce a full RopeSlice from the Rope, then slice that a bunch // of times than it is to always call Rope::slice/get_slice (it will internally always hit RSEnum::Light). let text = doc.text().slice(..); @@ -353,9 +364,20 @@ impl EditorView { let mut visual_x = 0u16; let mut line = 0u16; let tab_width = doc.tab_width(); - let tab = " ".repeat(tab_width); + let tab = if whitespace.render.tab() == WhitespaceRenderValue::All { + (1..tab_width).fold(whitespace.characters.tab.to_string(), |s, _| s + " ") + } else { + " ".repeat(tab_width) + }; + let space = whitespace.characters.space.to_string(); + let newline = if whitespace.render.newline() == WhitespaceRenderValue::All { + whitespace.characters.newline.to_string() + } else { + " ".to_string() + }; let text_style = theme.get("ui.text"); + let whitespace_style = theme.get("ui.virtual.whitespace"); 'outer: for event in highlights { match event { @@ -374,6 +396,14 @@ impl EditorView { .iter() .fold(text_style, |acc, span| acc.patch(theme.highlight(span.0))); + let space = if whitespace.render.space() == WhitespaceRenderValue::All + && text.len_chars() < end + { + &space + } else { + " " + }; + use helix_core::graphemes::{grapheme_width, RopeGraphemes}; for grapheme in RopeGraphemes::new(text) { @@ -386,8 +416,8 @@ impl EditorView { surface.set_string( viewport.x + visual_x - offset.col as u16, viewport.y + line, - " ", - style, + &newline, + style.patch(whitespace_style), ); } @@ -400,12 +430,21 @@ impl EditorView { } } else { let grapheme = Cow::from(grapheme); + let is_whitespace; let (grapheme, width) = if grapheme == "\t" { + is_whitespace = true; // make sure we display tab as appropriate amount of spaces let visual_tab_width = tab_width - (visual_x as usize % tab_width); - (&tab[..visual_tab_width], visual_tab_width) + let grapheme_tab_width = + ropey::str_utils::char_to_byte_idx(&tab, visual_tab_width); + + (&tab[..grapheme_tab_width], visual_tab_width) + } else if grapheme == " " { + is_whitespace = true; + (space, 1) } else { + is_whitespace = false; // Cow will prevent allocations if span contained in a single slice // which should really be the majority case let width = grapheme_width(&grapheme); @@ -418,7 +457,11 @@ impl EditorView { viewport.x + visual_x - offset.col as u16, viewport.y + line, grapheme, - style, + if is_whitespace { + style.patch(whitespace_style) + } else { + style + }, ); } diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index dec59c89..3ca6965c 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -240,6 +240,7 @@ impl<T: 'static> Component for FilePicker<T> { surface, &cx.editor.theme, highlights, + &cx.editor.config().whitespace, ); // highlight the line |