From 7e7fb200adb03e454865ce5291dd4bc30cc64de5 Mon Sep 17 00:00:00 2001 From: A-Walrus Date: Wed, 3 Aug 2022 11:49:06 +0300 Subject: [PATCH 1/3] Fix tab highlight when tab is partially visible --- helix-term/src/ui/editor.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 6ed9799b4ae3..dcf70a5d8039 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -473,10 +473,10 @@ impl EditorView { use helix_core::graphemes::{grapheme_width, RopeGraphemes}; for grapheme in RopeGraphemes::new(text) { - let out_of_bounds = visual_x < offset.col as u16 - || visual_x >= viewport.width + offset.col as u16; - if LineEnding::from_rope_slice(&grapheme).is_some() { + let out_of_bounds = visual_x < offset.col as u16 + || visual_x >= viewport.width + offset.col as u16; + if !out_of_bounds { // we still want to render an empty cell with the style surface.set_string( @@ -530,12 +530,25 @@ impl EditorView { (grapheme.as_ref(), width) }; + let cut_off_start = offset.col.saturating_sub(visual_x as usize); + let out_of_bounds = cut_off_start >= width; + if !out_of_bounds { + let substring = { + let mut chars = display_grapheme.chars(); + // TODO use advance_by once stable + for _ in 0..cut_off_start { + chars.next(); + } + chars.as_str() + }; + // if we're offscreen just keep going until we hit a new line surface.set_string( - viewport.x + visual_x - offset.col as u16, + viewport.x + visual_x - offset.col as u16 + + cut_off_start as u16, viewport.y + line, - display_grapheme, + substring, if is_whitespace { style.patch(whitespace_style) } else { From 6c09dafea3b635714d079768eb445102b719b178 Mon Sep 17 00:00:00 2001 From: A-Walrus Date: Wed, 3 Aug 2022 20:35:11 +0300 Subject: [PATCH 2/3] Make it style based, and not truncation based Dealing with truncating is a mess, especially when it comes to wide unicode graphemes. This way it should work no matter what. --- helix-term/src/ui/editor.rs | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index dcf70a5d8039..39db3b156f86 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -473,10 +473,10 @@ impl EditorView { use helix_core::graphemes::{grapheme_width, RopeGraphemes}; for grapheme in RopeGraphemes::new(text) { - if LineEnding::from_rope_slice(&grapheme).is_some() { - let out_of_bounds = visual_x < offset.col as u16 - || visual_x >= viewport.width + offset.col as u16; + let out_of_bounds = visual_x < offset.col as u16 + || visual_x >= viewport.width + offset.col as u16; + if LineEnding::from_rope_slice(&grapheme).is_some() { if !out_of_bounds { // we still want to render an empty cell with the style surface.set_string( @@ -530,32 +530,33 @@ impl EditorView { (grapheme.as_ref(), width) }; + let style = if is_whitespace { + style.patch(whitespace_style) + } else { + style + }; + let cut_off_start = offset.col.saturating_sub(visual_x as usize); - let out_of_bounds = cut_off_start >= width; if !out_of_bounds { - let substring = { - let mut chars = display_grapheme.chars(); - // TODO use advance_by once stable - for _ in 0..cut_off_start { - chars.next(); - } - chars.as_str() - }; - // if we're offscreen just keep going until we hit a new line surface.set_string( - viewport.x + visual_x - offset.col as u16 - + cut_off_start as u16, + viewport.x + visual_x - offset.col as u16, viewport.y + line, - substring, - if is_whitespace { - style.patch(whitespace_style) - } else { - style - }, + display_grapheme, + style, ); + } else if cut_off_start != 0 && cut_off_start < width { + // partially on screen + let rect = Rect::new( + viewport.x as u16, + viewport.y + line, + (width - cut_off_start) as u16, + 1, + ); + surface.set_style(rect, style); } + if is_in_indent_area && !(grapheme == " " || grapheme == "\t") { draw_indent_guides(visual_x, line, surface); is_in_indent_area = false; From 0fd2140061e839778a5ed2bf67b00da396766dab Mon Sep 17 00:00:00 2001 From: A-Walrus Date: Fri, 5 Aug 2022 10:10:55 +0300 Subject: [PATCH 3/3] Inline style calculation into branches --- helix-term/src/ui/editor.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 39db3b156f86..7329272a7910 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -530,12 +530,6 @@ impl EditorView { (grapheme.as_ref(), width) }; - let style = if is_whitespace { - style.patch(whitespace_style) - } else { - style - }; - let cut_off_start = offset.col.saturating_sub(visual_x as usize); if !out_of_bounds { @@ -544,7 +538,11 @@ impl EditorView { viewport.x + visual_x - offset.col as u16, viewport.y + line, display_grapheme, - style, + if is_whitespace { + style.patch(whitespace_style) + } else { + style + }, ); } else if cut_off_start != 0 && cut_off_start < width { // partially on screen @@ -554,7 +552,14 @@ impl EditorView { (width - cut_off_start) as u16, 1, ); - surface.set_style(rect, style); + surface.set_style( + rect, + if is_whitespace { + style.patch(whitespace_style) + } else { + style + }, + ); } if is_in_indent_area && !(grapheme == " " || grapheme == "\t") {