From 73deabaa408c505905271e11065846ac87e1afd0 Mon Sep 17 00:00:00 2001
From: rhogenson <05huvhec@duck.com>
Date: Sun, 22 Sep 2024 10:17:02 -0700
Subject: [PATCH] Fix panic when drawing at the edge of the screen. (#11737)

When pressing tab at the edge of the screen, Helix panics in debug mode
subtracting position.col - self.offset.col.

To correctly account for graphemes that are partially visible,
column_in_bounds takes a width and returns whether the whole range is
in bounds.

Co-authored-by: Rose Hogenson <rosehogenson@posteo.net>
---
 helix-term/src/ui/document.rs                     | 7 +++----
 helix-term/src/ui/text_decorations.rs             | 2 +-
 helix-term/src/ui/text_decorations/diagnostics.rs | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/helix-term/src/ui/document.rs b/helix-term/src/ui/document.rs
index 79145ba0..ae00ea14 100644
--- a/helix-term/src/ui/document.rs
+++ b/helix-term/src/ui/document.rs
@@ -433,7 +433,7 @@ impl<'a> TextRenderer<'a> {
             Grapheme::Newline => &self.newline,
         };
 
-        let in_bounds = self.column_in_bounds(position.col + width - 1);
+        let in_bounds = self.column_in_bounds(position.col, width);
 
         if in_bounds {
             self.surface.set_string(
@@ -452,7 +452,6 @@ impl<'a> TextRenderer<'a> {
             );
             self.surface.set_style(rect, style);
         }
-
         if *is_in_indent_area && !is_whitespace {
             *last_indent_level = position.col;
             *is_in_indent_area = false;
@@ -461,8 +460,8 @@ impl<'a> TextRenderer<'a> {
         width
     }
 
-    pub fn column_in_bounds(&self, colum: usize) -> bool {
-        self.offset.col <= colum && colum < self.viewport.width as usize + self.offset.col
+    pub fn column_in_bounds(&self, colum: usize, width: usize) -> bool {
+        self.offset.col <= colum && colum + width <= self.offset.col + self.viewport.width as usize
     }
 
     /// Overlay indentation guides ontop of a rendered line
diff --git a/helix-term/src/ui/text_decorations.rs b/helix-term/src/ui/text_decorations.rs
index 630af581..931ea431 100644
--- a/helix-term/src/ui/text_decorations.rs
+++ b/helix-term/src/ui/text_decorations.rs
@@ -164,7 +164,7 @@ impl Decoration for Cursor<'_> {
         renderer: &mut TextRenderer,
         grapheme: &FormattedGrapheme,
     ) -> usize {
-        if renderer.column_in_bounds(grapheme.visual_pos.col)
+        if renderer.column_in_bounds(grapheme.visual_pos.col, grapheme.width())
             && renderer.offset.row < grapheme.visual_pos.row
         {
             let position = grapheme.visual_pos - renderer.offset;
diff --git a/helix-term/src/ui/text_decorations/diagnostics.rs b/helix-term/src/ui/text_decorations/diagnostics.rs
index 2d9e8370..0bb0026f 100644
--- a/helix-term/src/ui/text_decorations/diagnostics.rs
+++ b/helix-term/src/ui/text_decorations/diagnostics.rs
@@ -98,7 +98,7 @@ impl Renderer<'_, '_> {
     fn draw_eol_diagnostic(&mut self, diag: &Diagnostic, row: u16, col: usize) -> u16 {
         let style = self.styles.severity_style(diag.severity());
         let width = self.renderer.viewport.width;
-        if !self.renderer.column_in_bounds(col + 1) {
+        if !self.renderer.column_in_bounds(col + 1, 1) {
             return 0;
         }
         let col = (col - self.renderer.offset.col) as u16;